Skip to content

Security: tjax4376/FrameAI

security.md

Security Findings and Remediation Prompts

This document contains security findings from Semgrep scan and provides non-ambiguous prompts to resolve each issue. Each prompt is numbered (P001, P002, etc.) for tracking purposes.

Summary

  • Total Findings: 32
  • Critical (ERROR): 4
  • Warnings: 28

Status (as of 2025-02-14):

  • Fixed: 32 (P001–P032; P001 GitHub Actions fix in .github/workflows/release.yml; workflow file exists in repo)
  • Open items: See .memory/cards.md for CR001–CR005 and current status (CR001/CR002/CR003 FIXED per plan)

P001: Fix GitHub Actions Shell Injection Vulnerability

File: .github/workflows/release.yml
Lines: 31-37
Severity: ERROR
CWE: CWE-78 (OS Command Injection)
OWASP: A01:2017 - Injection, A03:2021 - Injection

Issue: Using variable interpolation ${{...}} with github context data in a run: step could allow an attacker to inject their own code into the runner.

Status: ✅ FIXED (2026-01-17)

Fix Applied:

  • .github/workflows/release.yml: "Get version" step uses env: to avoid direct ${{ ... }} interpolation in shell.

Prompt: Replace the direct use of ${{ github.event_name }} and ${{ github.event.inputs.version }} in the shell script with environment variables. Modify the "Get version" step in .github/workflows/release.yml to:

  1. Add an env: block that stores github.event_name and github.event.inputs.version in environment variables
  2. Use these environment variables in the run: script with double-quotes (e.g., "$ENVVAR")
  3. Ensure the script uses the environment variables instead of direct ${{...}} interpolation

Example Fix Pattern:

- name: Get version
  id: get_version
  env:
    EVENT_NAME: ${{ github.event_name }}
    INPUT_VERSION: ${{ github.event.inputs.version }}
  run: |
    if [ "$EVENT_NAME" = "workflow_dispatch" ]; then
      echo "version=$INPUT_VERSION" >> $GITHUB_OUTPUT
    else
      echo "version=${GITHUB_REF#refs/tags/}" >> $GITHUB_OUTPUT
    fi

P002: Fix Unsafe Format String in Console Logging

File: console/app.js
Line: 427
Severity: INFO
CWE: CWE-134 (Use of Externally-Controlled Format String)
OWASP: A01:2021 - Broken Access Control

Issue: String concatenation with non-literal variables in console.log can allow format specifier injection to forge log messages.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • console/app.js: replaced template literal logging with a constant format string + arguments.

Prompt: Replace the template literal in console.log at line 427 of console/app.js with a constant format string and pass variables as separate arguments. Change:

console.log(`Health check for ${serviceId}: ${result.value.status}`, result.value);

To:

console.log('Health check for %s: %s', serviceId, result.value.status, result.value);

P003: Fix Unsafe Format String in Console Error Logging

File: console/app.js
Line: 439
Severity: INFO
CWE: CWE-134 (Use of Externally-Controlled Format String)
OWASP: A01:2021 - Broken Access Control

Issue: String concatenation with non-literal variables in console.error can allow format specifier injection.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • console/app.js: replaced template literal error logging with a constant format string + arguments.

Prompt: Replace the template literal in console.error at line 439 of console/app.js with a constant format string and pass variables as separate arguments. Change:

console.error(`Health check failed for ${serviceId}:`, result.reason);

To:

console.error('Health check failed for %s:', serviceId, result.reason);

P004: Fix XSS Vulnerability in Service Details Panel

File: console/app.js
Lines: 643-670
Severity: ERROR
CWE: CWE-79 (Cross-site Scripting)
OWASP: A07:2017 - Cross-Site Scripting (XSS), A03:2021 - Injection

Issue: User-controlled data in innerHTML assignment can lead to XSS vulnerabilities. The code sets detailsPanel.innerHTML with unescaped variables including service.name, serviceId, service.port, service.layer, status.status, status.error, and status.details.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • console/app.js: refactored showServiceDetails() to build the panel via DOM APIs (createElement, textContent, appendChild) and render JSON via <pre>.textContent.

