{"version": "2.1.0", "$schema": "https://json.schemastore.org/sarif-2.1.0.json", "runs": [{"tool": {"driver": {"name": "Repobility", "informationUri": "https://repobility.com", "rules": [{"id": "WEB003", "name": "Public web service has no security.txt", "shortDescription": {"text": "Public web service has no security.txt"}, "fullDescription": {"text": "security.txt gives researchers and customers a safe disclosure channel. Public web apps and APIs should publish it under /.well-known/security.txt."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "medium", "confidence": 0.78, "cwe": "", "owasp": ""}}, {"id": "AUC012", "name": "[AUC012] FastAPI interactive docs may be exposed by framework defaults: FastAPI exposes /docs, /redoc, and /openapi.json", "shortDescription": {"text": "[AUC012] FastAPI interactive docs may be exposed by framework defaults: FastAPI exposes /docs, /redoc, and /openapi.json by default. Public production APIs should explicitly disable those defaults, protect them behind admin authentication, "}, "fullDescription": {"text": "FastAPI exposes /docs, /redoc, and /openapi.json by default. Public production APIs should explicitly disable those defaults, protect them behind admin authentication, or publish a reviewed OpenAPI spec with declared security requirements."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.72, "cwe": "CWE-285", "owasp": "WSTG-AUTHZ"}}, {"id": "AUC009", "name": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function", "shortDescription": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: POST /r"}, "fullDescription": {"text": "A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: POST /refresh."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.68, "cwe": "CWE-285", "owasp": "API5:2023 Broken Function Level Authorization"}}, {"id": "AUC001", "name": "[AUC001] No Repobility access matrix policy found: The repository uses web/API frameworks but does not define .repobilit", "shortDescription": {"text": "[AUC001] No Repobility access matrix policy found: The repository uses web/API frameworks but does not define .repobility/access.yml or equivalent authorization documentation."}, "fullDescription": {"text": "The repository uses web/API frameworks but does not define .repobility/access.yml or equivalent authorization documentation."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.92, "cwe": "CWE-285", "owasp": "WSTG-AUTHZ"}}, {"id": "DKR003", "name": "Compose service `nginx` image uses the latest tag", "shortDescription": {"text": "Compose service `nginx` image uses the latest tag"}, "fullDescription": {"text": "The latest tag is mutable and can change without a code review, producing different images from the same source."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.94, "cwe": "", "owasp": ""}}, {"id": "DKC015", "name": "Database service has no healthcheck", "shortDescription": {"text": "Database service has no healthcheck"}, "fullDescription": {"text": "Compose starts dependent containers in dependency order, but it does not wait for a database to be ready unless a healthcheck is defined and dependents use service_healthy."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.88, "cwe": "", "owasp": ""}}, {"id": "DKR001", "name": "Docker final stage has no non-root USER", "shortDescription": {"text": "Docker final stage has no non-root USER"}, "fullDescription": {"text": "Docker images run as root unless the image or Dockerfile switches to a non-root user."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.82, "cwe": "", "owasp": ""}}, {"id": "DKR007", "name": "Docker build context has no .dockerignore", "shortDescription": {"text": "Docker build context has no .dockerignore"}, "fullDescription": {"text": "Without .dockerignore, build context can include source history, local env files, dependencies, and generated artifacts."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "SEC015", "name": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable.", "shortDescription": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "fullDescription": {"text": "Use secrets module (Python) or crypto.getRandomValues() (JS) for security-sensitive randomness."}, "properties": {"scanner": "repobility-threat-engine", "category": "crypto", "severity": "medium", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC034", "name": "[SEC034] Log Injection / Log Forging \u2014 unsanitized user input in log: User input is logged without sanitizing newlines o", "shortDescription": {"text": "[SEC034] Log Injection / Log Forging \u2014 unsanitized user input in log: User input is logged without sanitizing newlines or control characters. Attackers inject `\\n` to forge fake log entries, hide tracks, or exploit downstream log parsers (S"}, "fullDescription": {"text": "Strip control characters before logging:\n  safe = user_input.replace('\\n','').replace('\\r','').replace('\\x00','')\n  logger.info('User action: %s', safe)\nAlways use parameterized logging (`%s` + args), never f-strings or string concat \u2014 that's also what mitigates log4shell-style attacks. For structured logging, use a JSON formatter that escapes values."}, "properties": {"scanner": "repobility-threat-engine", "category": "log_injection", "severity": "medium", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "DKC016", "name": "App service does not wait for database health", "shortDescription": {"text": "App service does not wait for database health"}, "fullDescription": {"text": "depends_on controls startup order, but without condition: service_healthy an app can start while the database is still initializing and fail intermittently."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.68, "cwe": "", "owasp": ""}}, {"id": "DKC010", "name": "Compose service lacks no-new-privileges hardening", "shortDescription": {"text": "Compose service lacks no-new-privileges hardening"}, "fullDescription": {"text": "no-new-privileges prevents processes from gaining additional privileges through setuid binaries or file capabilities."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.62, "cwe": "", "owasp": ""}}, {"id": "DKC006", "name": "Compose service does not declare a runtime user", "shortDescription": {"text": "Compose service does not declare a runtime user"}, "fullDescription": {"text": "If the image does not define USER internally, this service may run as root."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.56, "cwe": "", "owasp": ""}}, {"id": "DKR012", "name": "Dockerfile keeps pip download cache", "shortDescription": {"text": "Dockerfile keeps pip download cache"}, "fullDescription": {"text": "Pip's package cache increases image size and can preserve unnecessary artifacts."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "SEC020", "name": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequen", "shortDescription": {"text": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequent AI-assisted coding failure: the helper exposes the exact value needed for troubleshooting."}, "fullDescription": {"text": "Log only redacted, hashed, or last-four-style metadata. Rotate any secret that may have reached logs."}, "properties": {"scanner": "repobility-threat-engine", "category": "credential_exposure", "severity": "info", "confidence": 0.15, "cwe": "", "owasp": ""}}, {"id": "AUC003", "name": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby a", "shortDescription": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: PUT /items/{item_id}."}, "fullDescription": {"text": "A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: PUT /items/{item_id}."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "high", "confidence": 0.7, "cwe": "CWE-639", "owasp": "API1:2023 Broken Object Level Authorization"}}, {"id": "DKR014", "name": "Dockerfile copies the entire context without .dockerignore", "shortDescription": {"text": "Dockerfile copies the entire context without .dockerignore"}, "fullDescription": {"text": "COPY . or ADD . sends the full build context to Docker. Without .dockerignore this can include secrets, git history, and local artifacts."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "high", "confidence": 0.92, "cwe": "", "owasp": ""}}, {"id": "SEC029", "name": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled ", "shortDescription": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes e"}, "fullDescription": {"text": "Validate the URL against an allowlist BEFORE fetching:\n  ALLOWED = {'images.example.com', 'cdn.example.com'}\n  host = urlparse(url).hostname\n  if host not in ALLOWED: abort(400)\nOr use a server-side proxy (Imgproxy / serve-files-only-from-S3) that isolates outbound network access from the request handler.\nBlock private CIDRs explicitly: 10/8, 172.16/12, 192.168/16, 169.254/16."}, "properties": {"scanner": "repobility-threat-engine", "category": "ssrf", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}]}}, "automationDetails": {"id": "repobility/509"}, "properties": {"repository": "benavlabs/FastAPI-boilerplate", "repoUrl": "https://github.com/benavlabs/FastAPI-boilerplate.git", "branch": "main"}, "results": [{"ruleId": "WEB003", "level": "warning", "message": {"text": "Public web service has no security.txt"}, "properties": {"repobilityId": 30221, "scanner": "repobility-web-presence", "fingerprint": "5cd26606c5a53c9f403ff7a92a6917c19cf440a23ce03e2b90e8c493312ef8cd", "category": "quality", "severity": "medium", "confidence": 0.78, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app/API but no security.txt file or route was discovered.", "evidence": {"rule_id": "WEB003", "scanner": "repobility-web-presence", "references": ["https://www.rfc-editor.org/rfc/rfc9116", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|5cd26606c5a53c9f403ff7a92a6917c19cf440a23ce03e2b90e8c493312ef8cd"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".well-known/security.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "AUC012", "level": "warning", "message": {"text": "[AUC012] FastAPI interactive docs may be exposed by framework defaults: FastAPI exposes /docs, /redoc, and /openapi.json by default. Public production APIs should explicitly disable those defaults, protect them behind admin authentication, or publish a reviewed OpenAPI spec with declared security requirements."}, "properties": {"repobilityId": 30220, "scanner": "repobility-access-control", "fingerprint": "27f8c50db94c1d5138790446654bd4d0b5823ce185d040059e5a7502358b5899", "category": "auth", "severity": "medium", "confidence": 0.72, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"apps": [{"line": 209, "file_path": "src/app/core/setup.py", "docs_url_disabled": false, "redoc_url_disabled": false, "openapi_url_disabled": false}, {"line": 231, "file_path": "src/app/core/utils/cache.py", "docs_url_disabled": false, "redoc_url_disabled": false, "openapi_url_disabled": false}, {"line": 250, "file_path": "src/app/core/utils/cache.py", "docs_url_disabled": false, "redoc_url_disabled": false, "openapi_url_disabled": false}], "scanner": "repobility-access-control", "correlation_key": "fp|27f8c50db94c1d5138790446654bd4d0b5823ce185d040059e5a7502358b5899"}}}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: POST /refresh."}, "properties": {"repobilityId": 30219, "scanner": "repobility-access-control", "fingerprint": "0f38128a84dd3cb7736d7f9cb17896d2e2f8053d5e5e983148072a27b2679656", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/refresh", "method": "POST", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/api/v1/login.py|47|cwe-285", "identity_targets": ["authenticated"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/api/v1/login.py"}, "region": {"startLine": 47}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: DELETE /{username}/post/{id}."}, "properties": {"repobilityId": 30218, "scanner": "repobility-access-control", "fingerprint": "692762a937c7011d180e976acbb442bb07f718998e407a37ff8247c3da0070c5", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/{username}/post/{id}", "method": "DELETE", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/api/v1/posts.py|118|cwe-285", "identity_targets": ["authenticated", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/api/v1/posts.py"}, "region": {"startLine": 118}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: GET /{username}/post/{id}."}, "properties": {"repobilityId": 30217, "scanner": "repobility-access-control", "fingerprint": "d8eaa6021f889c78e2d4e502b803e7843e56f0f7ffcd06fcea7585965989900d", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/{username}/post/{id}", "method": "GET", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/api/v1/posts.py|75|cwe-285", "identity_targets": ["authenticated", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/api/v1/posts.py"}, "region": {"startLine": 75}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: DELETE /user/{username}."}, "properties": {"repobilityId": 30216, "scanner": "repobility-access-control", "fingerprint": "bec81f1bcfb0f729efea60d1c4cf36517f9b777fbb9ea188b7601aa12bbf9ca1", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/user/{username}", "method": "DELETE", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/api/v1/users.py|106|cwe-285", "identity_targets": ["authenticated"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/api/v1/users.py"}, "region": {"startLine": 106}}}]}, {"ruleId": "AUC009", "level": "warning", "message": {"text": "[AUC009] Sensitive function route lacks elevated authorization evidence: A route appears to perform a sensitive function such as export, invite, role, token, billing, or destructive action without elevated policy evidence. Endpoint: GET /user/{username}."}, "properties": {"repobilityId": 30215, "scanner": "repobility-access-control", "fingerprint": "33ca07fa2d9e74b194f770d46e0f78ad94c28623a219aa023c93df67690f377d", "category": "auth", "severity": "medium", "confidence": 0.68, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/user/{username}", "method": "GET", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/api/v1/users.py|65|cwe-285", "identity_targets": ["authenticated"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/api/v1/users.py"}, "region": {"startLine": 65}}}]}, {"ruleId": "AUC001", "level": "warning", "message": {"text": "[AUC001] No Repobility access matrix policy found: The repository uses web/API frameworks but does not define .repobility/access.yml or equivalent authorization documentation."}, "properties": {"repobilityId": 30209, "scanner": "repobility-access-control", "fingerprint": "f1305052c3ba1e6c1cdb5dccc19e58a8168cf78b176658f32b1fc823df3e9d10", "category": "auth", "severity": "medium", "confidence": 0.92, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"scanner": "repobility-access-control", "frameworks": ["Django", "FastAPI"], "expected_files": [".repobility/access.yml", ".repobility/access.yaml", ".repobility/access.json", ".repobility/authorization.yml"], "correlation_key": "fp|f1305052c3ba1e6c1cdb5dccc19e58a8168cf78b176658f32b1fc823df3e9d10"}}}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `nginx` image uses the latest tag"}, "properties": {"repobilityId": 30208, "scanner": "repobility-docker", "fingerprint": "3a3f1b531142ffca8197b82528fcc00023ff70b8011e60f61aa1659bffd1cf52", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "nginx:latest", "rule_id": "DKR003", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://docs.docker.com/scout/policy/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|3a3f1b531142ffca8197b82528fcc00023ff70b8011e60f61aa1659bffd1cf52"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 55}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 30206, "scanner": "repobility-docker", "fingerprint": "b447d50c9c8bc1e8e0f8b95fdc43cfdf004a12672a5baa13114f23f2a45ea942", "category": "docker", "severity": "medium", "confidence": 0.88, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Database-like service has no Compose healthcheck.", "evidence": {"rule_id": "DKC015", "scanner": "repobility-docker", "service": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|b447d50c9c8bc1e8e0f8b95fdc43cfdf004a12672a5baa13114f23f2a45ea942"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 38}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 30192, "scanner": "repobility-docker", "fingerprint": "c389893fe6215b76445288d1ffea237f12049a155f1e7730ffee015b7758ce45", "category": "docker", "severity": "medium", "confidence": 0.88, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Database-like service has no Compose healthcheck.", "evidence": {"rule_id": "DKC015", "scanner": "repobility-docker", "service": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|c389893fe6215b76445288d1ffea237f12049a155f1e7730ffee015b7758ce45"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 38}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 30181, "scanner": "repobility-docker", "fingerprint": "489ab76f9738f034f77b6c434f2bff8d33ac2c5bd4e36b019d69fe49e655f714", "category": "docker", "severity": "medium", "confidence": 0.88, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Database-like service has no Compose healthcheck.", "evidence": {"rule_id": "DKC015", "scanner": "repobility-docker", "service": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|489ab76f9738f034f77b6c434f2bff8d33ac2c5bd4e36b019d69fe49e655f714"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 38}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 30174, "scanner": "repobility-docker", "fingerprint": "78b9cbc3ffc5263a3dc3a9d72ab8fde112a27088eb2c0f140ca679b85bea48ad", "category": "docker", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "No USER directive was found in the final runtime stage.", "evidence": {"rule_id": "DKR001", "scanner": "repobility-docker", "final_base": "python:3.11", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|78b9cbc3ffc5263a3dc3a9d72ab8fde112a27088eb2c0f140ca679b85bea48ad"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/Dockerfile"}, "region": {"startLine": 15}}}]}, {"ruleId": "DKR007", "level": "warning", "message": {"text": "Docker build context has no .dockerignore"}, "properties": {"repobilityId": 30171, "scanner": "repobility-docker", "fingerprint": "c98378cf8c37e4866e89d6ca06a24b7e8c44654aa34e6e4bf1367c4a4c0c5b44", "category": "docker", "severity": "medium", "confidence": 0.9, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Dockerfile exists but repository root has no .dockerignore.", "evidence": {"rule_id": "DKR007", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|c98378cf8c37e4866e89d6ca06a24b7e8c44654aa34e6e4bf1367c4a4c0c5b44"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".dockerignore"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 30170, "scanner": "repobility-docker", "fingerprint": "380c8bfed36b79782e5bd367a4c60099f8a1b24f80643e9cf2a30e5b76156566", "category": "docker", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "No USER directive was found in the final runtime stage.", "evidence": {"rule_id": "DKR001", "scanner": "repobility-docker", "final_base": "python:3.11", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|380c8bfed36b79782e5bd367a4c60099f8a1b24f80643e9cf2a30e5b76156566"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/Dockerfile"}, "region": {"startLine": 15}}}]}, {"ruleId": "SEC015", "level": "warning", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 30168, "scanner": "repobility-threat-engine", "fingerprint": "f127d798676c2b132ee78e579a3eda49a23065d48d0e80e08be4ac6b7c2a3e39", "category": "crypto", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Security-sensitive keyword found nearby \u2014 weak PRNG is risky here", "evidence": {"match": "def create_access_token", "reason": "Security-sensitive keyword found nearby \u2014 weak PRNG is risky here", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "code|crypto|src/app/core/security.py|54|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/core/security.py"}, "region": {"startLine": 54}}}]}, {"ruleId": "SEC034", "level": "warning", "message": {"text": "[SEC034] Log Injection / Log Forging \u2014 unsanitized user input in log: User input is logged without sanitizing newlines or control characters. Attackers inject `\\n` to forge fake log entries, hide tracks, or exploit downstream log parsers (SIEM, splunk). Combined with template injection this can escalate to RCE (CVE-2021-44228 log4shell). CWE-117."}, "properties": {"repobilityId": 30164, "scanner": "repobility-threat-engine", "fingerprint": "35a2eb7c10aaf9c25cd556f401b0b2a8ce57ba095ca6a46a573e6f351af5c208", "category": "log_injection", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "logger.info(f\"Admin user {user", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC034", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|35a2eb7c10aaf9c25cd556f401b0b2a8ce57ba095ca6a46a573e6f351af5c208"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/scripts/create_first_superuser.py"}, "region": {"startLine": 62}}}]}, {"ruleId": "SEC034", "level": "warning", "message": {"text": "[SEC034] Log Injection / Log Forging \u2014 unsanitized user input in log: User input is logged without sanitizing newlines or control characters. Attackers inject `\\n` to forge fake log entries, hide tracks, or exploit downstream log parsers (SIEM, splunk). Combined with template injection this can escalate to RCE (CVE-2021-44228 log4shell). CWE-117."}, "properties": {"repobilityId": 30163, "scanner": "repobility-threat-engine", "fingerprint": "78c06e07bed291b19f3ea118c61e037582bbf1e5ac2502e6ea4d9c6993bd7120", "category": "log_injection", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "logger.warning(\n                    f\"User {user", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC034", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|78c06e07bed291b19f3ea118c61e037582bbf1e5ac2502e6ea4d9c6993bd7120"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/api/dependencies.py"}, "region": {"startLine": 92}}}]}, {"ruleId": "DKC015", "level": "note", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 30207, "scanner": "repobility-docker", "fingerprint": "b9eb4d82a90a47518f00eabe90e9588b22a102f65e71cf3867418e21c681e891", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Database-like service has no Compose healthcheck.", "evidence": {"rule_id": "DKC015", "scanner": "repobility-docker", "service": "redis", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|b9eb4d82a90a47518f00eabe90e9588b22a102f65e71cf3867418e21c681e891"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 47}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30205, "scanner": "repobility-docker", "fingerprint": "8cd8064d8e5886266ce6882bbaa59c6502ed47b54b8554f05f3291f8ffe39806", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "worker", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|8cd8064d8e5886266ce6882bbaa59c6502ed47b54b8554f05f3291f8ffe39806", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30204, "scanner": "repobility-docker", "fingerprint": "b4c0510ea9309b9f15eaaedd02cd010905647e3169d23bb649b19e353de7dd94", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "worker", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|b4c0510ea9309b9f15eaaedd02cd010905647e3169d23bb649b19e353de7dd94"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30203, "scanner": "repobility-docker", "fingerprint": "b67402fad0d3a6869da80d5fd74de69343b65c8641842b3951767110cf066b71", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "worker", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|b67402fad0d3a6869da80d5fd74de69343b65c8641842b3951767110cf066b71"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30202, "scanner": "repobility-docker", "fingerprint": "471f3131bb394913efb9dd7e0769d4dcfaf337511cca040a706a0cc3c7c5828f", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "web", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|471f3131bb394913efb9dd7e0769d4dcfaf337511cca040a706a0cc3c7c5828f", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30201, "scanner": "repobility-docker", "fingerprint": "50b96d5f48388cbdd069514be145333a0d9799e94088b0e5b40bef798e6403e7", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "web", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|50b96d5f48388cbdd069514be145333a0d9799e94088b0e5b40bef798e6403e7"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30200, "scanner": "repobility-docker", "fingerprint": "136a03f50ec41626aff8cad636ba70d7dcb6687535159c2c3c03d99275667999", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "web", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|136a03f50ec41626aff8cad636ba70d7dcb6687535159c2c3c03d99275667999"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30199, "scanner": "repobility-docker", "fingerprint": "bde3e92cc9f16a56155284912d8c40955627a14a2760a28a8b6d8d0497c7e06f", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "pytest", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|bde3e92cc9f16a56155284912d8c40955627a14a2760a28a8b6d8d0497c7e06f", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 79}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30198, "scanner": "repobility-docker", "fingerprint": "ca1e035e6de14e13d10ae672970c0e2a8b228c838704c6d833139d284f3da4cc", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "pytest", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|ca1e035e6de14e13d10ae672970c0e2a8b228c838704c6d833139d284f3da4cc"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 79}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30197, "scanner": "repobility-docker", "fingerprint": "1be046f6b66ef67fee4da3ee2fda9580b54127575b14faaf18c6663af7a84a0a", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "pytest", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|1be046f6b66ef67fee4da3ee2fda9580b54127575b14faaf18c6663af7a84a0a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 79}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30196, "scanner": "repobility-docker", "fingerprint": "1db8af94d5e5e206474cc9e608149728df129e7b2761dca9ce96157e3c90a4a2", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "create_superuser", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|1db8af94d5e5e206474cc9e608149728df129e7b2761dca9ce96157e3c90a4a2", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30195, "scanner": "repobility-docker", "fingerprint": "0bb5f4512c3fe0a1bc80bad37cea14731d342352c81898f027fab8ccfdf5faab", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "create_superuser", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|0bb5f4512c3fe0a1bc80bad37cea14731d342352c81898f027fab8ccfdf5faab"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30194, "scanner": "repobility-docker", "fingerprint": "0ff31ab91ba83ef7da33e3230da056b0cc3449f383bde05532c033704c026c11", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "create_superuser", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|0ff31ab91ba83ef7da33e3230da056b0cc3449f383bde05532c033704c026c11"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "DKC015", "level": "note", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 30193, "scanner": "repobility-docker", "fingerprint": "23edfa062c2dd6d4359c1c6dea73f204e9523482f50dfe10fe2fd6fb28439800", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Database-like service has no Compose healthcheck.", "evidence": {"rule_id": "DKC015", "scanner": "repobility-docker", "service": "redis", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|23edfa062c2dd6d4359c1c6dea73f204e9523482f50dfe10fe2fd6fb28439800"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 47}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30191, "scanner": "repobility-docker", "fingerprint": "a03ce262671c76fd56ca427004c3016666e9dd09813bdece364dbbf6636de3df", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "worker", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|a03ce262671c76fd56ca427004c3016666e9dd09813bdece364dbbf6636de3df", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30190, "scanner": "repobility-docker", "fingerprint": "27322e68044f2e78bf05eaf1a8b36e29e1911489f60b5199af7ff64c1366f7e2", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "worker", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|27322e68044f2e78bf05eaf1a8b36e29e1911489f60b5199af7ff64c1366f7e2"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30189, "scanner": "repobility-docker", "fingerprint": "9b0b0784b16f49e87497ab72a7a0baf53580382dc9aa0a279c0b761ddefc3f23", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "worker", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|9b0b0784b16f49e87497ab72a7a0baf53580382dc9aa0a279c0b761ddefc3f23"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30188, "scanner": "repobility-docker", "fingerprint": "86afa84b7abb8258a1fcf47d97f94d8c1507ca2b19eeed6aa78cb4f5001795a1", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "web", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|86afa84b7abb8258a1fcf47d97f94d8c1507ca2b19eeed6aa78cb4f5001795a1", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30187, "scanner": "repobility-docker", "fingerprint": "92d2c8d69d84fa5c0dc48ad017e1d20e2b7d9bf951e375023de939a9f65e49fa", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "web", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|92d2c8d69d84fa5c0dc48ad017e1d20e2b7d9bf951e375023de939a9f65e49fa"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30186, "scanner": "repobility-docker", "fingerprint": "047fb957ae7e97a4463199cdec34711a3e85887449b67a732b9396fb36f355d1", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "web", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|047fb957ae7e97a4463199cdec34711a3e85887449b67a732b9396fb36f355d1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30185, "scanner": "repobility-docker", "fingerprint": "3441e540ae4ba8b5264bfa06088cbd5f386fea6b490c8f2b7e262d442f55fe81", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "create_superuser", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|3441e540ae4ba8b5264bfa06088cbd5f386fea6b490c8f2b7e262d442f55fe81", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30184, "scanner": "repobility-docker", "fingerprint": "8904187f308d656a8eac582e56c38550be8af7bdf8feb42655a95b19d8faa3e9", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "create_superuser", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|8904187f308d656a8eac582e56c38550be8af7bdf8feb42655a95b19d8faa3e9"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30183, "scanner": "repobility-docker", "fingerprint": "64b0f0c5d07861547fd80b47f79751b697e51a432d4ac82226bf205cd48b92d5", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "create_superuser", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|64b0f0c5d07861547fd80b47f79751b697e51a432d4ac82226bf205cd48b92d5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 65}}}]}, {"ruleId": "DKC015", "level": "note", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 30182, "scanner": "repobility-docker", "fingerprint": "43b76109cdb36fafa4baf752f9d049fcbefd27df11d68f38dc7bc04c03ef3943", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Database-like service has no Compose healthcheck.", "evidence": {"rule_id": "DKC015", "scanner": "repobility-docker", "service": "redis", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|43b76109cdb36fafa4baf752f9d049fcbefd27df11d68f38dc7bc04c03ef3943"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 47}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30180, "scanner": "repobility-docker", "fingerprint": "ee3d7f367ae74c8d5c659b22e654b746feedfc8e63ed4527370136ed2840cecd", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "worker", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|ee3d7f367ae74c8d5c659b22e654b746feedfc8e63ed4527370136ed2840cecd", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30179, "scanner": "repobility-docker", "fingerprint": "6db397646b6d3bc19c5ee3b14b1bc56ec00dbe2f0c1d0677fbfa9ae6f21186c6", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "worker", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|6db397646b6d3bc19c5ee3b14b1bc56ec00dbe2f0c1d0677fbfa9ae6f21186c6"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30178, "scanner": "repobility-docker", "fingerprint": "8193b007f4ff74016d5d63a318d07493cc689f082aaba52e63e8bca589e77043", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "worker", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|8193b007f4ff74016d5d63a318d07493cc689f082aaba52e63e8bca589e77043"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 24}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 30177, "scanner": "repobility-docker", "fingerprint": "1e1dd8cda3bd5ddece22b71dfd69b61ce6c67440ee11035d249a50053799350f", "category": "docker", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "App depends on a database-like service without a health-gated dependency.", "evidence": {"rule_id": "DKC016", "scanner": "repobility-docker", "service": "web", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|1e1dd8cda3bd5ddece22b71dfd69b61ce6c67440ee11035d249a50053799350f", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 30176, "scanner": "repobility-docker", "fingerprint": "986f76c4e5926ae1282b41b9e421b5d7c85f838b6edadcb6acaf08f5414ffeed", "category": "docker", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "App-like service has no security_opt no-new-privileges setting.", "evidence": {"rule_id": "DKC010", "scanner": "repobility-docker", "service": "web", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|986f76c4e5926ae1282b41b9e421b5d7c85f838b6edadcb6acaf08f5414ffeed"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 30175, "scanner": "repobility-docker", "fingerprint": "5a032da3eb04d72114d9d15c077c47be1c959c4003263b48e5a34ca8d12bd058", "category": "docker", "severity": "low", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Service has no user setting and Repobility could not prove the image runs non-root.", "evidence": {"rule_id": "DKC006", "scanner": "repobility-docker", "service": "web", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|5a032da3eb04d72114d9d15c077c47be1c959c4003263b48e5a34ca8d12bd058"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR012", "level": "note", "message": {"text": "Dockerfile keeps pip download cache"}, "properties": {"repobilityId": 30173, "scanner": "repobility-docker", "fingerprint": "0a159b171eef5f5f8252119fc5f969fc3ccac9371025b698ed8dd77c48b57c0e", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "pip install appears without --no-cache-dir.", "evidence": {"rule_id": "DKR012", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|0a159b171eef5f5f8252119fc5f969fc3ccac9371025b698ed8dd77c48b57c0e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/production_with_nginx/Dockerfile"}, "region": {"startLine": 7}}}]}, {"ruleId": "DKR012", "level": "note", "message": {"text": "Dockerfile keeps pip download cache"}, "properties": {"repobilityId": 30169, "scanner": "repobility-docker", "fingerprint": "2bfa8b9e350f081b4a142c55706f5c233154325b0ea27acc9fbbde7c39ce68bc", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "pip install appears without --no-cache-dir.", "evidence": {"rule_id": "DKR012", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|2bfa8b9e350f081b4a142c55706f5c233154325b0ea27acc9fbbde7c39ce68bc"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/gunicorn_managing_uvicorn_workers/Dockerfile"}, "region": {"startLine": 7}}}]}, {"ruleId": "SEC020", "level": "none", "message": {"text": "[SEC020] Secret Printed to Logs: Debug or diagnostic code appears to print a credential-bearing value. This is a frequent AI-assisted coding failure: the helper exposes the exact value needed for troubleshooting."}, "properties": {"repobilityId": 30162, "scanner": "repobility-threat-engine", "fingerprint": "a5451e276266ab9798c9ffe47c5b9fb6caa266261b0f422355b6072ca5d5f79a", "category": "credential_exposure", "severity": "info", "confidence": 0.15, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Log message mentions credential-related metadata but does not print a credential-bearing value", "evidence": {"match": "print(\"   - Generate a new SECRET_KEY: openssl rand -hex 32\")", "reason": "Log message mentions credential-related metadata but does not print a credential-bearing value", "rule_id": "SEC020", "scanner": "repobility-threat-engine", "confidence": 0.15, "correlation_key": "secret|setup.py|9|print - generate a new secret_key: openssl rand -hex 32"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "setup.py"}, "region": {"startLine": 100}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: PUT /items/{item_id}."}, "properties": {"repobilityId": 30214, "scanner": "repobility-access-control", "fingerprint": "242ea60f9ecfca1ddab97578fa26c85d09544206142de89601c7545619cdf139", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/items/{item_id}", "method": "PUT", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/core/utils/cache.py|260|cwe-639", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/core/utils/cache.py"}, "region": {"startLine": 260}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: GET /users/{user_id}/items."}, "properties": {"repobilityId": 30213, "scanner": "repobility-access-control", "fingerprint": "8e4b9e87acee413a427bb638e4d642e36253cddc58bee2f9b9ffcc5859aa426f", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/users/{user_id}/items", "method": "GET", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/core/utils/cache.py|253|cwe-639", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/core/utils/cache.py"}, "region": {"startLine": 253}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: GET /sample/{resource_id}."}, "properties": {"repobilityId": 30212, "scanner": "repobility-access-control", "fingerprint": "2fb7c249803d76c92e1fed385929bc96d8446cf312c67ca2f2a70cd5ed19e77f", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/sample/{resource_id}", "method": "GET", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/core/utils/cache.py|234|cwe-639", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/core/utils/cache.py"}, "region": {"startLine": 234}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: PATCH /{username}/post/{id}."}, "properties": {"repobilityId": 30211, "scanner": "repobility-access-control", "fingerprint": "6d0df561080b5fd6dbd6f89544bc221d0adaada91af2e0c21cfc5b78399e73bf", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/{username}/post/{id}", "method": "PATCH", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/api/v1/posts.py|93|cwe-639", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/api/v1/posts.py"}, "region": {"startLine": 93}}}]}, {"ruleId": "AUC003", "level": "error", "message": {"text": "[AUC003] Object-level route lacks visible authorization: A route with an object id-like parameter does not show nearby authentication or authorization evidence. This is a BOLA/IDOR review target. Endpoint: GET /task/{task_id}."}, "properties": {"repobilityId": 30210, "scanner": "repobility-access-control", "fingerprint": "7804220d66f5cf8bbf225a7c8fc00d017214c7ee8def532cf29b268ef122101e", "category": "auth", "severity": "high", "confidence": 0.7, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/task/{task_id}", "method": "GET", "scanner": "repobility-access-control", "framework": "FastAPI", "correlation_key": "code|auth|src/app/api/v1/tasks.py|37|cwe-639", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/api/v1/tasks.py"}, "region": {"startLine": 37}}}]}, {"ruleId": "DKR014", "level": "error", "message": {"text": "Dockerfile copies the entire context without .dockerignore"}, "properties": {"repobilityId": 30172, "scanner": "repobility-docker", "fingerprint": "991af6c07b80f70e33a18f6ad75a338f8ebc5eb9d8f4222f1296d773f343a8e0", "category": "docker", "severity": "high", "confidence": 0.92, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Broad context copy and missing .dockerignore were found together.", "evidence": {"rule_id": "DKR014", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|991af6c07b80f70e33a18f6ad75a338f8ebc5eb9d8f4222f1296d773f343a8e0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "scripts/local_with_uvicorn/Dockerfile"}, "region": {"startLine": 17}}}]}, {"ruleId": "SEC029", "level": "error", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes endpoints, file:// URIs), exfiltrate data, or pivot through your network. SSRF is OWASP A10:2021 and a frequent foothold in cloud breaches."}, "properties": {"repobilityId": 30167, "scanner": "repobility-threat-engine", "fingerprint": "1312ff8f81d8ab91be8241156535573c6007b1122e36186137a66a0fae629e77", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "url(r", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|1312ff8f81d8ab91be8241156535573c6007b1122e36186137a66a0fae629e77"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/core/utils/rate_limit.py"}, "region": {"startLine": 27}}}]}, {"ruleId": "SEC029", "level": "error", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes endpoints, file:// URIs), exfiltrate data, or pivot through your network. SSRF is OWASP A10:2021 and a frequent foothold in cloud breaches."}, "properties": {"repobilityId": 30166, "scanner": "repobility-threat-engine", "fingerprint": "8b6f5df084ad6f6209d117fcbf47f41091e7892b70d8ce10c6e7d33fcf52b517", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "url(s", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|8b6f5df084ad6f6209d117fcbf47f41091e7892b70d8ce10c6e7d33fcf52b517"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/core/setup.py"}, "region": {"startLine": 45}}}]}, {"ruleId": "SEC029", "level": "error", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes endpoints, file:// URIs), exfiltrate data, or pivot through your network. SSRF is OWASP A10:2021 and a frequent foothold in cloud breaches."}, "properties": {"repobilityId": 30165, "scanner": "repobility-threat-engine", "fingerprint": "0991ade56b5cebb1a79ca138782556dfeda09827b2940959d5f8bc03b76578a3", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "URL(s", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|0991ade56b5cebb1a79ca138782556dfeda09827b2940959d5f8bc03b76578a3"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/app/core/config.py"}, "region": {"startLine": 113}}}]}]}]}