From 154f45e0c13ac41068d5e098f3d5000d07a1e7f4 Mon Sep 17 00:00:00 2001 From: "google-labs-jules[bot]" <161369871+google-labs-jules[bot]@users.noreply.github.com> Date: Thu, 14 May 2026 05:08:26 +0000 Subject: [PATCH] Secure temporary file creation in capture managers Update `File.createTempFile` calls in `CameraCaptureManager` and `ScreenRecordManager` to explicitly use `context.cacheDir`. This prevents temporary files containing sensitive screen/camera captures from being created in a default or less secure temporary directory, reducing the risk of local data disclosure. Co-authored-by: yuga-hashimoto <74749461+yuga-hashimoto@users.noreply.github.com> --- .../com/openclaw/assistant/node/CameraCaptureManager.kt | 8 ++++---- .../com/openclaw/assistant/node/ScreenRecordManager.kt | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/app/src/main/java/com/openclaw/assistant/node/CameraCaptureManager.kt b/app/src/main/java/com/openclaw/assistant/node/CameraCaptureManager.kt index 92577b61..2743cec9 100644 --- a/app/src/main/java/com/openclaw/assistant/node/CameraCaptureManager.kt +++ b/app/src/main/java/com/openclaw/assistant/node/CameraCaptureManager.kt @@ -111,7 +111,7 @@ class CameraCaptureManager(private val context: Context) { provider.unbindAll() provider.bindToLifecycle(owner, selector, capture) - val (bytes, orientation) = capture.takeJpegWithExif(context.mainExecutor()) + val (bytes, orientation) = capture.takeJpegWithExif(context.mainExecutor(), context.cacheDir) val decoded = BitmapFactory.decodeByteArray(bytes, 0, bytes.size) ?: throw IllegalStateException("UNAVAILABLE: failed to decode captured image") val rotated = rotateBitmapByExif(decoded, orientation) @@ -213,7 +213,7 @@ class CameraCaptureManager(private val context: Context) { android.util.Log.w("CameraCaptureManager", "clip: warming up camera 1.5s...") kotlinx.coroutines.delay(1_500) - val file = File.createTempFile("openclaw-clip-", ".mp4") + val file = File.createTempFile("openclaw-clip-", ".mp4", context.cacheDir) val outputOptions = FileOutputOptions.Builder(file).build() val finalized = kotlinx.coroutines.CompletableDeferred() @@ -356,9 +356,9 @@ private suspend fun Context.cameraProvider(): ProcessCameraProvider = } /** Returns (jpegBytes, exifOrientation) so caller can rotate the decoded bitmap. */ -private suspend fun ImageCapture.takeJpegWithExif(executor: Executor): Pair = +private suspend fun ImageCapture.takeJpegWithExif(executor: Executor, cacheDir: java.io.File): Pair = suspendCancellableCoroutine { cont -> - val file = File.createTempFile("openclaw-snap-", ".jpg") + val file = File.createTempFile("openclaw-snap-", ".jpg", cacheDir) val options = ImageCapture.OutputFileOptions.Builder(file).build() takePicture( options, diff --git a/app/src/main/java/com/openclaw/assistant/node/ScreenRecordManager.kt b/app/src/main/java/com/openclaw/assistant/node/ScreenRecordManager.kt index 2e4c786b..c00e4a42 100644 --- a/app/src/main/java/com/openclaw/assistant/node/ScreenRecordManager.kt +++ b/app/src/main/java/com/openclaw/assistant/node/ScreenRecordManager.kt @@ -93,7 +93,7 @@ class ScreenRecordManager(private val context: Context) { val height = metrics.heightPixels val densityDpi = metrics.densityDpi - val file = File.createTempFile("openclaw-screen-", ".mp4") + val file = File.createTempFile("openclaw-screen-", ".mp4", context.cacheDir) if (includeAudio) ensureMicPermission() val recorder = createMediaRecorder()