Prompt: Replace the innerHTML assignment at lines 643-670 in console/app.js with DOM manipulation methods to prevent XSS.

  1. Create DOM elements using document.createElement() instead of string interpolation
  2. Set text content using textContent property (not innerHTML)
  3. For the JSON.stringify output, use textContent on a <pre> element
  4. Sanitize all user-controlled data before rendering
  5. Use appendChild() to build the DOM structure

Example Pattern:

// Clear existing content
detailsPanel.innerHTML = '';

// Create and append elements using DOM methods
const createInfoItem = (label, value) => {
  const item = document.createElement('div');
  item.className = 'service-info-item';
  const strong = document.createElement('strong');
  strong.textContent = label;
  item.appendChild(strong);
  const text = document.createTextNode(value);
  item.appendChild(text);
  return item;
};

P005: Fix XSS Vulnerability in Secrets List Rendering

File: console/app.js
Lines: 750-768
Severity: ERROR
CWE: CWE-79 (Cross-site Scripting)
OWASP: A07:2017 - Cross-Site Scripting (XSS), A03:2021 - Injection

Issue: User-controlled data in innerHTML assignment with secrets.map() can lead to XSS vulnerabilities. Variables include secret.name, secret.type, secret.service, secret.description, and secret.id (used in onclick handlers).

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • console/app.js: refactored secrets rendering to DOM APIs (createElement, textContent, appendChild).
  • console/app.js: replaced inline onclick handlers with addEventListener().
  • console/app.js: added class-name sanitization for user-controlled badge class input.

Prompt: Replace the innerHTML assignment at lines 750-768 in console/app.js with DOM manipulation methods to prevent XSS.

  1. Create DOM elements using document.createElement() instead of string interpolation
  2. Set text content using textContent property
  3. Replace onclick attribute assignments with addEventListener() to prevent code injection
  4. Sanitize all secret data (name, type, service, description, id) before rendering
  5. Use appendChild() to build the DOM structure for each secret card

Critical: The onclick="editSecret('${secret.id}')" and onclick="deleteSecret('${secret.id}')" patterns must be replaced with event listeners that use addEventListener().


P006: Fix CORS Wildcard in Secrets Service

File: console/secrets_service.py
Line: 39
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*", which is insecure.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • console/secrets_service.py: added get_allowed_origins() reading ALLOWED_ORIGINS (JSON array or comma-separated).
  • console/secrets_service.py: configured CORS with allow_origins=allowed_origins (no wildcard) and development fallback to localhost.

Prompt: Replace the wildcard CORS configuration at line 39 in console/secrets_service.py with a specific list of allowed origins.

  1. Read allowed origins from environment variable (e.g., ALLOWED_ORIGINS) or configuration
  2. Parse the environment variable as a comma-separated list or JSON array
  3. Replace allow_origins=["*"] with allow_origins=allowed_origins_list
  4. Add a default fallback for development (e.g., ["http://localhost:3000"]) if environment variable is not set
  5. Document the required environment variable in the service documentation

Example Pattern:

import os
allowed_origins = os.getenv('ALLOWED_ORIGINS', 'http://localhost:3000').split(',')
app.add_middleware(
    CORSMiddleware,
    allow_origins=allowed_origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)

P007: Fix CORS Wildcard in Security Hardening Service

File: sag/services/security_hardening.py
Line: 80
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • sag/services/security_hardening.py: added get_allowed_origins() reading ALLOWED_ORIGINS (JSON array or comma-separated).
  • sag/services/security_hardening.py: configured CORS with allow_origins=allowed_origins (no wildcard) and development fallback to localhost.

Prompt: Replace the wildcard CORS configuration at line 80 in sag/services/security_hardening.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.


P008: Fix CORS Wildcard in Execution Context Service

File: sag/services/execution_context.py
Line: 1398 (previously, now fixed at lines 1388-1447)
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Prompt: Replace the wildcard CORS configuration at line 1398 in sag/services/execution_context.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.

