fix: Implement security measures for HTTP server based on streaming mode, ensuring local access only in local mode

This commit is contained in:
Faded
2026-03-05 16:49:12 +05:00
parent 08e4e25e6c
commit 4f20ccb4bd
3 changed files with 86 additions and 19 deletions

1
.gitignore vendored
View File

@@ -47,3 +47,4 @@ repomix-output.md
/fadcam-promo/
extras/*
TASKS.md
feedback.md

View File

@@ -95,24 +95,36 @@ public class RemoteStreamService extends Service {
// Start foreground with notification
startForeground(NOTIFICATION_ID, buildNotification("Ready. Start recording to begin streaming.", "http://..."));
// Start HTTP server
if (!startHttpServer()) {
Log.e(TAG, "Failed to start HTTP server, stopping service");
stopSelf();
return START_NOT_STICKY;
}
// Check streaming mode (0 = local, 1 = cloud)
int streamingMode = getSharedPreferences("FadCamCloudPrefs", MODE_PRIVATE).getInt("streaming_mode", 0);
boolean isCloudMode = streamingMode == 1;
// Save port to preferences for CloudStatusManager
getSharedPreferences("FadCamPrefs", MODE_PRIVATE)
.edit()
.putInt("stream_server_port", activePort)
.apply();
Log.i(TAG, (isCloudMode ? "☁️" : "📱") + " Streaming mode: " + (isCloudMode ? "CLOUD" : "LOCAL"));
// SECURITY FIX: Only start HTTP server in LOCAL mode
// In cloud mode, all streaming goes through relay server, no local access needed
if (!isCloudMode) {
if (!startHttpServer()) {
Log.e(TAG, "Failed to start HTTP server, stopping service");
stopSelf();
return START_NOT_STICKY;
}
// Save port to preferences for local dashboard
getSharedPreferences("FadCamPrefs", MODE_PRIVATE)
.edit()
.putInt("stream_server_port", activePort)
.apply();
} else {
Log.i(TAG, "🔒 Cloud mode active - HTTP server not started (all traffic through relay)");
activePort = -1;
}
// Enable streaming in RemoteStreamManager
RemoteStreamManager.getInstance().setStreamingEnabled(true);
// Start cloud status manager (handles status push and command poll)
// This works independently of video streaming - just needs server to be on
// This works independently of video streaming - just needs service to be on
CloudStatusManager.getInstance(this).start();
// Update notification with stream URL
@@ -149,6 +161,58 @@ public class RemoteStreamService extends Service {
return binder;
}
/**
* SECURITY FIX: Handle streaming mode changes dynamically
* Stops HTTP server when switching to cloud, starts when switching to local.
* This is called from RemoteFragment when user changes streaming mode.
* Ensures the server is immediately updated without needing a service restart.
*/
public void updateStreamingMode() {
// Get current mode from preferences (0 = local, 1 = cloud)
int streamingMode = getSharedPreferences("FadCamCloudPrefs", MODE_PRIVATE)
.getInt("streaming_mode", 0);
boolean isCloudMode = streamingMode == 1;
Log.i(TAG, (isCloudMode ? "☁️" : "📱") + " Mode changed: " + (isCloudMode ? "CLOUD" : "LOCAL"));
boolean serverRunning = isServerRunning();
if (isCloudMode) {
// Cloud mode: STOP server if running (security - no local access in cloud mode)
if (serverRunning) {
Log.i(TAG, "🔒 Stopping HTTP server (switching to cloud mode)");
stopHttpServer();
updateNotification();
} else {
Log.i(TAG, "🔒 Cloud mode - HTTP server already stopped");
}
} else {
// Local mode: START server if not running
if (!serverRunning) {
Log.i(TAG, "📱 Starting HTTP server (switching to local mode)");
if (startHttpServer()) {
// Save port to preferences
getSharedPreferences("FadCamPrefs", MODE_PRIVATE)
.edit()
.putInt("stream_server_port", activePort)
.apply();
updateNotification();
} else {
Log.e(TAG, "❌ Failed to start HTTP server when switching to local mode");
}
} else {
Log.i(TAG, "📱 Local mode - HTTP server already running on port " + activePort);
}
}
}
/**
* Check if HTTP server is currently running
*/
public boolean isServerRunning() {
return httpServer != null && httpServer.isAlive();
}
/**
* Start HTTP server on a free port.
*/
@@ -504,11 +568,4 @@ public class RemoteStreamService extends Service {
public int getActivePort() {
return activePort;
}
/**
* Check if server is running.
*/
public boolean isServerRunning() {
return httpServer != null && httpServer.isAlive();
}
}

View File

@@ -1498,6 +1498,15 @@ public class RemoteFragment extends BaseFragment {
RemoteStreamManager.getInstance().clearLocalhostClients();
}
// SECURITY FIX: Call updateStreamingMode on service to immediately stop/start HTTP server
// This ensures proper enforcement of cloud-only mode (no local access)
if (streamService != null && serviceBound) {
Log.i(TAG, "🔄 Updating streaming mode in service...");
streamService.updateStreamingMode();
} else {
Log.w(TAG, "⚠️ Service not bound, mode persisted but server state may not update immediately");
}
// Start/stop cloud status manager if server is already running
CloudStatusManager statusManager = CloudStatusManager.getInstance(requireContext());
if (cloudEnabled) {