{"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": "JRN002", "name": "Browser storage is used for session token material", "shortDescription": {"text": "Browser storage is used for session token material"}, "fullDescription": {"text": "Prefer httpOnly, Secure, SameSite cookies or short-lived in-memory tokens. Avoid persistent browser storage for access, refresh, ID, or partner session tokens."}, "properties": {"scanner": "repobility-journey-contract", "category": "auth", "severity": "medium", "confidence": 0.82, "cwe": "", "owasp": ""}}, {"id": "DKC005", "name": "Compose service adds dangerous Linux capabilities", "shortDescription": {"text": "Compose service adds dangerous Linux capabilities"}, "fullDescription": {"text": "Drop all capabilities by default and add only narrowly required capabilities after review."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "DKR003", "name": "Compose service `SnapOtter` image uses the latest tag", "shortDescription": {"text": "Compose service `SnapOtter` image uses the latest tag"}, "fullDescription": {"text": "Pin to a maintained version tag or digest and update it deliberately through dependency automation."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.94, "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": "Add a non-root USER in the final runtime stage after files and permissions are prepared."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.82, "cwe": "", "owasp": ""}}, {"id": "DKR014", "name": "Dockerfile copies broad context with incomplete .dockerignore", "shortDescription": {"text": "Dockerfile copies broad context with incomplete .dockerignore"}, "fullDescription": {"text": "Tighten .dockerignore or replace COPY . with explicit COPY statements."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.76, "cwe": "", "owasp": ""}}, {"id": "ERR002", "name": "[ERR002] Empty Catch Block: Empty catch blocks hide errors.", "shortDescription": {"text": "[ERR002] Empty Catch Block: Empty catch blocks hide errors."}, "fullDescription": {"text": "Log the error or rethrow it. Use console.error() at minimum."}, "properties": {"scanner": "repobility-threat-engine", "category": "error_handling", "severity": "medium", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC007", "name": "[SEC007] Unsafe Deserialization: Unsafe deserialization can execute arbitrary code.", "shortDescription": {"text": "[SEC007] Unsafe Deserialization: Unsafe deserialization can execute arbitrary code."}, "fullDescription": {"text": "Use yaml.safe_load() instead of yaml.load(). Avoid pickle for untrusted data."}, "properties": {"scanner": "repobility-threat-engine", "category": "deserialization", "severity": "medium", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "DKC010", "name": "Compose service lacks no-new-privileges hardening", "shortDescription": {"text": "Compose service lacks no-new-privileges hardening"}, "fullDescription": {"text": "Add `security_opt: [\"no-new-privileges:true\"]` unless the service has a documented need for privilege escalation."}, "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": "Set a non-root `user:` in Compose or ensure the final image stage has a non-root USER directive."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.56, "cwe": "", "owasp": ""}}, {"id": "DKR008", "name": ".dockerignore misses sensitive defaults", "shortDescription": {"text": ".dockerignore misses sensitive defaults"}, "fullDescription": {"text": "Add missing patterns such as .env, .git, private keys, certificates, dependency folders, and local databases."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "DKR012", "name": "Dockerfile keeps pip download cache", "shortDescription": {"text": "Dockerfile keeps pip download cache"}, "fullDescription": {"text": "Use `pip install --no-cache-dir ...` in container builds."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "AIC003", "name": "Duplicated implementation block across source files", "shortDescription": {"text": "Duplicated implementation block across source files"}, "fullDescription": {"text": "Extract the shared behavior into one function/module or delete the inactive duplicate after proving which path is used."}, "properties": {"scanner": "repobility-ai-code-hygiene", "category": "quality", "severity": "low", "confidence": 0.86, "cwe": "", "owasp": ""}}, {"id": "DKR002", "name": "Dockerfile base image is selected through a build variable", "shortDescription": {"text": "Dockerfile base image is selected through a build variable"}, "fullDescription": {"text": "Resolve the variable to a versioned tag or digest in production builds and document the allowed images."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "info", "confidence": 0.48, "cwe": "", "owasp": ""}}, {"id": "SEC011", "name": "[SEC011] Unsafe PyTorch Model Loading: torch.load() uses pickle internally and can execute arbitrary code from untrusted", "shortDescription": {"text": "[SEC011] Unsafe PyTorch Model Loading: torch.load() uses pickle internally and can execute arbitrary code from untrusted model files."}, "fullDescription": {"text": "Use torch.load(..., weights_only=True) or use safetensors format."}, "properties": {"scanner": "repobility-threat-engine", "category": "deserialization", "severity": "info", "confidence": 0.1, "cwe": "", "owasp": ""}}, {"id": "SEC013", "name": "[SEC013] Path Traversal \u2014 User Input in File Path (and 8 more): Same pattern found in 8 additional files. Review if need", "shortDescription": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path (and 8 more): Same pattern found in 8 additional files. Review if needed."}, "fullDescription": {"text": "Use os.path.realpath() and verify the path starts with your expected base directory. Use secure_filename() for uploads."}, "properties": {"scanner": "repobility-threat-engine", "category": "path_traversal", "severity": "info", "confidence": 0.2, "cwe": "", "owasp": ""}}, {"id": "SEC015", "name": "[SEC015] Insecure Randomness for Security (and 2 more): Same pattern found in 2 additional files. Review if needed.", "shortDescription": {"text": "[SEC015] Insecure Randomness for Security (and 2 more): Same pattern found in 2 additional files. Review if needed."}, "fullDescription": {"text": "Use secrets module (Python) or crypto.getRandomValues() (JS) for security-sensitive randomness."}, "properties": {"scanner": "repobility-threat-engine", "category": "crypto", "severity": "info", "confidence": 0.2, "cwe": "", "owasp": ""}}, {"id": "SEC029", "name": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 36 more): Same pattern found in 36 addi", "shortDescription": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 36 more): Same pattern found in 36 additional files. Review if needed."}, "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": "info", "confidence": 0.2, "cwe": "", "owasp": ""}}, {"id": "JRN009", "name": "Secret-like setting is echoed into a password input value", "shortDescription": {"text": "Secret-like setting is echoed into a password input value"}, "fullDescription": {"text": "Never prefill secret fields with stored values. Show a masked status such as configured/not configured, require explicit rotation to replace the value, and return the raw key only once at creation time."}, "properties": {"scanner": "repobility-journey-contract", "category": "auth", "severity": "high", "confidence": 0.83, "cwe": "", "owasp": ""}}, {"id": "DKC007", "name": "Compose service contains a literal secret environment value", "shortDescription": {"text": "Compose service contains a literal secret environment value"}, "fullDescription": {"text": "Rotate the value if real. Move it to Docker Compose secrets, a platform secret manager, or an uncommitted environment file."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "critical", "confidence": 0.96, "cwe": "", "owasp": ""}}, {"id": "DKR005", "name": "Docker image bakes a secret-like ENV value", "shortDescription": {"text": "Docker image bakes a secret-like ENV value"}, "fullDescription": {"text": "Remove the secret from the Dockerfile, rotate the value if real, and inject runtime secrets through your platform secret manager."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "critical", "confidence": 0.96, "cwe": "", "owasp": ""}}, {"id": "SEC001", "name": "[SEC001] Hardcoded Password: Hardcoded password found in source code.", "shortDescription": {"text": "[SEC001] Hardcoded Password: Hardcoded password found in source code."}, "fullDescription": {"text": "Use environment variables or a secrets manager."}, "properties": {"scanner": "repobility-threat-engine", "category": "credential_exposure", "severity": "critical", "confidence": 0.9, "cwe": "", "owasp": ""}}]}}, "automationDetails": {"id": "repobility/473"}, "properties": {"repository": "snapotter-hq/SnapOtter", "repoUrl": "https://github.com/snapotter-hq/SnapOtter", "branch": "main"}, "results": [{"ruleId": "JRN002", "level": "warning", "message": {"text": "Browser storage is used for session token material"}, "properties": {"repobilityId": 27735, "scanner": "repobility-journey-contract", "fingerprint": "475d539b55a4b83c277cfb1fc5c0a7c80882050aa4dbf603f46887324b776e51", "category": "auth", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Storage API call references token-like key or value names.", "evidence": {"rule_id": "JRN002", "scanner": "repobility-journey-contract", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html"], "correlation_key": "code|auth|token|22|jrn002"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "tests/e2e-analytics/helpers.ts"}, "region": {"startLine": 22}}}]}, {"ruleId": "JRN002", "level": "warning", "message": {"text": "Browser storage is used for session token material"}, "properties": {"repobilityId": 27734, "scanner": "repobility-journey-contract", "fingerprint": "a8638b5f42f0214668a7501318b78905e27cacc137ae9d3bfb531f1331e5913d", "category": "auth", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Storage API call references token-like key or value names.", "evidence": {"rule_id": "JRN002", "scanner": "repobility-journey-contract", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html"], "correlation_key": "code|auth|token|11|jrn002"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "tests/e2e-analytics/helpers.ts"}, "region": {"startLine": 11}}}]}, {"ruleId": "JRN002", "level": "warning", "message": {"text": "Browser storage is used for session token material"}, "properties": {"repobilityId": 27733, "scanner": "repobility-journey-contract", "fingerprint": "4306f287d0d078d413059dbf9788b07b73d0519e280343e6560d129480b73db2", "category": "auth", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Storage API call references token-like key or value names.", "evidence": {"rule_id": "JRN002", "scanner": "repobility-journey-contract", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html"], "correlation_key": "code|auth|tests/e2e/auth.setup.ts|18|jrn002"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "tests/e2e/auth.setup.ts"}, "region": {"startLine": 18}}}]}, {"ruleId": "JRN002", "level": "warning", "message": {"text": "Browser storage is used for session token material"}, "properties": {"repobilityId": 27732, "scanner": "repobility-journey-contract", "fingerprint": "900ff3b58e5697bbf9773c345fc4e641efdaf5a8bf45051013fefce8bc8ad22f", "category": "auth", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Storage API call references token-like key or value names.", "evidence": {"rule_id": "JRN002", "scanner": "repobility-journey-contract", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html"], "correlation_key": "code|auth|apps/web/src/lib/api.ts|160|jrn002"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/lib/api.ts"}, "region": {"startLine": 160}}}]}, {"ruleId": "JRN002", "level": "warning", "message": {"text": "Browser storage is used for session token material"}, "properties": {"repobilityId": 27731, "scanner": "repobility-journey-contract", "fingerprint": "c383742410854640702871d19b14e508f0cb499aacefefb58b062d8df4944ef7", "category": "auth", "severity": "medium", "confidence": 0.82, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Storage API call references token-like key or value names.", "evidence": {"rule_id": "JRN002", "scanner": "repobility-journey-contract", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html"], "correlation_key": "code|auth|apps/web/src/lib/api.ts|49|jrn002"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/lib/api.ts"}, "region": {"startLine": 49}}}]}, {"ruleId": "DKC005", "level": "warning", "message": {"text": "Compose service adds dangerous Linux capabilities"}, "properties": {"repobilityId": 27727, "scanner": "repobility-docker", "fingerprint": "d470a013120fde716ac2d45d994b569a48952619452b4793f3a13a92f3167d72", "category": "docker", "severity": "medium", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "cap_add includes broad or sensitive Linux capabilities.", "evidence": {"rule_id": "DKC005", "scanner": "repobility-docker", "service": "SnapOtter", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "capabilities": ["DAC_OVERRIDE"], "correlation_key": "fp|d470a013120fde716ac2d45d994b569a48952619452b4793f3a13a92f3167d72"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/docker-compose.yml"}, "region": {"startLine": 7}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `SnapOtter` image uses the latest tag"}, "properties": {"repobilityId": 27726, "scanner": "repobility-docker", "fingerprint": "354819debbfe821ef9d637b7d802b5b6b31eb99723a510f6aba05511de0e11e8", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "snapotter: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|354819debbfe821ef9d637b7d802b5b6b31eb99723a510f6aba05511de0e11e8"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/docker-compose.yml"}, "region": {"startLine": 7}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 27725, "scanner": "repobility-docker", "fingerprint": "05071d65dbd50ce049da7f9e92dfd54464f32e895e4eabbd0ef23a0cacdad7bf", "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": "node:22-bookworm", "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|05071d65dbd50ce049da7f9e92dfd54464f32e895e4eabbd0ef23a0cacdad7bf"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile.test"}, "region": {"startLine": 6}}}]}, {"ruleId": "DKR014", "level": "warning", "message": {"text": "Dockerfile copies broad context with incomplete .dockerignore"}, "properties": {"repobilityId": 27723, "scanner": "repobility-docker", "fingerprint": "9b653958dd51e182b551061fa2dd19a69592d9d771e79d4d0792aacc494922c5", "category": "docker", "severity": "medium", "confidence": 0.76, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Broad context copy found and .dockerignore misses sensitive defaults.", "evidence": {"rule_id": "DKR014", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|9b653958dd51e182b551061fa2dd19a69592d9d771e79d4d0792aacc494922c5", "missing_patterns": ["id_rsa", "*.pem", "*.key"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile.test"}, "region": {"startLine": 39}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 27721, "scanner": "repobility-docker", "fingerprint": "5f654ea5a992c3a37d66ea3eea91cd85fc91f7d45742a02957a3741bee39cfbf", "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": "base-${TARGETOS}-${TARGETARCH}", "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|5f654ea5a992c3a37d66ea3eea91cd85fc91f7d45742a02957a3741bee39cfbf"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 125}}}]}, {"ruleId": "ERR002", "level": "warning", "message": {"text": "[ERR002] Empty Catch Block: Empty catch blocks hide errors."}, "properties": {"repobilityId": 27677, "scanner": "repobility-threat-engine", "fingerprint": "f61e14c2e97849429867da5799fbf0de3545d130101bc27f143dbc97abab9fc0", "category": "error_handling", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".catch(() => {})", "reason": "Pattern matched with no mitigating context found", "rule_id": "ERR002", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|f61e14c2e97849429867da5799fbf0de3545d130101bc27f143dbc97abab9fc0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/user-files.ts"}, "region": {"startLine": 449}}}]}, {"ruleId": "ERR002", "level": "warning", "message": {"text": "[ERR002] Empty Catch Block: Empty catch blocks hide errors."}, "properties": {"repobilityId": 27676, "scanner": "repobility-threat-engine", "fingerprint": "7c090833b7d0a9054dddad81cf3e1aea37fe443673e9495bd36a8b7d1cf77239", "category": "error_handling", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".catch(() => {})", "reason": "Pattern matched with no mitigating context found", "rule_id": "ERR002", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|7c090833b7d0a9054dddad81cf3e1aea37fe443673e9495bd36a8b7d1cf77239"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/info.ts"}, "region": {"startLine": 170}}}]}, {"ruleId": "ERR002", "level": "warning", "message": {"text": "[ERR002] Empty Catch Block: Empty catch blocks hide errors."}, "properties": {"repobilityId": 27675, "scanner": "repobility-threat-engine", "fingerprint": "9bed9dbb3b3053d639a21aa47dce12f5484ccece6c6405490a5149b8d5a5574d", "category": "error_handling", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".catch(() => {})", "reason": "Pattern matched with no mitigating context found", "rule_id": "ERR002", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|9bed9dbb3b3053d639a21aa47dce12f5484ccece6c6405490a5149b8d5a5574d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/convert.ts"}, "region": {"startLine": 125}}}]}, {"ruleId": "SEC007", "level": "warning", "message": {"text": "[SEC007] Unsafe Deserialization: Unsafe deserialization can execute arbitrary code."}, "properties": {"repobilityId": 27674, "scanner": "repobility-threat-engine", "fingerprint": "058074753ff067ce1ee95afb2e593cb22a8c79957b2880c02ede053a42942c1c", "category": "deserialization", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "yaml.load(", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC007", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "code|deserialization|apps/api/src/routes/docs.ts|147|sec007"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/docs.ts"}, "region": {"startLine": 147}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 27730, "scanner": "repobility-docker", "fingerprint": "83489de42ca329e9d7d2db1288823f9495499f4e83c52e457f331da2c135bbcb", "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": "SnapOtter", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|83489de42ca329e9d7d2db1288823f9495499f4e83c52e457f331da2c135bbcb"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/docker-compose.yml"}, "region": {"startLine": 7}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 27728, "scanner": "repobility-docker", "fingerprint": "593223633e8729aa82259d67c968d9e7c53e6d8660f00b50d6443fa45c99e8e4", "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": "SnapOtter", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|593223633e8729aa82259d67c968d9e7c53e6d8660f00b50d6443fa45c99e8e4"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/docker-compose.yml"}, "region": {"startLine": 7}}}]}, {"ruleId": "DKR008", "level": "note", "message": {"text": ".dockerignore misses sensitive defaults"}, "properties": {"repobilityId": 27722, "scanner": "repobility-docker", "fingerprint": "aea2ad92c68c4ee1f8432bb1ec25e7d45ac12c9e1790ac2d3fffe638b1acce12", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "A Docker build context should exclude secrets and repository metadata.", "evidence": {"rule_id": "DKR008", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|aea2ad92c68c4ee1f8432bb1ec25e7d45ac12c9e1790ac2d3fffe638b1acce12", "missing_patterns": ["id_rsa", "*.pem", "*.key"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".dockerignore"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR012", "level": "note", "message": {"text": "Dockerfile keeps pip download cache"}, "properties": {"repobilityId": 27720, "scanner": "repobility-docker", "fingerprint": "e249c8b9ee2c1c9f17ab00d0dc473172012416ba0cf8e66feec9010ec81725d5", "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|e249c8b9ee2c1c9f17ab00d0dc473172012416ba0cf8e66feec9010ec81725d5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 199}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27718, "scanner": "repobility-ai-code-hygiene", "fingerprint": "8c0c63e0445871b69989c4ea783eb2ee5397927949d134c64ab3653054a48497", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/pipeline.ts", "duplicate_line": 66, "correlation_key": "fp|8c0c63e0445871b69989c4ea783eb2ee5397927949d134c64ab3653054a48497"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/edit-metadata.ts"}, "region": {"startLine": 119}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27717, "scanner": "repobility-ai-code-hygiene", "fingerprint": "6bdd47e0bb263b627f7e3a65dbea0a49d6c79ae4586d2d738af748009bd576bf", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/ai-canvas-expand.ts", "duplicate_line": 65, "correlation_key": "fp|6bdd47e0bb263b627f7e3a65dbea0a49d6c79ae4586d2d738af748009bd576bf"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/edit-metadata.ts"}, "region": {"startLine": 107}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27716, "scanner": "repobility-ai-code-hygiene", "fingerprint": "577f24cd31853df6e12d147e7a10dd7ac55212a77b2649ed40db6739fce37213", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 62, "correlation_key": "fp|577f24cd31853df6e12d147e7a10dd7ac55212a77b2649ed40db6739fce37213"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/edit-metadata.ts"}, "region": {"startLine": 104}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27715, "scanner": "repobility-ai-code-hygiene", "fingerprint": "2a544fd08471066e8470319a8c74000d591ccb0dbfdd5754153024483e23e7a5", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/color-palette.ts", "duplicate_line": 36, "correlation_key": "fp|2a544fd08471066e8470319a8c74000d591ccb0dbfdd5754153024483e23e7a5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/edit-metadata.ts"}, "region": {"startLine": 69}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27714, "scanner": "repobility-ai-code-hygiene", "fingerprint": "ef0a30d06373561ee2268b4480d8ba5d83d1e790def41dd6bd2c882c5aa9b2b6", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/lib/format-decoders.ts", "duplicate_line": 104, "correlation_key": "fp|ef0a30d06373561ee2268b4480d8ba5d83d1e790def41dd6bd2c882c5aa9b2b6"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/convert.ts"}, "region": {"startLine": 22}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27713, "scanner": "repobility-ai-code-hygiene", "fingerprint": "ddc5b854cd1b4c4162f19c8ccd8a44d619548345de2479344fe7697194478c0e", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/lib/format-encoders.ts", "duplicate_line": 9, "correlation_key": "fp|ddc5b854cd1b4c4162f19c8ccd8a44d619548345de2479344fe7697194478c0e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/convert.ts"}, "region": {"startLine": 21}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27712, "scanner": "repobility-ai-code-hygiene", "fingerprint": "3b3c25f23ddcdd23ab24d9e56bcaf012954156dd6b72c4a00527de757f7e90a1", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/pipeline.ts", "duplicate_line": 66, "correlation_key": "fp|3b3c25f23ddcdd23ab24d9e56bcaf012954156dd6b72c4a00527de757f7e90a1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/content-aware-resize.ts"}, "region": {"startLine": 43}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27711, "scanner": "repobility-ai-code-hygiene", "fingerprint": "ef92e307868676f089ee5e5e6cbbbdd53bb64ee9cc32f58bb56f7882039a7f14", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/ai-canvas-expand.ts", "duplicate_line": 65, "correlation_key": "fp|ef92e307868676f089ee5e5e6cbbbdd53bb64ee9cc32f58bb56f7882039a7f14"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/content-aware-resize.ts"}, "region": {"startLine": 31}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27710, "scanner": "repobility-ai-code-hygiene", "fingerprint": "97a7b01220a789e436c2ff934e6edd4540280724f46bafa6d11cbdd22453b035", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 62, "correlation_key": "fp|97a7b01220a789e436c2ff934e6edd4540280724f46bafa6d11cbdd22453b035"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/content-aware-resize.ts"}, "region": {"startLine": 28}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27709, "scanner": "repobility-ai-code-hygiene", "fingerprint": "4ff45a23328ecb86dab046b7be59dee0668c004ea3ee7e6ea2fe9ac36e4d1a1f", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 93, "correlation_key": "fp|4ff45a23328ecb86dab046b7be59dee0668c004ea3ee7e6ea2fe9ac36e4d1a1f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/compose.ts"}, "region": {"startLine": 89}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27708, "scanner": "repobility-ai-code-hygiene", "fingerprint": "6d38a24ee41ac78c575a1834426eb0ea796b8bf3e8dfa4a7bb9c55a2626684b1", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/beautify.ts", "duplicate_line": 231, "correlation_key": "fp|6d38a24ee41ac78c575a1834426eb0ea796b8bf3e8dfa4a7bb9c55a2626684b1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/compose.ts"}, "region": {"startLine": 72}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27707, "scanner": "repobility-ai-code-hygiene", "fingerprint": "fe8c7f6d0dac7930230b115f702ae43830cd40f11f9db24e8263fb902765d9e9", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 93, "correlation_key": "fp|fe8c7f6d0dac7930230b115f702ae43830cd40f11f9db24e8263fb902765d9e9"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/colorize.ts"}, "region": {"startLine": 72}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27706, "scanner": "repobility-ai-code-hygiene", "fingerprint": "86c59b2ce95855ada83bc37274f17884cc28fa7c488daede6e69815e801c3d45", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/blur-faces.ts", "duplicate_line": 62, "correlation_key": "fp|86c59b2ce95855ada83bc37274f17884cc28fa7c488daede6e69815e801c3d45"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/colorize.ts"}, "region": {"startLine": 62}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27705, "scanner": "repobility-ai-code-hygiene", "fingerprint": "88aca7b1aec22a57c75d2b24d29c156c7211a6103af2a41fe29dbeb8b0db17d5", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/pipeline.ts", "duplicate_line": 66, "correlation_key": "fp|88aca7b1aec22a57c75d2b24d29c156c7211a6103af2a41fe29dbeb8b0db17d5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/colorize.ts"}, "region": {"startLine": 58}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27704, "scanner": "repobility-ai-code-hygiene", "fingerprint": "b2188112f68cc5b1793ce337b470b1e70b694662c3561fc67477a38122f3093e", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/ai-canvas-expand.ts", "duplicate_line": 51, "correlation_key": "fp|b2188112f68cc5b1793ce337b470b1e70b694662c3561fc67477a38122f3093e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/colorize.ts"}, "region": {"startLine": 27}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27703, "scanner": "repobility-ai-code-hygiene", "fingerprint": "e7eb5db17f62d5ec35c8213dbc492ac33051208e0b82a9062b371e73b1226bcf", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 109, "correlation_key": "fp|e7eb5db17f62d5ec35c8213dbc492ac33051208e0b82a9062b371e73b1226bcf"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/color-palette.ts"}, "region": {"startLine": 64}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27702, "scanner": "repobility-ai-code-hygiene", "fingerprint": "90bbfdc19030d31ae9ebadd77cb7f37b4d57805207328b23bd980c0b2f26eaad", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 93, "correlation_key": "fp|90bbfdc19030d31ae9ebadd77cb7f37b4d57805207328b23bd980c0b2f26eaad"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/collage.ts"}, "region": {"startLine": 472}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27701, "scanner": "repobility-ai-code-hygiene", "fingerprint": "777bde2a81d55f84a796435c44dff9d98ae84c39d0893aa7c1c0fbf942d0ec9d", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/bulk-rename.ts", "duplicate_line": 14, "correlation_key": "fp|777bde2a81d55f84a796435c44dff9d98ae84c39d0893aa7c1c0fbf942d0ec9d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/collage.ts"}, "region": {"startLine": 399}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27700, "scanner": "repobility-ai-code-hygiene", "fingerprint": "93783bb599f5d4230e8ab31409d1f1834e8c180edc7692b7bb25878fea0274e6", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 93, "correlation_key": "fp|93783bb599f5d4230e8ab31409d1f1834e8c180edc7692b7bb25878fea0274e6"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/bulk-rename.ts"}, "region": {"startLine": 43}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27699, "scanner": "repobility-ai-code-hygiene", "fingerprint": "fd678e0f83e589cd12bd967dafc965e5a45397d36c4992eb2b5ec7b9ec0fb15b", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/lib/beautify/shadow.ts", "duplicate_line": 28, "correlation_key": "fp|fd678e0f83e589cd12bd967dafc965e5a45397d36c4992eb2b5ec7b9ec0fb15b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/border.ts"}, "region": {"startLine": 82}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27698, "scanner": "repobility-ai-code-hygiene", "fingerprint": "c4dc90811302e96cb5b5d889baccbecdbbd71c0ba5019bd21a7ac617d9c39ab5", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 93, "correlation_key": "fp|c4dc90811302e96cb5b5d889baccbecdbbd71c0ba5019bd21a7ac617d9c39ab5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/blur-faces.ts"}, "region": {"startLine": 72}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27697, "scanner": "repobility-ai-code-hygiene", "fingerprint": "9726a632d9bc6443b0c70f64d7fdfc1a4631e01ea2e1a7abce22e8a69456a2b3", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/pipeline.ts", "duplicate_line": 66, "correlation_key": "fp|9726a632d9bc6443b0c70f64d7fdfc1a4631e01ea2e1a7abce22e8a69456a2b3"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/blur-faces.ts"}, "region": {"startLine": 58}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27696, "scanner": "repobility-ai-code-hygiene", "fingerprint": "a85de382530ca227e5b5bf84dd1848901cee74464cbb599d3b9f94302e7a9348", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/ai-canvas-expand.ts", "duplicate_line": 51, "correlation_key": "fp|a85de382530ca227e5b5bf84dd1848901cee74464cbb599d3b9f94302e7a9348"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/blur-faces.ts"}, "region": {"startLine": 27}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27695, "scanner": "repobility-ai-code-hygiene", "fingerprint": "8e0199aa28645a0a866920079691a186584d31b1c9c30ff23d5265057d52d34d", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/barcode-read.ts", "duplicate_line": 95, "correlation_key": "fp|8e0199aa28645a0a866920079691a186584d31b1c9c30ff23d5265057d52d34d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/beautify.ts"}, "region": {"startLine": 247}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27694, "scanner": "repobility-ai-code-hygiene", "fingerprint": "cc1f50771d1993e3aef47a91d4edc04b392cc61d413f2a5e78fa14bbac609f77", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/pipeline.ts", "duplicate_line": 66, "correlation_key": "fp|cc1f50771d1993e3aef47a91d4edc04b392cc61d413f2a5e78fa14bbac609f77"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/barcode-read.ts"}, "region": {"startLine": 77}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27693, "scanner": "repobility-ai-code-hygiene", "fingerprint": "967a2b854347dd2800b584754a04a896cce5cfb8ac0868dade9cbca876cbd4aa", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/tools/ai-canvas-expand.ts", "duplicate_line": 65, "correlation_key": "fp|967a2b854347dd2800b584754a04a896cce5cfb8ac0868dade9cbca876cbd4aa"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/barcode-read.ts"}, "region": {"startLine": 65}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27692, "scanner": "repobility-ai-code-hygiene", "fingerprint": "9c5a017a980e2beed2e65bbb907c21b8eedf35de5afef593cc37298effc3229d", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/pipeline.ts", "duplicate_line": 66, "correlation_key": "fp|9c5a017a980e2beed2e65bbb907c21b8eedf35de5afef593cc37298effc3229d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/tools/ai-canvas-expand.ts"}, "region": {"startLine": 82}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27691, "scanner": "repobility-ai-code-hygiene", "fingerprint": "4b0e25c3f80637a9566992aabb8321a41b360fcfc70c7b09a99f0f67b292a229", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/permissions.ts", "duplicate_line": 8, "correlation_key": "fp|4b0e25c3f80637a9566992aabb8321a41b360fcfc70c7b09a99f0f67b292a229"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/roles.ts"}, "region": {"startLine": 10}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27690, "scanner": "repobility-ai-code-hygiene", "fingerprint": "ff1be02fb865dc97ecb823e8a28c3e8f9054dab05dfa16f328d0f22d456dd26b", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/routes/batch.ts", "duplicate_line": 45, "correlation_key": "fp|ff1be02fb865dc97ecb823e8a28c3e8f9054dab05dfa16f328d0f22d456dd26b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/pipeline.ts"}, "region": {"startLine": 337}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 27689, "scanner": "repobility-ai-code-hygiene", "fingerprint": "012b9880ac37883f0120b6c307290101be127fcd901f155ed039865baee8f1d4", "category": "quality", "severity": "low", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "A normalized source-code window appears in two different non-test files.", "evidence": {"lines": 12, "rule_id": "AIC003", "scanner": "repobility-ai-code-hygiene", "references": ["https://jscpd.dev/"], "duplicate_file": "apps/api/src/lib/file-validation.ts", "duplicate_line": 127, "correlation_key": "fp|012b9880ac37883f0120b6c307290101be127fcd901f155ed039865baee8f1d4"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/lib/format-decoders.ts"}, "region": {"startLine": 18}}}]}, {"ruleId": "DKR002", "level": "none", "message": {"text": "Dockerfile base image is selected through a build variable"}, "properties": {"repobilityId": 27719, "scanner": "repobility-docker", "fingerprint": "4b0e0f87815cce5cb9da8d4a6ec8ed3d8babcd423518edd292c12e04e25d2ce0", "category": "docker", "severity": "info", "confidence": 0.48, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Base image contains a variable; manual review is needed to avoid false positives.", "evidence": {"image": "base-${TARGETOS}-${TARGETARCH}", "rule_id": "DKR002", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://docs.docker.com/scout/policy/"], "correlation_key": "fp|4b0e0f87815cce5cb9da8d4a6ec8ed3d8babcd423518edd292c12e04e25d2ce0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile"}, "region": {"startLine": 125}}}]}, {"ruleId": "SEC011", "level": "none", "message": {"text": "[SEC011] Unsafe PyTorch Model Loading: torch.load() uses pickle internally and can execute arbitrary code from untrusted model files."}, "properties": {"repobilityId": 27688, "scanner": "repobility-threat-engine", "fingerprint": "d800414b23b4e5bd1816dc3ae7edc740a18a070f6b0e91f77d21046ccbfe85de", "category": "deserialization", "severity": "info", "confidence": 0.1, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Safe pattern 'weights_only\\s*=\\s*True' detected on same line", "evidence": {"match": "torch.load(", "reason": "Safe pattern 'weights_only\\s*=\\s*True' detected on same line", "rule_id": "SEC011", "scanner": "repobility-threat-engine", "confidence": 0.1, "correlation_key": "code|deserialization|token|322|sec011"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/ai/python/noise_removal.py"}, "region": {"startLine": 322}}}]}, {"ruleId": "SEC013", "level": "none", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path (and 8 more): Same pattern found in 8 additional files. Review if needed."}, "properties": {"repobilityId": 27687, "scanner": "repobility-threat-engine", "fingerprint": "520cf870aae10286e2adb5bcf0770a06c7548e0527e329db7df02bc6f58dfc6c", "category": "path_traversal", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 8 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 8 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|520cf870aae10286e2adb5bcf0770a06c7548e0527e329db7df02bc6f58dfc6c"}}}, {"ruleId": "SEC015", "level": "none", "message": {"text": "[SEC015] Insecure Randomness for Security (and 2 more): Same pattern found in 2 additional files. Review if needed."}, "properties": {"repobilityId": 27682, "scanner": "repobility-threat-engine", "fingerprint": "f78b05f3525efdc18a5d1983ba1263e47eaa8a772967c623a7aa23730bd5139a", "category": "crypto", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 2 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 2 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|f78b05f3525efdc18a5d1983ba1263e47eaa8a772967c623a7aa23730bd5139a"}}}, {"ruleId": "SEC015", "level": "none", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 27681, "scanner": "repobility-threat-engine", "fingerprint": "d421bf8408b6fe9282a927eab819832c91b83408856e806a2cea51cc0d45d039", "category": "crypto", "severity": "info", "confidence": 0.15, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Weak PRNG appears to be used for non-security behavior (UI, sampling, demos, shuffling, or backoff), not for secrets", "evidence": {"match": "Math.random()", "reason": "Weak PRNG appears to be used for non-security behavior (UI, sampling, demos, shuffling, or backoff), not for secrets", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 0.15, "correlation_key": "code|crypto|token|72|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/components/features/feature-install-prompt.tsx"}, "region": {"startLine": 72}}}]}, {"ruleId": "SEC015", "level": "none", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 27680, "scanner": "repobility-threat-engine", "fingerprint": "b4a4a8f00fba5fc1e5f8281286e6995f31c1d5995b83c2384c7d328c40d7bacd", "category": "crypto", "severity": "info", "confidence": 0.15, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Weak PRNG appears to be used for non-security behavior (UI, sampling, demos, shuffling, or backoff), not for secrets", "evidence": {"match": "Math.random()", "reason": "Weak PRNG appears to be used for non-security behavior (UI, sampling, demos, shuffling, or backoff), not for secrets", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 0.15, "correlation_key": "code|crypto|token|329|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/components/editor/konva-filters.ts"}, "region": {"startLine": 329}}}]}, {"ruleId": "SEC015", "level": "none", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 27679, "scanner": "repobility-threat-engine", "fingerprint": "1337238c17372c0d610c4dc134dfa8508ae14cbf5e36e537a7612587fb592d9e", "category": "crypto", "severity": "info", "confidence": 0.25, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Weak PRNG appears to be used for non-security behavior (UI, sampling, demos, shuffling, or backoff), not for secrets", "evidence": {"match": "Math.random()", "reason": "Weak PRNG appears to be used for non-security behavior (UI, sampling, demos, shuffling, or backoff), not for secrets", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 0.25, "correlation_key": "code|crypto|token|51|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/pages/change-password-page.tsx"}, "region": {"startLine": 51}}}]}, {"ruleId": "ERR002", "level": "none", "message": {"text": "[ERR002] Empty Catch Block (and 9 more): Same pattern found in 9 additional files. Review if needed."}, "properties": {"repobilityId": 27678, "scanner": "repobility-threat-engine", "fingerprint": "9cc98ec684a3e6bc47534b8969a978472a77e62faf58b476f27031bff834dc54", "category": "error_handling", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 9 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 9 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "ERR002", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|9cc98ec684a3e6bc47534b8969a978472a77e62faf58b476f27031bff834dc54"}}}, {"ruleId": "SEC029", "level": "none", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 36 more): Same pattern found in 36 additional files. Review if needed."}, "properties": {"repobilityId": 27673, "scanner": "repobility-threat-engine", "fingerprint": "de360f850ead589ee5e9ed6a342addc11eb9276bba1c673b6eea6332ec53bc3b", "category": "ssrf", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 36 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 36 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|de360f850ead589ee5e9ed6a342addc11eb9276bba1c673b6eea6332ec53bc3b"}}}, {"ruleId": "JRN009", "level": "error", "message": {"text": "Secret-like setting is echoed into a password input value"}, "properties": {"repobilityId": 27736, "scanner": "repobility-journey-contract", "fingerprint": "44b4ccf19f54d727c4c27986042f381c1675e48e15f0dc277ceb5cbab1f6313e", "category": "auth", "severity": "high", "confidence": 0.83, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "A password or secret-named input is populated from a secret-like variable instead of a masked placeholder.", "evidence": {"rule_id": "JRN009", "scanner": "repobility-journey-contract", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Session_Management_Cheat_Sheet.html"], "correlation_key": "code|auth|token|212|jrn009"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/pages/login-page.tsx"}, "region": {"startLine": 212}}}]}, {"ruleId": "SEC013", "level": "error", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "properties": {"repobilityId": 27686, "scanner": "repobility-threat-engine", "fingerprint": "9665b48af854d2f232233645c017a2f5351c37f20e0c6e924e915da678368246", "category": "path_traversal", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "User-controlled input detected in file path construction", "evidence": {"match": "open(input", "reason": "User-controlled input detected in file path construction", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.8, "correlation_key": "code|path_traversal|token|247|sec013"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/ai/python/enhance_faces.py"}, "region": {"startLine": 247}}}]}, {"ruleId": "SEC013", "level": "error", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "properties": {"repobilityId": 27685, "scanner": "repobility-threat-engine", "fingerprint": "6a3dfd80578e3007b9fbc14ba20353d37da6224a7edf37e451ff168bf6bf4816", "category": "path_traversal", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "User-controlled input detected in file path construction", "evidence": {"match": "open(input", "reason": "User-controlled input detected in file path construction", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.8, "correlation_key": "code|path_traversal|token|236|sec013"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/ai/python/detect_faces.py"}, "region": {"startLine": 236}}}]}, {"ruleId": "SEC013", "level": "error", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "properties": {"repobilityId": 27684, "scanner": "repobility-threat-engine", "fingerprint": "0cbaaa846711e93c5a2ba0413efb4e9a9d2a62e7761679ff5a28469b995ece50", "category": "path_traversal", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "User-controlled input detected in file path construction", "evidence": {"match": "open(input", "reason": "User-controlled input detected in file path construction", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.8, "correlation_key": "code|path_traversal|token|177|sec013"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "packages/ai/python/colorize.py"}, "region": {"startLine": 177}}}]}, {"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": 27672, "scanner": "repobility-threat-engine", "fingerprint": "ae800f9b23a4d131bc5de162d7322495f066d2729152afe590840b3fe4b4c08c", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "Url(u", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|ae800f9b23a4d131bc5de162d7322495f066d2729152afe590840b3fe4b4c08c"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/web/src/components/common/dropzone.tsx"}, "region": {"startLine": 131}}}]}, {"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": 27671, "scanner": "repobility-threat-engine", "fingerprint": "93eb4e4bcbc6673a70d5c5b034664fd7893b8e8d80558d20feb0d5d46cc8e5bc", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "Url(u", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|93eb4e4bcbc6673a70d5c5b034664fd7893b8e8d80558d20feb0d5d46cc8e5bc"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/routes/fetch-urls.ts"}, "region": {"startLine": 101}}}]}, {"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": 27670, "scanner": "repobility-threat-engine", "fingerprint": "85189c346cb77f821ae2ff2a6a1deb4ee0a84eccd521a3504fbd2ace417ce61a", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "URL(e", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|85189c346cb77f821ae2ff2a6a1deb4ee0a84eccd521a3504fbd2ace417ce61a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "apps/api/src/plugins/oidc.ts"}, "region": {"startLine": 30}}}]}, {"ruleId": "DKC007", "level": "error", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 27729, "scanner": "repobility-docker", "fingerprint": "04c4a94cd421e6903ec05379e3361daf175ce8817c0585ab236dded66478ddc9", "category": "docker", "severity": "critical", "confidence": 0.96, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Environment variable name is secret-like and value is a committed literal.", "evidence": {"rule_id": "DKC007", "scanner": "repobility-docker", "service": "SnapOtter", "variable": "DEFAULT_PASSWORD", "references": ["https://docs.docker.com/compose/how-tos/environment-variables/best-practices/", "https://docs.docker.com/reference/compose-file/secrets/"], "path_context": "runtime", "correlation_key": "fp|04c4a94cd421e6903ec05379e3361daf175ce8817c0585ab236dded66478ddc9", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/docker-compose.yml"}, "region": {"startLine": 7}}}]}, {"ruleId": "DKR005", "level": "error", "message": {"text": "Docker image bakes a secret-like ENV value"}, "properties": {"repobilityId": 27724, "scanner": "repobility-docker", "fingerprint": "78760c1254262b05a85e683d57e40cd4133d890564363e15ed79575ac4f1ca0b", "category": "docker", "severity": "critical", "confidence": 0.96, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "ENV assigns a literal value to a secret-like variable name.", "evidence": {"rule_id": "DKR005", "scanner": "repobility-docker", "variable": "DEFAULT_PASSWORD", "references": ["https://docs.docker.com/build/building/secrets/", "https://docs.docker.com/compose/how-tos/environment-variables/best-practices/"], "correlation_key": "fp|78760c1254262b05a85e683d57e40cd4133d890564363e15ed79575ac4f1ca0b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/Dockerfile.test"}, "region": {"startLine": 42}}}]}, {"ruleId": "SEC001", "level": "error", "message": {"text": "[SEC001] Hardcoded Password: Hardcoded password found in source code."}, "properties": {"repobilityId": 27683, "scanner": "repobility-threat-engine", "fingerprint": "41e1df3844dc5d23b11a4a2407d440f5ab1289a5c4275fbd85f89c5985a8b64e", "category": "credential_exposure", "severity": "critical", "confidence": 0.9, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "High entropy value (4.5 bits) \u2014 likely real secret", "evidence": {"match": "PASSWORD=\"<redacted>}\"", "reason": "High entropy value (4.5 bits) \u2014 likely real secret", "rule_id": "SEC001", "scanner": "repobility-threat-engine", "confidence": 0.9, "correlation_key": "secret|docker/entrypoint.sh|1|password redacted"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/entrypoint.sh"}, "region": {"startLine": 8}}}]}]}]}