Fix Applied:

  • Added get_allowed_origins() function (lines 1391-1427) to read from ALLOWED_ORIGINS environment variable
  • Supports both comma-separated list and JSON array formats
  • Defaults to http://localhost:8020 for development if not set
  • Updated CORS middleware to use specific origins instead of wildcard
  • Changed allow_credentials to True since we're no longer using wildcard origins
  • Added logging for CORS configuration
  • Added import os to support environment variable reading

P009: Fix CORS Wildcard in Auth Service

File: sag/services/auth.py
Line: 533 (previously, now fixed at lines 528-583)
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Prompt: Replace the wildcard CORS configuration at line 533 in sag/services/auth.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.

Fix Applied:

  • Added get_allowed_origins() function (lines 531-567) to read from ALLOWED_ORIGINS environment variable
  • Supports both comma-separated list and JSON array formats
  • Defaults to http://localhost:8001 for development if not set
  • Updated CORS middleware to use specific origins instead of wildcard
  • Changed allow_credentials to True since we're no longer using wildcard origins
  • Added logging for CORS configuration
  • import os and import json were already present in the file

P010: Fix CORS Wildcard in Admin Console Service

File: sag/services/admin_console.py
Line: 52 (previously, now fixed at lines 39-99)
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Prompt: Replace the wildcard CORS configuration at line 52 in sag/services/admin_console.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.

Fix Applied:

  • Added get_allowed_origins() function (lines 42-78) to read from ALLOWED_ORIGINS environment variable
  • Supports both comma-separated list and JSON array formats
  • Defaults to http://localhost:8020 for development if not set
  • Updated CORS middleware to use specific origins instead of wildcard
  • Changed allow_credentials to True since we're no longer using wildcard origins
  • Added logging for CORS configuration
  • import os and import json were already present in the file

P011: Fix CORS Wildcard in Gateway Service

File: sag/services/gateway.py
Line: 943 (previously, now fixed at lines 939-991)
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Prompt: Replace the wildcard CORS configuration at line 943 in sag/services/gateway.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.

Fix Applied:

  • Added get_allowed_origins() function (lines 942-978) to read from ALLOWED_ORIGINS environment variable
  • Supports both comma-separated list and JSON array formats
  • Defaults to http://localhost:8000 for development if not set
  • Updated CORS middleware to use specific origins instead of wildcard
  • Changed allow_credentials to True since we're no longer using wildcard origins
  • Added logging for CORS configuration
  • Added import os to support environment variable reading

P012: Fix CORS Wildcard in Workflow Service

File: sag/services/workflow.py
Line: 1234 (previously, now fixed at lines 1224-1283)
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Prompt: Replace the wildcard CORS configuration at line 1234 in sag/services/workflow.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.

Fix Applied:

  • Added get_allowed_origins() function (lines 1227-1263) to read from ALLOWED_ORIGINS environment variable
  • Supports both comma-separated list and JSON array formats
  • Defaults to http://localhost:8010 for development if not set
  • Updated CORS middleware to use specific origins instead of wildcard
  • Changed allow_credentials to True since we're no longer using wildcard origins
  • Added logging for CORS configuration
  • Added import os to support environment variable reading

P013: Fix CORS Wildcard in SIEM Integration Service

File: sag/services/siem_integration.py
Line: 829 (previously, now fixed at lines 819-878)
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Prompt: Replace the wildcard CORS configuration at line 829 in sag/services/siem_integration.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.

Fix Applied:

  • Added get_allowed_origins() function (lines 822-858) to read from ALLOWED_ORIGINS environment variable
  • Supports both comma-separated list and JSON array formats
  • Defaults to http://localhost:8013 for development if not set
  • Updated CORS middleware to use specific origins instead of wildcard
  • Changed allow_credentials to True since we're no longer using wildcard origins
  • Added logging for CORS configuration
  • Added import os to support environment variable reading

P014: Fix CORS Wildcard in Adapter Framework Service

