From 0c577812894393798e4d8d4eee3be127d15923c9 Mon Sep 17 00:00:00 2001 From: Aman Singh Date: Sat, 4 Apr 2026 09:41:09 +0530 Subject: [PATCH 1/2] fix: run container as non-root user to reduce attack --- Dockerfile | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 34a1efe7..b27bc3a2 100644 --- a/Dockerfile +++ b/Dockerfile @@ -88,8 +88,14 @@ ENV PATH="/app/.venv/bin:$PATH" # Copy frontend build from stage 1 COPY --from=frontend-builder /app/frontend/dist ./static -# Create necessary directories -RUN mkdir -p extensions_storage data +# Create necessary directories and non-root user +RUN mkdir -p extensions_storage data && \ + addgroup --system appgroup && \ + adduser --system --ingroup appgroup appuser && \ + chown -R appuser:appgroup /app + +# Drop root privileges +USER appuser # Set default environment variables ENV EXTENSION_STORAGE_PATH=/app/extensions_storage \ From ae7b7e347a36b985c83f04dfeefb23db4b38c159 Mon Sep 17 00:00:00 2001 From: Aman Singh Date: Sat, 4 Apr 2026 09:46:41 +0530 Subject: [PATCH 2/2] fix: reduce ZIP bomb protection limits to prevent DoS --- src/extension_shield/core/config.py | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/extension_shield/core/config.py b/src/extension_shield/core/config.py index 4e94c7f3..e521c1ad 100644 --- a/src/extension_shield/core/config.py +++ b/src/extension_shield/core/config.py @@ -208,16 +208,18 @@ def get_settings() -> Settings: telemetry_admin_key = os.environ.get("TELEMETRY_ADMIN_KEY") # Zip-bomb protection: max file count and max total uncompressed size - _zip_max_files = os.environ.get("ZIP_EXTRACT_MAX_FILES", "10000") - _zip_max_bytes = os.environ.get("ZIP_EXTRACT_MAX_UNCOMPRESSED_BYTES", "524288000") # 500 MiB + # Reduced defaults to prevent DoS via crafted .crx archives: + # 1000 files and 100 MiB are sufficient for any legitimate Chrome extension. + _zip_max_files = os.environ.get("ZIP_EXTRACT_MAX_FILES", "1000") + _zip_max_bytes = os.environ.get("ZIP_EXTRACT_MAX_UNCOMPRESSED_BYTES", "104857600") # 100 MiB try: zip_extract_max_files = int(_zip_max_files) except ValueError: - zip_extract_max_files = 10000 + zip_extract_max_files = 1000 try: zip_extract_max_uncompressed_bytes = int(_zip_max_bytes) except ValueError: - zip_extract_max_uncompressed_bytes = 524288000 + zip_extract_max_uncompressed_bytes = 104857600 storage_backend = _parse_storage_backend(os.environ.get("STORAGE_BACKEND"))