File: sag/services/adapter_framework.py
Line: 1612 (previously, now fixed at lines 1602-1661)
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Prompt: Replace the wildcard CORS configuration at line 1612 in sag/services/adapter_framework.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.

Fix Applied:

  • Added get_allowed_origins() function (lines 1605-1641) to read from ALLOWED_ORIGINS environment variable
  • Supports both comma-separated list and JSON array formats
  • Defaults to http://localhost:8014 for development if not set
  • Updated CORS middleware to use specific origins instead of wildcard
  • Changed allow_credentials to True since we're no longer using wildcard origins
  • Added logging for CORS configuration
  • Added import os to support environment variable reading

P015: Fix CORS Wildcard in Policy Admin Service

File: sag/services/policy_admin.py
Line: 1266 (previously, now fixed at lines 1256-1315)
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Prompt: Replace the wildcard CORS configuration at line 1266 in sag/services/policy_admin.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.

Fix Applied:

  • Added get_allowed_origins() function (lines 1259-1295) to read from ALLOWED_ORIGINS environment variable
  • Supports both comma-separated list and JSON array formats
  • Defaults to http://localhost:8011 for development if not set
  • Updated CORS middleware to use specific origins instead of wildcard
  • Changed allow_credentials to True since we're no longer using wildcard origins
  • Added logging for CORS configuration
  • Added import os to support environment variable reading

P016: Fix CORS Wildcard in Policy Service

File: sag/services/policy.py
Line: 842
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • sag/services/policy.py: added get_allowed_origins() reading ALLOWED_ORIGINS and configured CORS with allow_origins=allowed_origins (no wildcard).

Prompt: Replace the wildcard CORS configuration at line 842 in sag/services/policy.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.


P017: Fix CORS Wildcard in Orchestrator Service

File: sag/services/orchestrator.py
Line: 1031
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • sag/services/orchestrator.py: added get_allowed_origins() reading ALLOWED_ORIGINS and configured CORS with allow_origins=allowed_origins (no wildcard).

Prompt: Replace the wildcard CORS configuration at line 1031 in sag/services/orchestrator.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.


P018: Fix CORS Wildcard in Notification Service

File: sag/services/notification.py
Line: 1358
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • sag/services/notification.py: added get_allowed_origins() reading ALLOWED_ORIGINS and configured CORS with allow_origins=allowed_origins (no wildcard).

Prompt: Replace the wildcard CORS configuration at line 1358 in sag/services/notification.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.


P019: Fix CORS Wildcard in Monitoring Service

File: sag/services/monitoring.py
Line: 1151
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • sag/services/monitoring.py: added get_allowed_origins() reading ALLOWED_ORIGINS and configured CORS with allow_origins=allowed_origins (no wildcard).

Prompt: Replace the wildcard CORS configuration at line 1151 in sag/services/monitoring.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.


P020: Fix CORS Wildcard in Audit Service

File: sag/services/audit.py
Line: 1170
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • sag/services/audit.py: added get_allowed_origins() reading ALLOWED_ORIGINS and configured CORS with allow_origins=allowed_origins (no wildcard).

Prompt: Replace the wildcard CORS configuration at line 1170 in sag/services/audit.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.


P021: Fix CORS Wildcard in Identity Service

File: sag/services/identity.py
Line: 966
Severity: WARNING
CWE: CWE-942 (Permissive Cross-domain Policy)
OWASP: A05:2021 - Security Misconfiguration

Issue: CORS policy allows any origin using wildcard "*".

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • sag/services/identity.py: added get_allowed_origins() reading ALLOWED_ORIGINS and configured CORS with allow_origins=allowed_origins (no wildcard).

Prompt: Replace the wildcard CORS configuration at line 966 in sag/services/identity.py with a specific list of allowed origins from environment variable or configuration, following the same pattern as P006.


P022: Add No-New-Privileges Security Option to Postgres Service

File: docker-compose.prod.yml
Line: 5 (postgres service)
Severity: WARNING
CWE: CWE-732 (Incorrect Permission Assignment)
OWASP: A05:2021 - Security Misconfiguration, A06:2017 - Security Misconfiguration

Issue: Service 'postgres' allows for privilege escalation via setuid or setgid binaries.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • docker-compose.prod.yml: added security_opt: - no-new-privileges:true for postgres.

Prompt: Add security_opt configuration with no-new-privileges:true to the postgres service in docker-compose.prod.yml. Add the following under the postgres service definition:

security_opt:
  - no-new-privileges:true

P023: Add Read-Only Filesystem to Postgres Service

File: docker-compose.prod.yml
Line: 5 (postgres service)
Severity: WARNING
CWE: CWE-732 (Incorrect Permission Assignment)
OWASP: A05:2021 - Security Misconfiguration, A06:2017 - Security Misconfiguration

Issue: Service 'postgres' is running with a writable root filesystem, which may allow malicious applications to download and run additional payloads.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • docker-compose.prod.yml: added read_only: true and tmpfs mounts for postgres.
  • docker-compose.prod.yml: ensured init SQL mount is read-only (:ro).

Prompt: Add read_only: true to the postgres service in docker-compose.prod.yml. Note: This may require additional configuration for postgres data directory using tmpfs or named volumes with proper permissions. If postgres requires write access to specific directories, use tmpfs mounts for those paths.

Example Pattern:

read_only: true
tmpfs:
  - /tmp
  - /var/run/postgresql

P024: Add No-New-Privileges Security Option to Redis Service

File: docker-compose.prod.yml
Line: 33 (redis service)
Severity: WARNING
CWE: CWE-732 (Incorrect Permission Assignment)
OWASP: A05:2021 - Security Misconfiguration, A06:2017 - Security Misconfiguration

Issue: Service 'redis' allows for privilege escalation via setuid or setgid binaries.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • docker-compose.prod.yml: added security_opt: - no-new-privileges:true for redis.

Prompt: Add security_opt configuration with no-new-privileges:true to the redis service in docker-compose.prod.yml. Add the following under the redis service definition:

security_opt:
  - no-new-privileges:true

P025: Add Read-Only Filesystem to Redis Service

File: docker-compose.prod.yml
Line: 33 (redis service)
Severity: WARNING
CWE: CWE-732 (Incorrect Permission Assignment)
OWASP: A05:2021 - Security Misconfiguration, A06:2017 - Security Misconfiguration

Issue: Service 'redis' is running with a writable root filesystem.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • docker-compose.prod.yml: added read_only: true and tmpfs mounts for redis.

Prompt: Add read_only: true to the redis service in docker-compose.prod.yml. Use tmpfs mounts for directories that redis needs to write to (e.g., /tmp, /var/run/redis). Ensure the redis data volume is properly configured as a named volume.


P026: Add No-New-Privileges Security Option to Nginx Service

File: docker-compose.prod.yml
Line: 577 (nginx service)
Severity: WARNING
CWE: CWE-732 (Incorrect Permission Assignment)
OWASP: A05:2021 - Security Misconfiguration, A06:2017 - Security Misconfiguration

Issue: Service 'nginx' allows for privilege escalation via setuid or setgid binaries.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • docker-compose.prod.yml: added security_opt: - no-new-privileges:true for nginx.

Prompt: Add security_opt configuration with no-new-privileges:true to the nginx service in docker-compose.prod.yml. Add the following under the nginx service definition:

security_opt:
  - no-new-privileges:true

P027: Add Read-Only Filesystem to Nginx Service

File: docker-compose.prod.yml
Line: 577 (nginx service)
Severity: WARNING
CWE: CWE-732 (Incorrect Permission Assignment)
OWASP: A05:2021 - Security Misconfiguration, A06:2017 - Security Misconfiguration

Issue: Service 'nginx' is running with a writable root filesystem.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • docker-compose.prod.yml: added read_only: true and tmpfs mounts for nginx.

Prompt: Add read_only: true to the nginx service in docker-compose.prod.yml. Use tmpfs mounts for directories that nginx needs to write to (e.g., /tmp, /var/cache/nginx, /var/run). Ensure nginx configuration and static files are mounted as read-only volumes.


P028-P032: Add Security Options to Remaining Docker Services

File: docker-compose.prod.yml
Severity: WARNING
CWE: CWE-732 (Incorrect Permission Assignment)
OWASP: A05:2021 - Security Misconfiguration, A06:2017 - Security Misconfiguration

Issue: Additional services in docker-compose.prod.yml may also require security hardening. Semgrep identified postgres, redis, and nginx, but other services should be reviewed.

Status: ✅ FIXED (2024-12-19)

Fix Applied:

  • docker-compose.prod.yml: applied security_opt: - no-new-privileges:true across all remaining services.
  • docker-compose.prod.yml: applied read_only: true and tmpfs: - /tmp across application services where feasible.

Prompt: Review all remaining services in docker-compose.prod.yml and apply the same security hardening:

  1. Add security_opt: - no-new-privileges:true to each service
  2. Add read_only: true where feasible
  3. Use tmpfs mounts for writable temporary directories
  4. Ensure data persistence volumes are properly configured
  5. Document any services that cannot use read_only: true and the reasons why

Services to Review: All application services (auth, gateway, orchestrator, etc.) should be evaluated for these security options.


Implementation Priority

Critical (Implement Immediately)

  • P001: GitHub Actions shell injection
  • ✅ P004: XSS in service details panel (fixed)
  • ✅ P005: XSS in secrets list (fixed)

High Priority (Implement Soon)

  • ✅ P002, P003: Unsafe format strings (fixed)
  • ✅ P006-P021: CORS wildcard configurations (fixed)

Medium Priority (Implement in Next Sprint)

  • ✅ P022-P032: Docker security hardening (fixed)

P033: Add Secure GitHub Actions Release Workflow (if GitHub Actions is used)

File: .github/workflows/release.yml
Severity: ERROR
CWE: CWE-78 (OS Command Injection)

Issue: P001 cannot be fixed because the workflow file does not exist in this repo. If releases are intended to be automated via GitHub Actions, add the workflow using safe patterns (no direct ${{ ... }} interpolation inside shell scripts).

Prompt:

  1. Create .github/workflows/release.yml (or restore it if it was removed).
  2. In any run: step that branches on GitHub context fields, copy GitHub context values into env:, and only reference them in the script as quoted variables (e.g., "$EVENT_NAME").
  3. Avoid eval, unquoted expansions, and command substitution with untrusted inputs.

Status: ✅ FIXED (2026-06-17) — .github/workflows/release.yml restored; shell steps use env: indirection per safe pattern.


P034: Console UI Defense-in-Depth Against XSS Lint False-Positives

File: console/app.js
Severity: WARNING
CWE: CWE-79 (Cross-site Scripting)

Issue: Even when setting innerHTML = '' (clearing content), some security scanners and future refactors can re-introduce unsafe patterns. Additionally, using remote/variable status strings directly in className can allow attribute injection (not code execution, but can cause unexpected DOM/CSS behavior).

Prompt:

  1. Replace element.innerHTML = '' clear operations with DOM child removal (no innerHTML usage).
  2. Restrict any status values used in CSS classnames to a fixed allowlist (e.g., healthy, warning, error, unknown).

Status: ✅ FIXED (2025-12-15)

Fix Applied:

  • console/app.js: added clearElementChildren() helper and replaced svg.innerHTML = '' and detailsPanel.innerHTML = ''.
  • console/app.js: added normalizeServiceStatus() and used it before interpolating status values into classnames and UI text.

Notes

  1. CORS Configuration: Consider creating a shared configuration module or environment variable that all services can use to ensure consistent CORS settings across the application.

  2. XSS Prevention: After implementing P004 and P005, consider adding a Content Security Policy (CSP) header to further mitigate XSS risks.

  3. Docker Security: Some services may require write access for legitimate operations. Test thoroughly after applying read_only: true to ensure services function correctly.

  4. Testing: After implementing each fix, run Semgrep again to verify the issue is resolved and no new issues are introduced.


References

There aren't any published security advisories