{"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": "Add /.well-known/security.txt with Contact, Expires, Canonical, Preferred-Languages, and Policy fields. Keep the contact endpoint monitored."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "medium", "confidence": 0.78, "cwe": "", "owasp": ""}}, {"id": "WEB015", "name": "Public web app has no Content Security Policy", "shortDescription": {"text": "Public web app has no Content Security Policy"}, "fullDescription": {"text": "Add a Content-Security-Policy header through the web framework or hosting config. For static apps, add a CSP meta tag that restricts default-src, script-src, connect-src, img-src, and frame-ancestors."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "medium", "confidence": 0.7, "cwe": "", "owasp": ""}}, {"id": "JRN003", "name": "Frontend API reference is not matched by discovered backend routes", "shortDescription": {"text": "Frontend API reference is not matched by discovered backend routes"}, "fullDescription": {"text": "Add the backend route, update the frontend constant to the implemented endpoint, or document that the route is served by another service and exclude it with .repobilityignore."}, "properties": {"scanner": "repobility-journey-contract", "category": "quality", "severity": "medium", "confidence": 0.74, "cwe": "", "owasp": ""}}, {"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: ANY /cu"}, "fullDescription": {"text": "Require an explicit admin, maintainer, super_admin, or scoped service role in code and .repobility/access.yml."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.68, "cwe": "", "owasp": ""}}, {"id": "AUC004", "name": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence ", "shortDescription": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /work_package_prioriti"}, "fullDescription": {"text": "Define whether this endpoint is admin-only or super_admin-only, then enforce that distinction in code and .repobility/access.yml."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.66, "cwe": "", "owasp": ""}}, {"id": "AUC002", "name": "[AUC002] Low visible authorization coverage in route inventory: Only 15.7% of discovered routes show nearby authenticati", "shortDescription": {"text": "[AUC002] Low visible authorization coverage in route inventory: Only 15.7% of discovered routes show nearby authentication, authorization, middleware, or public-route evidence."}, "fullDescription": {"text": "Review the access matrix and add explicit framework auth declarations or policy-file exceptions for intentionally public routes."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.74, "cwe": "", "owasp": ""}}, {"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": "Add .repobility/access.yml mapping routes to anonymous, authenticated, owner, admin, and super_admin. Keep business-specific rules in the repo so CI can enforce them."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "medium", "confidence": 0.92, "cwe": "", "owasp": ""}}, {"id": "DKR003", "name": "Compose service `cuprite-chrome` image uses the latest tag", "shortDescription": {"text": "Compose service `cuprite-chrome` 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": "DKC015", "name": "Database service has no healthcheck", "shortDescription": {"text": "Database service has no healthcheck"}, "fullDescription": {"text": "Add a database-native healthcheck such as pg_isready, mysqladmin ping, redis-cli ping, or the vendor's readiness command."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.88, "cwe": "", "owasp": ""}}, {"id": "DKR002", "name": "Compose service `cache` image has no explicit tag", "shortDescription": {"text": "Compose service `cache` image has no explicit tag"}, "fullDescription": {"text": "Pin the image to a supported version tag or digest, for example python:3.13-slim or image@sha256:..."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.9, "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": "medium", "confidence": 0.56, "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": "DKR009", "name": "Dockerfile separates apt update from install", "shortDescription": {"text": "Dockerfile separates apt update from install"}, "fullDescription": {"text": "Combine update and install in the same RUN instruction and clean package indexes in that layer."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "medium", "confidence": 0.86, "cwe": "", "owasp": ""}}, {"id": "AIC004", "name": "Suspicious implementation file appears unreferenced", "shortDescription": {"text": "Suspicious implementation file appears unreferenced"}, "fullDescription": {"text": "Confirm whether this file is reachable. If not, delete it; if yes, wire it through explicit imports, routes, or entry points and add a test that proves the path executes."}, "properties": {"scanner": "repobility-ai-code-hygiene", "category": "quality", "severity": "medium", "confidence": 0.78, "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": "SEC134", "name": "[SEC134] AI scaffold leftover \u2014 Lorem ipsum / example.com / John Doe in code: Lorem ipsum / John Doe / example.com left ", "shortDescription": {"text": "[SEC134] AI scaffold leftover \u2014 Lorem ipsum / example.com / John Doe in code: Lorem ipsum / John Doe / example.com left in non-test code. AI agents emit these as 'reasonable defaults' when they don't know real values; the human then forgets"}, "fullDescription": {"text": "Move dummy values to fixtures / seed files. In application code, require these to come from config or fail closed. Add a CI grep that rejects 'lorem ipsum' and 'example.com' outside test files."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "medium", "confidence": 1.0, "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": "WEB011", "name": "Public web app has no humans.txt", "shortDescription": {"text": "Public web app has no humans.txt"}, "fullDescription": {"text": "Add humans.txt with team ownership, contact URL, key documentation links, and the last-updated date."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.5, "cwe": "", "owasp": ""}}, {"id": "WEB008", "name": "Public docs site has no llms.txt", "shortDescription": {"text": "Public docs site has no llms.txt"}, "fullDescription": {"text": "Add llms.txt with the product summary, canonical docs, API endpoints, security guidance, and preferred CLI workflow for AI agents."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.64, "cwe": "", "owasp": ""}}, {"id": "WEB002", "name": "Public web app has no sitemap", "shortDescription": {"text": "Public web app has no sitemap"}, "fullDescription": {"text": "Add sitemap.xml, a sitemap index, or a framework-native sitemap route and reference it from robots.txt."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "WEB001", "name": "Public web app has no robots.txt", "shortDescription": {"text": "Public web app has no robots.txt"}, "fullDescription": {"text": "Add robots.txt at the web root or a framework-native robots route. Include an explicit Sitemap directive and disallow only private paths."}, "properties": {"scanner": "repobility-web-presence", "category": "quality", "severity": "low", "confidence": 0.74, "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": "Give the database a healthcheck and change the dependency to `depends_on: { db: { condition: service_healthy } }`."}, "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": "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": "DKC017", "name": "Database password is wired through an environment variable placeholder", "shortDescription": {"text": "Database password is wired through an environment variable placeholder"}, "fullDescription": {"text": "Prefer Compose secrets or your platform secret manager with *_FILE variables where the image supports them. Rotate only if a real value was committed."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.58, "cwe": "", "owasp": ""}}, {"id": "DKR011", "name": "Dockerfile installs recommended OS packages", "shortDescription": {"text": "Dockerfile installs recommended OS packages"}, "fullDescription": {"text": "Add `--no-install-recommends` and explicitly list only packages the image needs."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.72, "cwe": "", "owasp": ""}}, {"id": "DKR010", "name": "Dockerfile leaves apt package indexes in the image layer", "shortDescription": {"text": "Dockerfile leaves apt package indexes in the image layer"}, "fullDescription": {"text": "End the apt install layer with `rm -rf /var/lib/apt/lists/*`."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "low", "confidence": 0.74, "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": "AIC005", "name": "Duplicate top-level symbol appears in a patch-style file", "shortDescription": {"text": "Duplicate top-level symbol appears in a patch-style file"}, "fullDescription": {"text": "Keep one authoritative implementation, update imports to point at it, and remove or rename the duplicate symbol."}, "properties": {"scanner": "repobility-ai-code-hygiene", "category": "quality", "severity": "low", "confidence": 0.64, "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": "AIC002", "name": "Source file name looks like an AI patch artifact", "shortDescription": {"text": "Source file name looks like an AI patch artifact"}, "fullDescription": {"text": "Rename it to the domain concept it implements or merge it into the existing module it was meant to change."}, "properties": {"scanner": "repobility-ai-code-hygiene", "category": "quality", "severity": "low", "confidence": 0.62, "cwe": "", "owasp": ""}}, {"id": "AIC009", "name": "Multiple AI-agent scaffold marker files are present", "shortDescription": {"text": "Multiple AI-agent scaffold marker files are present"}, "fullDescription": {"text": "Keep one current agent instruction file if it helps contributors, remove stale progress/completion markers, and make sure the README, tests, and CI describe the real supported behavior."}, "properties": {"scanner": "repobility-ai-code-hygiene", "category": "quality", "severity": "low", "confidence": 0.68, "cwe": "", "owasp": ""}}, {"id": "MINED043", "name": "[MINED043] Http Not Https: Hardcoded http:// (not localhost) for endpoints that handle credentials or data.", "shortDescription": {"text": "[MINED043] Http Not Https: Hardcoded http:// (not localhost) for endpoints that handle credentials or data."}, "fullDescription": {"text": "Review and fix per the pattern semantics. See CWE-319 / A02:2021 for context."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 1.0, "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.1, "cwe": "", "owasp": ""}}, {"id": "SEC029", "name": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 33 more): Same pattern found in 33 addi", "shortDescription": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 33 more): Same pattern found in 33 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": "SEC128", "name": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake) (and 19 more): Same pattern found in 19 add", "shortDescription": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake) (and 19 more): Same pattern found in 19 additional files. Review if needed."}, "fullDescription": {"text": "Add `await` before each async call, or chain with `.then`. If you intentionally want fire-and-forget, prefix with `void` (TS) or assign to `_` (Python with `asyncio.create_task`) to make the intent explicit and survive lint."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 0.2, "cwe": "", "owasp": ""}}, {"id": "MINED126", "name": "[MINED126] Workflow container/services image `postgres:16` unpinned: `container/services image: postgres:16` without `@s", "shortDescription": {"text": "[MINED126] Workflow container/services image `postgres:16` unpinned: `container/services image: postgres:16` without `@sha256:...` pulls a mutable tag at workflow-run time. Treat workflow container references with the same supply-chain disc"}, "fullDescription": {"text": "Replace with `postgres:16@sha256:<digest>`. Re-pin via Dependabot Docker scope."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "MINED130", "name": "[MINED130] Lockfile pulls package from off-canonical host `github.com`: `package-lock.json` resolved URL for `node_modul", "shortDescription": {"text": "[MINED130] Lockfile pulls package from off-canonical host `github.com`: `package-lock.json` resolved URL for `node_modules/op-blocknote-extensions` is `https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-block...` \u2014 h"}, "fullDescription": {"text": "Verify the host is intentional. If your org uses a private registry, add it to your scanner's allowlist (CANONICAL_NPM_HOSTS). Otherwise, regenerate the lockfile against the canonical registry."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "MINED118", "name": "[MINED118] Dockerfile FROM `node:22.18` not pinned by digest: `FROM node:22.18` resolves the tag at build time. The regi", "shortDescription": {"text": "[MINED118] Dockerfile FROM `node:22.18` not pinned by digest: `FROM node:22.18` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should p"}, "fullDescription": {"text": "Replace with: `FROM node:22.18@sha256:<digest>`. Get the digest from `docker manifest inspect`. Re-pin via a scheduled bot (Renovate, Dependabot)."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "MINED122", "name": "[MINED122] package.json dep `op-blocknote-extensions` pulled from URL/Git: `dependencies.op-blocknote-extensions` = `htt", "shortDescription": {"text": "[MINED122] package.json dep `op-blocknote-extensions` pulled from URL/Git: `dependencies.op-blocknote-extensions` = `https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz` bypasses the npm"}, "fullDescription": {"text": "Publish the dependency to npm (or your private registry) and reference it by `^x.y.z`. If that's not possible, lock by commit SHA: `git+https://...#<full-sha>` AND verify the SHA in CI."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "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: ANY /plugin/:id."}, "fullDescription": {"text": "Add ownership, tenant, relationship, or policy checks before reading or mutating the target object."}, "properties": {"scanner": "repobility-access-control", "category": "auth", "severity": "high", "confidence": 0.7, "cwe": "", "owasp": ""}}, {"id": "DKC013", "name": "Database service has no persistent data volume", "shortDescription": {"text": "Database service has no persistent data volume"}, "fullDescription": {"text": "Mount the database data directory to a named Docker volume or managed persistent disk, and document backup and restore testing."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "DKC011", "name": "Database service publishes a host port", "shortDescription": {"text": "Database service publishes a host port"}, "fullDescription": {"text": "Use `expose` for service-to-service access, bind to 127.0.0.1 for local-only access, or protect the port with firewall rules."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "high", "confidence": 0.84, "cwe": "", "owasp": ""}}, {"id": "DKC009", "name": "Compose service bind-mounts a sensitive host path", "shortDescription": {"text": "Compose service bind-mounts a sensitive host path"}, "fullDescription": {"text": "Mount only the exact file or directory required, prefer read-only mode, and avoid host system paths."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "MINED004", "name": "[MINED004] Weak Crypto: MD5/SHA1/DES/RC4 used for security context (not just checksums).", "shortDescription": {"text": "[MINED004] Weak Crypto: MD5/SHA1/DES/RC4 used for security context (not just checksums)."}, "fullDescription": {"text": "Review and fix per the pattern semantics. See CWE-327 / A02:2021 for context."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC103", "name": "[SEC103] LDAP injection \u2014 non-constant search filter: User input concatenated into an LDAP search filter. Attackers inje", "shortDescription": {"text": "[SEC103] LDAP injection \u2014 non-constant search filter: User input concatenated into an LDAP search filter. Attackers inject `*)(uid=*` style payloads to bypass auth or enumerate accounts."}, "fullDescription": {"text": "Escape with javax.naming.ldap.Rdn.escapeValue or equivalent. For python-ldap, use ldap.filter.escape_filter_chars. Better: use parameterized search APIs (Spring LdapTemplate filter encoders)."}, "properties": {"scanner": "repobility-threat-engine", "category": "injection", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC109", "name": "[SEC109] Rails skip_forgery_protection / protect_from_forgery disabled: Rails CSRF protection turned off at controller l", "shortDescription": {"text": "[SEC109] Rails skip_forgery_protection / protect_from_forgery disabled: Rails CSRF protection turned off at controller level. Any state-changing endpoint becomes a CSRF target."}, "fullDescription": {"text": "Remove the skip. For pure-API controllers, inherit from ActionController::API instead (which doesn't include forgery protection). For Bearer-auth APIs, use `protect_from_forgery with: :null_session` only on those specific controllers."}, "properties": {"scanner": "repobility-threat-engine", "category": "csrf", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC097", "name": "[SEC097] Rails: force_ssl disabled / protect_from_forgery missing: Rails app disables SSL or CSRF protection. Concept fr", "shortDescription": {"text": "[SEC097] Rails: force_ssl disabled / protect_from_forgery missing: Rails app disables SSL or CSRF protection. Concept from Brakeman check_force_ssl / check_forgery_setting \u2014 re-authored from OWASP A07."}, "fullDescription": {"text": "Set `config.force_ssl = true` in production.rb. Use `protect_from_forgery with: :exception`."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "MINED116", "name": "[MINED116] Workflow uses `secrets.HETZNER_CA_KEY` on a `pull_request` trigger: This workflow triggers on `pull_request`,", "shortDescription": {"text": "[MINED116] Workflow uses `secrets.HETZNER_CA_KEY` on a `pull_request` trigger: This workflow triggers on `pull_request`, which checks out the FORK's code. Referencing `${ secrets.HETZNER_CA_KEY }` lets a PR from any fork exfiltrate the secr"}, "fullDescription": {"text": "Either remove the secret reference, or switch the trigger to `pull_request_target` AND ensure no fork-controlled code runs before the secret is consumed."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "critical", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "DKC008", "name": "Compose service mounts the Docker socket", "shortDescription": {"text": "Compose service mounts the Docker socket"}, "fullDescription": {"text": "Avoid mounting docker.sock. Use a narrow proxy, rootless build service, or provider-native deployment credentials."}, "properties": {"scanner": "repobility-docker", "category": "docker", "severity": "critical", "confidence": 0.98, "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": "MINED018", "name": "[MINED018] Unsafe Deserialization Pickle: pickle.loads / yaml.load (without Loader=SafeLoader) / unmarshal of network/fi", "shortDescription": {"text": "[MINED018] Unsafe Deserialization Pickle: pickle.loads / yaml.load (without Loader=SafeLoader) / unmarshal of network/file data \u2014 RCE."}, "fullDescription": {"text": "Review and fix per the pattern semantics. See CWE-502 / A08:2021 for context."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "critical", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC116", "name": "[SEC116] Ruby YAML.load / Marshal.load on untrusted input: `YAML.load` (pre-3.1) and `Marshal.load` instantiate arbitrar", "shortDescription": {"text": "[SEC116] Ruby YAML.load / Marshal.load on untrusted input: `YAML.load` (pre-3.1) and `Marshal.load` instantiate arbitrary Ruby classes \u2014 direct RCE on untrusted input. `unsafe_load` is even more dangerous."}, "fullDescription": {"text": "Use `YAML.safe_load(input, permitted_classes: [Date])` \u2014 explicit class allowlist. Never use `Marshal.load` on untrusted data; serialize as JSON instead."}, "properties": {"scanner": "repobility-threat-engine", "category": "deserialization", "severity": "critical", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC079", "name": "[SEC079] Python: yaml.load without SafeLoader: yaml.load() without explicit SafeLoader can execute arbitrary Python obje", "shortDescription": {"text": "[SEC079] Python: yaml.load without SafeLoader: yaml.load() without explicit SafeLoader can execute arbitrary Python objects (CVE-2017-18342). Ported from bandit B506 / dlint DUO109 (Apache-2.0 / BSD-3)."}, "fullDescription": {"text": "Use `yaml.safe_load(data)` or `yaml.load(data, Loader=yaml.SafeLoader)`."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "critical", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC096", "name": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql: ActiveRecord where() / find_by_sql with interpolation ", "shortDescription": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql: ActiveRecord where() / find_by_sql with interpolation enables SQL injection. Concept from Brakeman check_sql \u2014 re-authored from OWASP CWE-89."}, "fullDescription": {"text": "Use parameterized form: `.where(\"name = ?\", user_input)` or named placeholders."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "critical", "confidence": 1.0, "cwe": "", "owasp": ""}}]}}, "automationDetails": {"id": "repobility/1020"}, "properties": {"repository": "opf/openproject", "repoUrl": "https://github.com/opf/openproject", "branch": "dev"}, "results": [{"ruleId": "WEB003", "level": "warning", "message": {"text": "Public web service has no security.txt"}, "properties": {"repobilityId": 95785, "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": "WEB015", "level": "warning", "message": {"text": "Public web app has no Content Security Policy"}, "properties": {"repobilityId": 95784, "scanner": "repobility-web-presence", "fingerprint": "7eb70cae3ff63d8ed7c31706185d32b37655333b40b58ca826d740b08fb1ad63", "category": "quality", "severity": "medium", "confidence": 0.7, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app but no CSP header, framework header config, Helmet policy, or CSP meta tag was discovered.", "evidence": {"rule_id": "WEB015", "scanner": "repobility-web-presence", "references": ["https://developer.mozilla.org/en-US/docs/Web/HTTP/CSP", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|7eb70cae3ff63d8ed7c31706185d32b37655333b40b58ca826d740b08fb1ad63"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "index.html"}, "region": {"startLine": 1}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95779, "scanner": "repobility-journey-contract", "fingerprint": "8c7bfee2106b26031b12d8cc8d426421b82cc00dfc8ad7251aed4d37713d1693", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/queries/group_bys/status", "correlation_key": "fp|8c7bfee2106b26031b12d8cc8d426421b82cc00dfc8ad7251aed4d37713d1693", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/shared/components/work-package-graphs/configuration/wp-graph-configuration.ts"}, "region": {"startLine": 36}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95778, "scanner": "repobility-journey-contract", "fingerprint": "55f8a92fa4715450420a533496c6a70576f2fb69c664cd90041b3352c686bd84", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/work_packages/{param}", "correlation_key": "fp|55f8a92fa4715450420a533496c6a70576f2fb69c664cd90041b3352c686bd84", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/features/work-packages/components/wp-table/configuration-modal/wp-table-configuration-relation-selector.ts"}, "region": {"startLine": 107}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95777, "scanner": "repobility-journey-contract", "fingerprint": "c5b430fc13f63ddfddd31358bf78e6f1194172172935388383d23bf31a709506", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/work_packages/new", "correlation_key": "fp|c5b430fc13f63ddfddd31358bf78e6f1194172172935388383d23bf31a709506", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/features/work-packages/components/wp-new/wp-create.service.ts"}, "region": {"startLine": 64}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95776, "scanner": "repobility-journey-contract", "fingerprint": "2ba84aa1398d106a013f30090afad6f2ec5f5bc4acd551aeaf4f04f908a4e714", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/queries/{param}", "correlation_key": "fp|2ba84aa1398d106a013f30090afad6f2ec5f5bc4acd551aeaf4f04f908a4e714", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/features/work-packages/components/wp-list/wp-list.service.ts"}, "region": {"startLine": 208}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95775, "scanner": "repobility-journey-contract", "fingerprint": "f7bce63877039ae6108fa2e1b34e7fd00a8f12d149c18737acc9620195da8554", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/users/{param}", "correlation_key": "fp|f7bce63877039ae6108fa2e1b34e7fd00a8f12d149c18737acc9620195da8554", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/features/work-packages/components/wp-edit-form/work-package-filter-values.ts"}, "region": {"startLine": 131}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95774, "scanner": "repobility-journey-contract", "fingerprint": "b3c2b5057f48f95a341cb816cc0e0b56022bf032b4ceb30a278afe84552cd570", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/users/me", "correlation_key": "fp|b3c2b5057f48f95a341cb816cc0e0b56022bf032b4ceb30a278afe84552cd570", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/features/work-packages/components/wp-edit-form/work-package-filter-values.ts"}, "region": {"startLine": 130}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95773, "scanner": "repobility-journey-contract", "fingerprint": "313196528fdc3ac37ac7046c790d6eddf1564d6bf7e4e51148afe313c0bb5da8", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/users/{param}", "correlation_key": "fp|313196528fdc3ac37ac7046c790d6eddf1564d6bf7e4e51148afe313c0bb5da8", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/core/current-user/current-user.service.ts"}, "region": {"startLine": 183}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95772, "scanner": "repobility-journey-contract", "fingerprint": "d8ac55defea3bbb0588977b55903d6b27ada4b0970e5022102fa46b85cdf1f11", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/actions/{param}", "correlation_key": "fp|d8ac55defea3bbb0588977b55903d6b27ada4b0970e5022102fa46b85cdf1f11", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/core/current-user/current-user.service.ts"}, "region": {"startLine": 126}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95771, "scanner": "repobility-journey-contract", "fingerprint": "40941333fd8e94f6430fedec5378771420b69ced5acb439cff3c6542533fbfa5", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/actions/{param}", "correlation_key": "fp|40941333fd8e94f6430fedec5378771420b69ced5acb439cff3c6542533fbfa5", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/core/current-user/current-user.service.ts"}, "region": {"startLine": 109}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95770, "scanner": "repobility-journey-contract", "fingerprint": "a5e4fa74e7900a717da8d1eef81713404b6680c003a1f92886a8dc81d69e40c9", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/work_packages/form", "correlation_key": "fp|a5e4fa74e7900a717da8d1eef81713404b6680c003a1f92886a8dc81d69e40c9", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/core/apiv3/endpoints/work_packages/apiv3-work-package-form.ts"}, "region": {"startLine": 21}}}]}, {"ruleId": "JRN003", "level": "warning", "message": {"text": "Frontend API reference is not matched by discovered backend routes"}, "properties": {"repobilityId": 95769, "scanner": "repobility-journey-contract", "fingerprint": "21897ce53801959335c89d725b4e370f181bebcc10d5cf224fd8b7c32e8cfc17", "category": "quality", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Same-origin /api path appears in frontend code but no discovered backend endpoint has the same route shape.", "evidence": {"rule_id": "JRN003", "scanner": "repobility-journey-contract", "references": ["https://repobility.com/library/authorization/"], "route_shape": "/api/v3/work_packages/form", "correlation_key": "fp|21897ce53801959335c89d725b4e370f181bebcc10d5cf224fd8b7c32e8cfc17", "backend_endpoint_count": 389}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/src/app/core/apiv3/endpoints/work_packages/apiv3-work-package-form.ts"}, "region": {"startLine": 8}}}]}, {"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: ANY /custom_style/:digest/export_logo/:filename."}, "properties": {"repobilityId": 95768, "scanner": "repobility-access-control", "fingerprint": "57ee13756aac103054807ccaaab6dc0372d65652d154d93d5077c822a290326f", "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": "/custom_style/:digest/export_logo/:filename", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|214|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 214}}}]}, {"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: ANY /custom_style/:digest/logo_mobile/:filename."}, "properties": {"repobilityId": 95767, "scanner": "repobility-access-control", "fingerprint": "6610bfbad498fcb154614fe7ba23fc56bd365fd271b7fe52834974f5484261d6", "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": "/custom_style/:digest/logo_mobile/:filename", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|210|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 210}}}]}, {"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: ANY /move/:id."}, "properties": {"repobilityId": 95766, "scanner": "repobility-access-control", "fingerprint": "8bfef0707a192501fe7e681015a2c981635ae1061d7b691a8f44a0417b08abc2", "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": "/move/:id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|200|auc009", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 200}}}]}, {"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: ANY /pdf_export_template."}, "properties": {"repobilityId": 95765, "scanner": "repobility-access-control", "fingerprint": "03a83e2e8ba214427491bff4b1e053b3576f22b4cd458f9308b2a05fabe2b26b", "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": "/pdf_export_template", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|185|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 185}}}]}, {"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: ANY /rows."}, "properties": {"repobilityId": 95764, "scanner": "repobility-access-control", "fingerprint": "0527a5c3d05d66757189d4caefca90c939fae1d39e78abd64e5dd7b6aa20ca58", "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": "/rows", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|170|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 170}}}]}, {"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: ANY /groups."}, "properties": {"repobilityId": 95763, "scanner": "repobility-access-control", "fingerprint": "3e23a716992e72ed2fdeea994f713b1bdac5d0af575070512048a785b2b8fce9", "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": "/groups", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|158|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 158}}}]}, {"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: ANY /types."}, "properties": {"repobilityId": 95762, "scanner": "repobility-access-control", "fingerprint": "dc3d4bdfdd55e6afb470f5f4ab2e65e81763c281c239fb187049553434e34f5e", "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": "/types", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|155|auc009", "identity_targets": ["authenticated"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 155}}}]}, {"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: ANY /roles/workflow/:id/:role_id/:type_id."}, "properties": {"repobilityId": 95761, "scanner": "repobility-access-control", "fingerprint": "f350cf60fb50197e401a653cba0ac3a587d29598413be1890580fd9207560198", "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": "/roles/workflow/:id/:role_id/:type_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|153|auc009", "identity_targets": ["authenticated", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 153}}}]}, {"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: ANY /resend_invite."}, "properties": {"repobilityId": 95760, "scanner": "repobility-access-control", "fingerprint": "873ec97f167f739a0f27b7f022c07e92177f733e240421e60f29a240e8379545", "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": "/resend_invite", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|99|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 99}}}]}, {"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: ANY /members."}, "properties": {"repobilityId": 95759, "scanner": "repobility-access-control", "fingerprint": "5eee913a749e56d3524ec6e1a6ea893ae127848feae71a477d0b3e8887c2e802", "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": "/members", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|97|auc009", "identity_targets": ["unknown"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 97}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /work_package_priorities."}, "properties": {"repobilityId": 95758, "scanner": "repobility-access-control", "fingerprint": "f097417daf53fe85f26244dab11bd30a47eed37fe17776850e3fafa68882d063", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/work_package_priorities", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|695|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 695}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /custom_actions."}, "properties": {"repobilityId": 95757, "scanner": "repobility-access-control", "fingerprint": "59049e8cdab8c9947c5e68897dfed4911169653fefd49069edb8d72597ccc69f", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/custom_actions", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|656|auc004", "identity_targets": ["authenticated", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 656}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /mcp_configurations."}, "properties": {"repobilityId": 95756, "scanner": "repobility-access-control", "fingerprint": "6175880f598096cfe633ca3383f24e0df7b3cbb9da9aa8be1a686ed3b639b5d5", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/mcp_configurations", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|650|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 650}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /ldap_auth_sources."}, "properties": {"repobilityId": 95755, "scanner": "repobility-access-control", "fingerprint": "cbc6bc03cb928fc9a559723d233660efdb7461131fcd3efa49a18b36df0dd0af", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/ldap_auth_sources", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|644|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 644}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /admin."}, "properties": {"repobilityId": 95754, "scanner": "repobility-access-control", "fingerprint": "f1dc20b8aaa213e98ae5ba3c2b6ad3c101c81907777e70a13188e9432009391d", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/admin", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|569|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 569}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /hover_card."}, "properties": {"repobilityId": 95753, "scanner": "repobility-access-control", "fingerprint": "d7f13514d504455e45ba210343cb9090d1f8a2f762831177119dca938a3c70b5", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/hover_card", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|565|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 565}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /project_phases."}, "properties": {"repobilityId": 95752, "scanner": "repobility-access-control", "fingerprint": "35c6b29685298b8c313321b95225d0444ad95c18f5b73953b5aa48bb6efd04da", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/project_phases", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|563|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 563}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /settings."}, "properties": {"repobilityId": 95751, "scanner": "repobility-access-control", "fingerprint": "32e427395c375b107093c52540f1b93c0f9540d1a9515dc6591d5a700bb7ffb1", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/settings", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|392|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 392}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /items."}, "properties": {"repobilityId": 95750, "scanner": "repobility-access-control", "fingerprint": "31f8e2f2fa7077c48c94a2718b8ab5f8e3b0ff26a7823a69f538aa39c4e8a620", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/items", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|253|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 253}}}]}, {"ruleId": "AUC004", "level": "warning", "message": {"text": "[AUC004] Admin route does not show super_admin separation: An administrative route was detected without nearby evidence that platform super_admin access is separated from tenant/application admin access. Endpoint: ANY /projects."}, "properties": {"repobilityId": 95749, "scanner": "repobility-access-control", "fingerprint": "8e3cb40270918e131e7ce9b0029c44add15d060405ff42ac8c5461573b23c500", "category": "auth", "severity": "medium", "confidence": 0.66, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"path": "/projects", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|251|auc004", "identity_targets": ["unknown", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 251}}}]}, {"ruleId": "AUC002", "level": "warning", "message": {"text": "[AUC002] Low visible authorization coverage in route inventory: Only 15.7% of discovered routes show nearby authentication, authorization, middleware, or public-route evidence."}, "properties": {"repobilityId": 95738, "scanner": "repobility-access-control", "fingerprint": "6ef15e9d9bd88305bdc487b675ce489e873f3d0604ae695d56c17a5c140bdb8d", "category": "auth", "severity": "medium", "confidence": 0.74, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Static route and framework evidence require project-owner confirmation.", "evidence": {"scanner": "repobility-access-control", "endpoint_count": 389, "correlation_key": "fp|6ef15e9d9bd88305bdc487b675ce489e873f3d0604ae695d56c17a5c140bdb8d", "auth_visible_percent": 15.7}}}, {"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": 95737, "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": ["Rails"], "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 `cuprite-chrome` image uses the latest tag"}, "properties": {"repobilityId": 95736, "scanner": "repobility-docker", "fingerprint": "dcf08b4e534e665dd7ba78aec5940ae880aac4ec6fd095b68e43f72927af8575", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "ghcr.io/browserless/chrome: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|dcf08b4e534e665dd7ba78aec5940ae880aac4ec6fd095b68e43f72927af8575"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 240}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `hocuspocus-test` image uses the latest tag"}, "properties": {"repobilityId": 95730, "scanner": "repobility-docker", "fingerprint": "31cc7484cac96d1705d139b85d37587d0c21a571ce59adee60ec6e9a03ebf676", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "openproject/hocuspocus: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|31cc7484cac96d1705d139b85d37587d0c21a571ce59adee60ec6e9a03ebf676"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 125}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 95729, "scanner": "repobility-docker", "fingerprint": "47d4b7c2c13791818f340edf7373a1fc522ec685165577594e446a1ae5f66d99", "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-test", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|47d4b7c2c13791818f340edf7373a1fc522ec685165577594e446a1ae5f66d99"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 113}}}]}, {"ruleId": "DKR002", "level": "warning", "message": {"text": "Compose service `cache` image has no explicit tag"}, "properties": {"repobilityId": 95727, "scanner": "repobility-docker", "fingerprint": "920f55422ee00effdef0f1f795ae855e4205a1caa601c1d7503e05dc258321a5", "category": "docker", "severity": "medium", "confidence": 0.9, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image reference has no tag or digest.", "evidence": {"image": "memcached", "rule_id": "DKR002", "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|920f55422ee00effdef0f1f795ae855e4205a1caa601c1d7503e05dc258321a5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 105}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 95725, "scanner": "repobility-docker", "fingerprint": "1bd3d02a20fe17334f314e7c78e179fd9fb225fa0dbd1427aa86f569c6a5d43d", "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|1bd3d02a20fe17334f314e7c78e179fd9fb225fa0dbd1427aa86f569c6a5d43d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 92}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `worker` image uses the latest tag"}, "properties": {"repobilityId": 95720, "scanner": "repobility-docker", "fingerprint": "7f66074426669f06d6eac83f5782f04f9c42a1e75c388d2a852c51fff752e421", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "openproject/dev: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|7f66074426669f06d6eac83f5782f04f9c42a1e75c388d2a852c51fff752e421"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 71}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `backend` image uses the latest tag"}, "properties": {"repobilityId": 95716, "scanner": "repobility-docker", "fingerprint": "44aff0b79c8c94402109f0b6734cb720bac9280c436efbf02c3afee060d359af", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "openproject/dev: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|44aff0b79c8c94402109f0b6734cb720bac9280c436efbf02c3afee060d359af"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 61}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `hocuspocus` image uses the latest tag"}, "properties": {"repobilityId": 95713, "scanner": "repobility-docker", "fingerprint": "cb7013696fe2161bc2aa3c6d330c5e8c3c1c0c787bea3962fc1b64367b0201a2", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "openproject/hocuspocus: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|cb7013696fe2161bc2aa3c6d330c5e8c3c1c0c787bea3962fc1b64367b0201a2"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 79}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 95704, "scanner": "repobility-docker", "fingerprint": "5a2dbdd9e2c4b4093ffb517c887a3857a46536fd5705f5437c82f183a2e948ed", "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|5a2dbdd9e2c4b4093ffb517c887a3857a46536fd5705f5437c82f183a2e948ed"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 51}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 95701, "scanner": "repobility-docker", "fingerprint": "27e042d6e6b09a67ed376380c06852e24587368bb824a9064b9dbc56972d0471", "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|27e042d6e6b09a67ed376380c06852e24587368bb824a9064b9dbc56972d0471"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/xwiki/docker-compose.yml"}, "region": {"startLine": 18}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 95699, "scanner": "repobility-docker", "fingerprint": "8eb99c841812408b5f7d214535fed209bd2eee0eacf740a19e8f360e6407bf45", "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": "web", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|8eb99c841812408b5f7d214535fed209bd2eee0eacf740a19e8f360e6407bf45"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/xwiki/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC007", "level": "warning", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95697, "scanner": "repobility-docker", "fingerprint": "a61a724de6a48e80d95120bc465b7c3e9f8587cd42ac635eb24c74bde3fb1099", "category": "docker", "severity": "medium", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Environment variable name is secret-like and value is a committed literal, but this Compose file is under a test/example/local path and needs human confirmation before treating it as production exposure.", "evidence": {"rule_id": "DKC007", "scanner": "repobility-docker", "service": "step", "variable": "DOCKER_STEPCA_INIT_PASSWORD", "references": ["https://docs.docker.com/compose/how-tos/environment-variables/best-practices/", "https://docs.docker.com/reference/compose-file/secrets/"], "path_context": "reference_or_local", "correlation_key": "fp|a61a724de6a48e80d95120bc465b7c3e9f8587cd42ac635eb24c74bde3fb1099", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/tls/docker-compose.yml"}, "region": {"startLine": 59}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `step` image uses the latest tag"}, "properties": {"repobilityId": 95696, "scanner": "repobility-docker", "fingerprint": "fcde874a39e28330e25d472a2ec516399e98646e8e7a8fbcb2525b308535768a", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "smallstep/step-ca: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|fcde874a39e28330e25d472a2ec516399e98646e8e7a8fbcb2525b308535768a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/tls/docker-compose.yml"}, "region": {"startLine": 59}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `traefik` image uses the latest tag"}, "properties": {"repobilityId": 95694, "scanner": "repobility-docker", "fingerprint": "7da28475b112531ce331783bac4c29e4c1918341dc50bf6bf093e57c83243615", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "traefik: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|7da28475b112531ce331783bac4c29e4c1918341dc50bf6bf093e57c83243615"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/tls/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC007", "level": "warning", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95692, "scanner": "repobility-docker", "fingerprint": "ce830e0e45998ff0ef15d960c9cfd49dfe64988ceaa3b7b8ce819295c80dfd12", "category": "docker", "severity": "medium", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Environment variable name is secret-like and value is a committed literal, but this Compose file is under a test/example/local path and needs human confirmation before treating it as production exposure.", "evidence": {"rule_id": "DKC007", "scanner": "repobility-docker", "service": "minio", "variable": "MINIO_ROOT_PASSWORD", "references": ["https://docs.docker.com/compose/how-tos/environment-variables/best-practices/", "https://docs.docker.com/reference/compose-file/secrets/"], "path_context": "reference_or_local", "correlation_key": "fp|ce830e0e45998ff0ef15d960c9cfd49dfe64988ceaa3b7b8ce819295c80dfd12", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/minio/docker-compose.yml"}, "region": {"startLine": 2}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `minio` image uses the latest tag"}, "properties": {"repobilityId": 95691, "scanner": "repobility-docker", "fingerprint": "8fa6b36ad84ef197db8a65d75517fdc15fce64587390ef402eb7a6338785cf20", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "minio/minio: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|8fa6b36ad84ef197db8a65d75517fdc15fce64587390ef402eb7a6338785cf20"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/minio/docker-compose.yml"}, "region": {"startLine": 2}}}]}, {"ruleId": "DKC007", "level": "warning", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95689, "scanner": "repobility-docker", "fingerprint": "57356c3a009720d1e84993f046b635437ea5bd10614a15b65f263304515d17ea", "category": "docker", "severity": "medium", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Environment variable name is secret-like and value is a committed literal, but this Compose file is under a test/example/local path and needs human confirmation before treating it as production exposure.", "evidence": {"rule_id": "DKC007", "scanner": "repobility-docker", "service": "keycloak", "variable": "KC_DB_PASSWORD", "references": ["https://docs.docker.com/compose/how-tos/environment-variables/best-practices/", "https://docs.docker.com/reference/compose-file/secrets/"], "path_context": "reference_or_local", "correlation_key": "fp|57356c3a009720d1e84993f046b635437ea5bd10614a15b65f263304515d17ea", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/keycloak/docker-compose.yml"}, "region": {"startLine": 13}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 95688, "scanner": "repobility-docker", "fingerprint": "d0de1b66640af04b021c2f739c4cf031e4591c199361bdc16e6f93f132b7c352", "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-keycloak", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|d0de1b66640af04b021c2f739c4cf031e4591c199361bdc16e6f93f132b7c352"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/keycloak/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC007", "level": "warning", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95687, "scanner": "repobility-docker", "fingerprint": "6bc432fe851b1db9317d39a6abd87cfc5d06b7c95cff6bbecd9fec19f61945fc", "category": "docker", "severity": "medium", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Environment variable name is secret-like and value is a committed literal, but this Compose file is under a test/example/local path and needs human confirmation before treating it as production exposure.", "evidence": {"rule_id": "DKC007", "scanner": "repobility-docker", "service": "db-keycloak", "variable": "POSTGRES_PASSWORD", "references": ["https://docs.docker.com/compose/how-tos/environment-variables/best-practices/", "https://docs.docker.com/reference/compose-file/secrets/"], "path_context": "reference_or_local", "correlation_key": "fp|6bc432fe851b1db9317d39a6abd87cfc5d06b7c95cff6bbecd9fec19f61945fc", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/keycloak/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC015", "level": "warning", "message": {"text": "Database service has no healthcheck"}, "properties": {"repobilityId": 95686, "scanner": "repobility-docker", "fingerprint": "b5883c840ac782311dac2d539dd1ec2fe7041090d07f848ddda4951dbfefa631", "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-jira", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|b5883c840ac782311dac2d539dd1ec2fe7041090d07f848ddda4951dbfefa631"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/jira-software/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC007", "level": "warning", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95685, "scanner": "repobility-docker", "fingerprint": "9f10e94cb78f32e3310ca38c541c0a4b1434d315cb61ef49b4b178f2a04a44ed", "category": "docker", "severity": "medium", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Environment variable name is secret-like and value is a committed literal, but this Compose file is under a test/example/local path and needs human confirmation before treating it as production exposure.", "evidence": {"rule_id": "DKC007", "scanner": "repobility-docker", "service": "db-jira", "variable": "POSTGRES_PASSWORD", "references": ["https://docs.docker.com/compose/how-tos/environment-variables/best-practices/", "https://docs.docker.com/reference/compose-file/secrets/"], "path_context": "reference_or_local", "correlation_key": "fp|9f10e94cb78f32e3310ca38c541c0a4b1434d315cb61ef49b4b178f2a04a44ed", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/jira-software/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC007", "level": "warning", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95684, "scanner": "repobility-docker", "fingerprint": "3ca7a4d44a45c2db5dbc91c7f0a0b9ab0ae688ae315b4c2bdf9dce953d9d4d64", "category": "docker", "severity": "medium", "confidence": 0.56, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Environment variable name is secret-like and value is a committed literal, but this Compose file is under a test/example/local path and needs human confirmation before treating it as production exposure.", "evidence": {"rule_id": "DKC007", "scanner": "repobility-docker", "service": "hocuspocus", "variable": "SECRET", "references": ["https://docs.docker.com/compose/how-tos/environment-variables/best-practices/", "https://docs.docker.com/reference/compose-file/secrets/"], "path_context": "reference_or_local", "correlation_key": "fp|3ca7a4d44a45c2db5dbc91c7f0a0b9ab0ae688ae315b4c2bdf9dce953d9d4d64", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/hocuspocus/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR003", "level": "warning", "message": {"text": "Compose service `gitlab` image uses the latest tag"}, "properties": {"repobilityId": 95682, "scanner": "repobility-docker", "fingerprint": "be89aba72ef69e06d6bc165d29fde33507da207d99d5d8e4dfaf174d6e7c259e", "category": "docker", "severity": "medium", "confidence": 0.94, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Image tag is latest.", "evidence": {"image": "gitlab/gitlab-ce: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|be89aba72ef69e06d6bc165d29fde33507da207d99d5d8e4dfaf174d6e7c259e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/gitlab/docker-compose.yml"}, "region": {"startLine": 3}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 95681, "scanner": "repobility-docker", "fingerprint": "2d47614b9dafb3686b905aaa69ce69ea8d64f362b252dabfa0bfc98c531014fa", "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.18", "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|2d47614b9dafb3686b905aaa69ce69ea8d64f362b252dabfa0bfc98c531014fa"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "extensions/op-blocknote-hocuspocus/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 95680, "scanner": "repobility-docker", "fingerprint": "b5bf97a1a1c7f959fa86697a58270344b2c6ddaf6999436875b9149ab2cb0068", "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": "ruby:2.6-stretch", "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|b5bf97a1a1c7f959fa86697a58270344b2c6ddaf6999436875b9149ab2cb0068"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/prod/mysql-to-postgres/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR001", "level": "warning", "message": {"text": "Docker final stage has no non-root USER"}, "properties": {"repobilityId": 95678, "scanner": "repobility-docker", "fingerprint": "5cc74b4550954ef12873904ccec8ad92f0e16d68462d3ac89ea6a1aeb6522b13", "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": "app-runtime", "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|5cc74b4550954ef12873904ccec8ad92f0e16d68462d3ac89ea6a1aeb6522b13"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/prod/Dockerfile"}, "region": {"startLine": 135}}}]}, {"ruleId": "DKR014", "level": "warning", "message": {"text": "Dockerfile copies broad context with incomplete .dockerignore"}, "properties": {"repobilityId": 95677, "scanner": "repobility-docker", "fingerprint": "05663493dfdb7797e31e5bf3ba8005e014caa2228c309f73210bed0a05b05cc6", "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|05663493dfdb7797e31e5bf3ba8005e014caa2228c309f73210bed0a05b05cc6", "missing_patterns": [".env", "id_rsa", "*.pem", "*.key"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/prod/Dockerfile"}, "region": {"startLine": 83}}}]}, {"ruleId": "DKR009", "level": "warning", "message": {"text": "Dockerfile separates apt update from install"}, "properties": {"repobilityId": 95667, "scanner": "repobility-docker", "fingerprint": "2e3b97ea44a70617a543d57dba05e0986dcfde44905e21206b9d06e867560bec", "category": "docker", "severity": "medium", "confidence": 0.86, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Package index update appears without package installation in the same layer.", "evidence": {"rule_id": "DKR009", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|2e3b97ea44a70617a543d57dba05e0986dcfde44905e21206b9d06e867560bec"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/backend/Dockerfile"}, "region": {"startLine": 37}}}]}, {"ruleId": "AIC004", "level": "warning", "message": {"text": "Suspicious implementation file appears unreferenced"}, "properties": {"repobilityId": 95649, "scanner": "repobility-ai-code-hygiene", "fingerprint": "191f1cb954d891857014cae4426bdb726bc059e6296e7c22213d2809c9a7470a", "category": "quality", "severity": "medium", "confidence": 0.78, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Patch-style source file has no detected inbound reference from other repository files.", "evidence": {"suffix": "update", "rule_id": "AIC004", "scanner": "repobility-ai-code-hygiene", "references": ["https://knip.dev/", "https://github.com/jendrikseipp/vulture"], "correlation_key": "fp|191f1cb954d891857014cae4426bdb726bc059e6296e7c22213d2809c9a7470a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/journal/caused_by_system_update.rb"}, "region": {"startLine": 1}}}]}, {"ruleId": "SEC007", "level": "warning", "message": {"text": "[SEC007] Unsafe Deserialization: Unsafe deserialization can execute arbitrary code."}, "properties": {"repobilityId": 95642, "scanner": "repobility-threat-engine", "fingerprint": "b8dccdba6db3f0d25ee591113987242d148ca80f7562f9ca60d2bc6d0366393f", "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|token|42|sec007"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/queries/work_packages/filter_serializer.rb"}, "region": {"startLine": 42}}}]}, {"ruleId": "SEC134", "level": "warning", "message": {"text": "[SEC134] AI scaffold leftover \u2014 Lorem ipsum / example.com / John Doe in code: Lorem ipsum / John Doe / example.com left in non-test code. AI agents emit these as 'reasonable defaults' when they don't know real values; the human then forgets to swap them. In production, these break demo flows, send mail to a real example.com host (it's owned by IANA), and leak that the codebase had an AI scaffolding pass."}, "properties": {"repobilityId": 95641, "scanner": "repobility-threat-engine", "fingerprint": "6e58651a9a43b3f4090f26f952b5763abb324cd1ab19ef5839e0492e56b41844", "category": "quality", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "\"Lorem ipsum dolor sit amet", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC134", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|6e58651a9a43b3f4090f26f952b5763abb324cd1ab19ef5839e0492e56b41844"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/exports/pdf/demo_generator.rb"}, "region": {"startLine": 134}}}]}, {"ruleId": "SEC015", "level": "warning", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 95624, "scanner": "repobility-threat-engine", "fingerprint": "05dcf7141749f4c27956ce6bcc4027c9b49cdf869b8c5f7340a87c97be72ec34", "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_backup_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|token|63|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/helpers/backup_helper.rb"}, "region": {"startLine": 63}}}]}, {"ruleId": "SEC015", "level": "warning", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 95623, "scanner": "repobility-threat-engine", "fingerprint": "fb80293b8001f687d38d3e09560e6637c08dcfabd16921ff5f49344fc63970d8", "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 generate_rss_key", "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|token|75|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/my/access_tokens_controller.rb"}, "region": {"startLine": 75}}}]}, {"ruleId": "SEC015", "level": "warning", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 95622, "scanner": "repobility-threat-engine", "fingerprint": "4092d4418fef8d9bcd2e51945cc59042be0fc882269f28eca7eba85530b7aa86", "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 new_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|token|47|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/my/access_token/new_access_token_dialog_component.rb"}, "region": {"startLine": 47}}}]}, {"ruleId": "WEB011", "level": "note", "message": {"text": "Public web app has no humans.txt"}, "properties": {"repobilityId": 95783, "scanner": "repobility-web-presence", "fingerprint": "bdd551fbe1ab6405480e0d5755632562c2096cb9e9a6a071ef60e4c27a6873f1", "category": "quality", "severity": "low", "confidence": 0.5, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Repository looks like a public web app but no humans.txt file or route was discovered.", "evidence": {"rule_id": "WEB011", "scanner": "repobility-web-presence", "references": ["https://github.com/Lissy93/web-check"], "correlation_key": "fp|bdd551fbe1ab6405480e0d5755632562c2096cb9e9a6a071ef60e4c27a6873f1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "humans.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "WEB008", "level": "note", "message": {"text": "Public docs site has no llms.txt"}, "properties": {"repobilityId": 95782, "scanner": "repobility-web-presence", "fingerprint": "cdce8ed8706710d39c3e7272dad572dd639cff74fd3d2ac62d8f6f522b891d76", "category": "quality", "severity": "low", "confidence": 0.64, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Repository looks public and documentation-heavy but no llms.txt file or route was discovered.", "evidence": {"rule_id": "WEB008", "scanner": "repobility-web-presence", "references": ["https://llmstxt.org/"], "correlation_key": "fp|cdce8ed8706710d39c3e7272dad572dd639cff74fd3d2ac62d8f6f522b891d76"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "llms.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "WEB002", "level": "note", "message": {"text": "Public web app has no sitemap"}, "properties": {"repobilityId": 95781, "scanner": "repobility-web-presence", "fingerprint": "fccbe72d13ca3ba9197ec37b0daa0802fb6d5ebff54b3eb9f09b59b0f8d0acdf", "category": "quality", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app but no sitemap file or route was discovered.", "evidence": {"rule_id": "WEB002", "scanner": "repobility-web-presence", "references": ["https://www.sitemaps.org/protocol.html", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|fccbe72d13ca3ba9197ec37b0daa0802fb6d5ebff54b3eb9f09b59b0f8d0acdf"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "sitemap.xml"}, "region": {"startLine": 1}}}]}, {"ruleId": "WEB001", "level": "note", "message": {"text": "Public web app has no robots.txt"}, "properties": {"repobilityId": 95780, "scanner": "repobility-web-presence", "fingerprint": "cae3f2223945958e14d8eb90f7965fa26b47011cc5be29c2855a4054937e29c4", "category": "quality", "severity": "low", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository looks like a public web app but no robots.txt file or route was discovered.", "evidence": {"rule_id": "WEB001", "scanner": "repobility-web-presence", "references": ["https://www.rfc-editor.org/rfc/rfc9309", "https://github.com/Lissy93/web-check"], "correlation_key": "fp|cae3f2223945958e14d8eb90f7965fa26b47011cc5be29c2855a4054937e29c4"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "robots.txt"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 95735, "scanner": "repobility-docker", "fingerprint": "58e79cb8005537d02b608d4ff4f7a46b6e7c339eab0d0c2a4276692b3a5606fb", "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": "backend-test", "dependency": "db-test", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|58e79cb8005537d02b608d4ff4f7a46b6e7c339eab0d0c2a4276692b3a5606fb", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 149}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 95734, "scanner": "repobility-docker", "fingerprint": "2ee0b46f6ee8dd6795738001cd8fe22fedefd1a9c7e921583dfc2020fa9c47a4", "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": "backend-test", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|2ee0b46f6ee8dd6795738001cd8fe22fedefd1a9c7e921583dfc2020fa9c47a4"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 149}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 95733, "scanner": "repobility-docker", "fingerprint": "1d7da0b616c1fed759052dc10585a5172148bc0f5919e2386286f19cad31d6eb", "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": "backend-test", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|1d7da0b616c1fed759052dc10585a5172148bc0f5919e2386286f19cad31d6eb"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 149}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 95732, "scanner": "repobility-docker", "fingerprint": "b540de5c5b9fea3c4d9b52ad2275714cbc0d4d060e476a796bcd286181e63c30", "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": "frontend-test", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|b540de5c5b9fea3c4d9b52ad2275714cbc0d4d060e476a796bcd286181e63c30"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 132}}}]}, {"ruleId": "DKC017", "level": "note", "message": {"text": "Database password is wired through an environment variable placeholder"}, "properties": {"repobilityId": 95726, "scanner": "repobility-docker", "fingerprint": "09374a5cb5d7744a8839dcc37aa40b5f1062360eb3fea9ccf14f9cebe422a644", "category": "docker", "severity": "low", "confidence": 0.58, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Database image supports file-based secret variables, but only placeholder environment variables were found.", "evidence": {"rule_id": "DKC017", "scanner": "repobility-docker", "service": "db", "variables": ["POSTGRES_PASSWORD"], "references": ["https://docs.docker.com/compose/how-tos/use-secrets/"], "correlation_key": "fp|09374a5cb5d7744a8839dcc37aa40b5f1062360eb3fea9ccf14f9cebe422a644"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 92}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 95724, "scanner": "repobility-docker", "fingerprint": "d1c954fe7c37ea960dd15de8dea28162ca17047eed9342b634b790774fc21a4a", "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": "frontend", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|d1c954fe7c37ea960dd15de8dea28162ca17047eed9342b634b790774fc21a4a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 78}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 95723, "scanner": "repobility-docker", "fingerprint": "9cae73f0ba4c11e2f378a63175cdd2fe27c12c19f09787c21614e0e29b0e2152", "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|9cae73f0ba4c11e2f378a63175cdd2fe27c12c19f09787c21614e0e29b0e2152", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 71}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 95722, "scanner": "repobility-docker", "fingerprint": "568e18a74e6d52590d1dc360c4db87c6483f0810621a6b3bab1858a255774e44", "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|568e18a74e6d52590d1dc360c4db87c6483f0810621a6b3bab1858a255774e44"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 71}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 95721, "scanner": "repobility-docker", "fingerprint": "4305973f0bb57e01da8e487f7d7c62d31b1baf059dd2f87f953c16337b2c60aa", "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|4305973f0bb57e01da8e487f7d7c62d31b1baf059dd2f87f953c16337b2c60aa"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 71}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 95719, "scanner": "repobility-docker", "fingerprint": "5e11b9cb191675afcda0320f406876e840cff3fc4215e117eaaccef1c0f7d682", "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": "backend", "dependency": "db", "references": ["https://docs.docker.com/compose/how-tos/startup-order/"], "correlation_key": "fp|5e11b9cb191675afcda0320f406876e840cff3fc4215e117eaaccef1c0f7d682", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 61}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 95718, "scanner": "repobility-docker", "fingerprint": "b3c52ef59c582752df9a3aab8c4a40dc85be4f706006cd35d0521116c37bb0fd", "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": "backend", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|b3c52ef59c582752df9a3aab8c4a40dc85be4f706006cd35d0521116c37bb0fd"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 61}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 95717, "scanner": "repobility-docker", "fingerprint": "b54737db80aa3f3afacb5389a1f2112af51d4877e6a14b8d1fb9e91d90da009e", "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": "backend", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|b54737db80aa3f3afacb5389a1f2112af51d4877e6a14b8d1fb9e91d90da009e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 61}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 95715, "scanner": "repobility-docker", "fingerprint": "23ebb8800e3ebd89c0ebfac3b6c442b5f1f00cae127edd7d690b3ea3b9382dd0", "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": "hocuspocus", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|23ebb8800e3ebd89c0ebfac3b6c442b5f1f00cae127edd7d690b3ea3b9382dd0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 79}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 95712, "scanner": "repobility-docker", "fingerprint": "46936ec16b342e3ab081515ba71378ca4be39073e85e8cbbc792a9e94cc5918c", "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|46936ec16b342e3ab081515ba71378ca4be39073e85e8cbbc792a9e94cc5918c", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 73}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 95711, "scanner": "repobility-docker", "fingerprint": "30f27adb995074632b41d4648b2970c2ed63421de0e1e17a89c5bf765b5f156e", "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|30f27adb995074632b41d4648b2970c2ed63421de0e1e17a89c5bf765b5f156e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 73}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 95709, "scanner": "repobility-docker", "fingerprint": "e4eb0536932c173639ed9ddd8ecdf8357f53836cba2d4452e3b6ed9602f09afa", "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|e4eb0536932c173639ed9ddd8ecdf8357f53836cba2d4452e3b6ed9602f09afa"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 73}}}]}, {"ruleId": "DKC016", "level": "note", "message": {"text": "App service does not wait for database health"}, "properties": {"repobilityId": 95708, "scanner": "repobility-docker", "fingerprint": "952208db2cef8e6575a1cb06d7516718d97ae7047c94aa0790140208fe8e0ecd", "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|952208db2cef8e6575a1cb06d7516718d97ae7047c94aa0790140208fe8e0ecd", "dependency_has_healthcheck": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 64}}}]}, {"ruleId": "DKC010", "level": "note", "message": {"text": "Compose service lacks no-new-privileges hardening"}, "properties": {"repobilityId": 95707, "scanner": "repobility-docker", "fingerprint": "7cbe36c4f8d9bb9164e10d2b7ece030c8f9b4c027fba2399ac8f41c28577f184", "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|7cbe36c4f8d9bb9164e10d2b7ece030c8f9b4c027fba2399ac8f41c28577f184"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 64}}}]}, {"ruleId": "DKC006", "level": "note", "message": {"text": "Compose service does not declare a runtime user"}, "properties": {"repobilityId": 95705, "scanner": "repobility-docker", "fingerprint": "7bb1d5afe711dddbce54285751f6822222093a761301d3b5aa180c2d0eebfb2c", "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|7bb1d5afe711dddbce54285751f6822222093a761301d3b5aa180c2d0eebfb2c"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 64}}}]}, {"ruleId": "DKC017", "level": "note", "message": {"text": "Database password is wired through an environment variable placeholder"}, "properties": {"repobilityId": 95702, "scanner": "repobility-docker", "fingerprint": "a412273761a7815f41ab7dc58e57b2a25f9963e96ffac017a61b8b1dae455979", "category": "docker", "severity": "low", "confidence": 0.58, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Database image supports file-based secret variables, but only placeholder environment variables were found.", "evidence": {"rule_id": "DKC017", "scanner": "repobility-docker", "service": "db", "variables": ["POSTGRES_ROOT_PASSWORD", "POSTGRES_PASSWORD"], "references": ["https://docs.docker.com/compose/how-tos/use-secrets/"], "correlation_key": "fp|a412273761a7815f41ab7dc58e57b2a25f9963e96ffac017a61b8b1dae455979"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/xwiki/docker-compose.yml"}, "region": {"startLine": 18}}}]}, {"ruleId": "DKC017", "level": "note", "message": {"text": "Database password is wired through an environment variable placeholder"}, "properties": {"repobilityId": 95700, "scanner": "repobility-docker", "fingerprint": "7310f1b3085289ba4d2b7a2463e7966377668f88be12f8395c63d7270fc1a7e6", "category": "docker", "severity": "low", "confidence": 0.58, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Database image supports file-based secret variables, but only placeholder environment variables were found.", "evidence": {"rule_id": "DKC017", "scanner": "repobility-docker", "service": "web", "variables": ["DB_PASSWORD"], "references": ["https://docs.docker.com/compose/how-tos/use-secrets/"], "correlation_key": "fp|7310f1b3085289ba4d2b7a2463e7966377668f88be12f8395c63d7270fc1a7e6"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/xwiki/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 95679, "scanner": "repobility-docker", "fingerprint": "8335cdcaccd023f47f800fa9bd64866f9242d1a3382f407f7ed8f7c9a64b63c6", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|8335cdcaccd023f47f800fa9bd64866f9242d1a3382f407f7ed8f7c9a64b63c6"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/prod/mysql-to-postgres/Dockerfile"}, "region": {"startLine": 10}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 95674, "scanner": "repobility-docker", "fingerprint": "02dcc2a507e0867ecaacae3c6752a85af92244f4b6a867df29583741262765c7", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|02dcc2a507e0867ecaacae3c6752a85af92244f4b6a867df29583741262765c7"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/frontend/Dockerfile"}, "region": {"startLine": 9}}}]}, {"ruleId": "DKR010", "level": "note", "message": {"text": "Dockerfile leaves apt package indexes in the image layer"}, "properties": {"repobilityId": 95673, "scanner": "repobility-docker", "fingerprint": "8d200e9892937e6ce17f224e0ef687a8a97b2f40eed6ba3c91f46586efc86459", "category": "docker", "severity": "low", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt update/install layer does not remove /var/lib/apt/lists.", "evidence": {"rule_id": "DKR010", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|8d200e9892937e6ce17f224e0ef687a8a97b2f40eed6ba3c91f46586efc86459"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/frontend/Dockerfile"}, "region": {"startLine": 9}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 95671, "scanner": "repobility-docker", "fingerprint": "912662d78046e267affbe871143b87fe8e9ea1089f3fd65516f8592ed7394092", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|912662d78046e267affbe871143b87fe8e9ea1089f3fd65516f8592ed7394092"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/backend/Dockerfile"}, "region": {"startLine": 69}}}]}, {"ruleId": "DKR010", "level": "note", "message": {"text": "Dockerfile leaves apt package indexes in the image layer"}, "properties": {"repobilityId": 95670, "scanner": "repobility-docker", "fingerprint": "4bd22c8c2491c09e619138bbe25413fe998d5d62aa9621900b0fc18f2b497030", "category": "docker", "severity": "low", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt update/install layer does not remove /var/lib/apt/lists.", "evidence": {"rule_id": "DKR010", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|4bd22c8c2491c09e619138bbe25413fe998d5d62aa9621900b0fc18f2b497030"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/backend/Dockerfile"}, "region": {"startLine": 69}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 95669, "scanner": "repobility-docker", "fingerprint": "c8f74573253a19bc156e56396fd13769c3fac23248c6904cea9009f5a97e8f30", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|c8f74573253a19bc156e56396fd13769c3fac23248c6904cea9009f5a97e8f30"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/backend/Dockerfile"}, "region": {"startLine": 41}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 95668, "scanner": "repobility-docker", "fingerprint": "1bdf520a0cd12ad60275bb948097dd33e87d8e07de35e5224348a56741d06676", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|1bdf520a0cd12ad60275bb948097dd33e87d8e07de35e5224348a56741d06676"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/backend/Dockerfile"}, "region": {"startLine": 38}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 95666, "scanner": "repobility-docker", "fingerprint": "42a9ca1207645f5b9f027699b60103f6aa1f1fd2e068a3b474ee74fd38eec987", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|42a9ca1207645f5b9f027699b60103f6aa1f1fd2e068a3b474ee74fd38eec987"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/backend/Dockerfile"}, "region": {"startLine": 23}}}]}, {"ruleId": "DKR008", "level": "note", "message": {"text": ".dockerignore misses sensitive defaults"}, "properties": {"repobilityId": 95665, "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": [".env", "id_rsa", "*.pem", "*.key"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".dockerignore"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 95664, "scanner": "repobility-docker", "fingerprint": "708a8448987e4bd60fe4f0c453c8901a19ec5718e48fed7e84191a7a56dda32a", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|708a8448987e4bd60fe4f0c453c8901a19ec5718e48fed7e84191a7a56dda32a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/ci/Dockerfile"}, "region": {"startLine": 15}}}]}, {"ruleId": "DKR011", "level": "note", "message": {"text": "Dockerfile installs recommended OS packages"}, "properties": {"repobilityId": 95663, "scanner": "repobility-docker", "fingerprint": "411dcfc6c7c0de86d793e1d3cf2600ad9aceedc5b866c4e1ec0716eaa43b6789", "category": "docker", "severity": "low", "confidence": 0.72, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt install appears without --no-install-recommends.", "evidence": {"rule_id": "DKR011", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/", "https://github.com/hadolint/hadolint"], "correlation_key": "fp|411dcfc6c7c0de86d793e1d3cf2600ad9aceedc5b866c4e1ec0716eaa43b6789"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/ci/Dockerfile"}, "region": {"startLine": 10}}}]}, {"ruleId": "DKR010", "level": "note", "message": {"text": "Dockerfile leaves apt package indexes in the image layer"}, "properties": {"repobilityId": 95662, "scanner": "repobility-docker", "fingerprint": "82990f7b9b8c79d11e7859e8982d10ec41e1d0eba0b2bc42db97fd09d8964ff5", "category": "docker", "severity": "low", "confidence": 0.74, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "apt update/install layer does not remove /var/lib/apt/lists.", "evidence": {"rule_id": "DKR010", "scanner": "repobility-docker", "references": ["https://docs.docker.com/develop/develop-images/dockerfile_best-practices/"], "correlation_key": "fp|82990f7b9b8c79d11e7859e8982d10ec41e1d0eba0b2bc42db97fd09d8964ff5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/ci/Dockerfile"}, "region": {"startLine": 10}}}]}, {"ruleId": "AIC005", "level": "note", "message": {"text": "Duplicate top-level symbol appears in a patch-style file"}, "properties": {"repobilityId": 95660, "scanner": "repobility-ai-code-hygiene", "fingerprint": "7bac9b4907fed18889e06074d8214203374bd8e4d2e512d6a81660a58adb0c0a", "category": "quality", "severity": "low", "confidence": 0.64, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Patch-style file defines a top-level symbol also defined in another source file.", "evidence": {"symbol": "Journal", "rule_id": "AIC005", "scanner": "repobility-ai-code-hygiene", "references": ["https://github.com/jendrikseipp/vulture", "https://knip.dev/"], "duplicate_file": "app/models/journal/associated_journal.rb", "correlation_key": "fp|7bac9b4907fed18889e06074d8214203374bd8e4d2e512d6a81660a58adb0c0a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/journal/caused_by_system_update.rb"}, "region": {"startLine": 1}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95659, "scanner": "repobility-ai-code-hygiene", "fingerprint": "842de1a874ef6eacc6c1616486122c4e2182adb96ac83b203b30615f01d9ff4d", "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": "app/components/work_package_types/form_configuration/group_attribute_row_component.rb", "duplicate_line": 30, "correlation_key": "fp|842de1a874ef6eacc6c1616486122c4e2182adb96ac83b203b30615f01d9ff4d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/work_package_types/form_configuration/group_header_component.rb"}, "region": {"startLine": 58}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95658, "scanner": "repobility-ai-code-hygiene", "fingerprint": "5fd0fe4619391556d200b55f4d66f683f3b1583600c93d8990d02748c8511d96", "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": "app/components/settings/project_custom_field_sections/custom_field_row_component.rb", "duplicate_line": 25, "correlation_key": "fp|5fd0fe4619391556d200b55f4d66f683f3b1583600c93d8990d02748c8511d96"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/settings/project_custom_field_sections/show_component.rb"}, "region": {"startLine": 34}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95657, "scanner": "repobility-ai-code-hygiene", "fingerprint": "6ed7cf9482187b5a521ec75d05c8682c6e4cbaa24b7ffcfea8beed632306daf4", "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": "app/components/projects/settings/life_cycle/index_component.rb", "duplicate_line": 17, "correlation_key": "fp|6ed7cf9482187b5a521ec75d05c8682c6e4cbaa24b7ffcfea8beed632306daf4"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/projects/settings/project_custom_field_sections/index_component.rb"}, "region": {"startLine": 14}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95656, "scanner": "repobility-ai-code-hygiene", "fingerprint": "2f8a26dcea67761e6f2b8d8a5d1c862111f5b69fbdf836cb7785c127a81b8d4b", "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": "app/components/portfolios/index_sub_header_component.rb", "duplicate_line": 13, "correlation_key": "fp|2f8a26dcea67761e6f2b8d8a5d1c862111f5b69fbdf836cb7785c127a81b8d4b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/projects/index_sub_header_component.rb"}, "region": {"startLine": 13}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95655, "scanner": "repobility-ai-code-hygiene", "fingerprint": "fdc13605cf65e6883420a18bb7ac58df5a47e87e2bb00f86d413a378478af144", "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": "app/components/portfolios/index_page_header_component.rb", "duplicate_line": 27, "correlation_key": "fp|fdc13605cf65e6883420a18bb7ac58df5a47e87e2bb00f86d413a378478af144"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/projects/index_page_header_component.rb"}, "region": {"startLine": 69}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95654, "scanner": "repobility-ai-code-hygiene", "fingerprint": "e079db74f180b1ac93dfeb38014d3c482e30c00104d098c5c1e5932b6e00a187", "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": "app/components/placeholder_users/edit_page_header_component.rb", "duplicate_line": 23, "correlation_key": "fp|e079db74f180b1ac93dfeb38014d3c482e30c00104d098c5c1e5932b6e00a187"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/placeholder_users/show_page_header_component.rb"}, "region": {"startLine": 17}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95653, "scanner": "repobility-ai-code-hygiene", "fingerprint": "5187235b5ca2bacdd5d85c8a17e97d3f7ae8d232ce455088cd2bd5273ecb9d16", "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": "app/components/open_project/common/inplace_edit_fields/boolean_input_component.rb", "duplicate_line": 10, "correlation_key": "fp|5187235b5ca2bacdd5d85c8a17e97d3f7ae8d232ce455088cd2bd5273ecb9d16"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/open_project/common/inplace_edit_fields/text_input_component.rb"}, "region": {"startLine": 11}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95652, "scanner": "repobility-ai-code-hygiene", "fingerprint": "bc189f16b6f9a06557a33aa6af3d8ab130dd45eaf6aba7a50989fd916bfc02ac", "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": "app/components/my/access_token/api/row_component.rb", "duplicate_line": 13, "correlation_key": "fp|bc189f16b6f9a06557a33aa6af3d8ab130dd45eaf6aba7a50989fd916bfc02ac"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/my/access_token/ical/row_component.rb"}, "region": {"startLine": 24}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95651, "scanner": "repobility-ai-code-hygiene", "fingerprint": "b7be6fcda5a9311e030d1839567a202df46197a607dda7f003929bc9920acbc7", "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": "app/components/admin/departments/edit_page_header_component.rb", "duplicate_line": 3, "correlation_key": "fp|b7be6fcda5a9311e030d1839567a202df46197a607dda7f003929bc9920acbc7"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/groups/edit_page_header_component.rb"}, "region": {"startLine": 2}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 95650, "scanner": "repobility-ai-code-hygiene", "fingerprint": "e6940ac9265bac1acfca1da49f3912b1f0124a5e2e67c3577d2745e8883119ce", "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": "app/components/admin/import/jira/import_runs/wizard_component.rb", "duplicate_line": 16, "correlation_key": "fp|e6940ac9265bac1acfca1da49f3912b1f0124a5e2e67c3577d2745e8883119ce"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/admin/import/jira/import_runs/wizard_step_confirm_import_component.rb"}, "region": {"startLine": 15}}}]}, {"ruleId": "AIC002", "level": "note", "message": {"text": "Source file name looks like an AI patch artifact"}, "properties": {"repobilityId": 95648, "scanner": "repobility-ai-code-hygiene", "fingerprint": "253eb5a72b8f717c318605ee788a73d96e75fd7f717313d0b12f916854b889c5", "category": "quality", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Source filename contains a temporary or patch-style suffix.", "evidence": {"suffix": "update", "rule_id": "AIC002", "scanner": "repobility-ai-code-hygiene", "references": ["https://arxiv.org/abs/2601.15195"], "correlation_key": "fp|253eb5a72b8f717c318605ee788a73d96e75fd7f717313d0b12f916854b889c5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "lib/open_project/inplace_edit/handlers/project_update.rb"}, "region": {"startLine": 1}}}]}, {"ruleId": "AIC002", "level": "note", "message": {"text": "Source file name looks like an AI patch artifact"}, "properties": {"repobilityId": 95647, "scanner": "repobility-ai-code-hygiene", "fingerprint": "8a6d57a8c04000c188e4386089cfef6c0b068e7ad5fb206ef9a0618d8130e9d6", "category": "quality", "severity": "low", "confidence": 0.62, "triageState": "open", "verdict": "needs_review", "isResolved": false, "reason": "Source filename contains a temporary or patch-style suffix.", "evidence": {"suffix": "update", "rule_id": "AIC002", "scanner": "repobility-ai-code-hygiene", "references": ["https://arxiv.org/abs/2601.15195"], "correlation_key": "fp|8a6d57a8c04000c188e4386089cfef6c0b068e7ad5fb206ef9a0618d8130e9d6"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/journal/caused_by_system_update.rb"}, "region": {"startLine": 1}}}]}, {"ruleId": "AIC009", "level": "note", "message": {"text": "Multiple AI-agent scaffold marker files are present"}, "properties": {"repobilityId": 95646, "scanner": "repobility-ai-code-hygiene", "fingerprint": "32459e18838866b083b985fd53ac32d4e825aa20af779d902253d8278f625dfb", "category": "quality", "severity": "low", "confidence": 0.68, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Repository root contains several AI-agent scaffold marker files.", "evidence": {"markers": [".github/copilot-instructions.md", "AGENTS.md", "CLAUDE.md"], "rule_id": "AIC009", "scanner": "repobility-ai-code-hygiene", "references": ["https://arxiv.org/abs/2601.15195"], "correlation_key": "fp|32459e18838866b083b985fd53ac32d4e825aa20af779d902253d8278f625dfb"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/copilot-instructions.md"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR002", "level": "none", "message": {"text": "Dockerfile base image is selected through a build variable"}, "properties": {"repobilityId": 95675, "scanner": "repobility-docker", "fingerprint": "2fc7eadb203ba6f56b585d66a340da556747dff3f6c7d8ba430ae6c49d3fad6e", "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": "ruby:${RUBY_VERSION}-slim-trixie", "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|2fc7eadb203ba6f56b585d66a340da556747dff3f6c7d8ba430ae6c49d3fad6e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/prod/Dockerfile"}, "region": {"startLine": 6}}}]}, {"ruleId": "DKR002", "level": "none", "message": {"text": "Dockerfile base image is selected through a build variable"}, "properties": {"repobilityId": 95661, "scanner": "repobility-docker", "fingerprint": "412f60827426bd1e464341d7d0c6e89d54fff51fefb54a309340ee450907217b", "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": "ruby:${RUBY_VERSION}-trixie", "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|412f60827426bd1e464341d7d0c6e89d54fff51fefb54a309340ee450907217b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/ci/Dockerfile"}, "region": {"startLine": 3}}}]}, {"ruleId": "MINED043", "level": "none", "message": {"text": "[MINED043] Http Not Https: Hardcoded http:// (not localhost) for endpoints that handle credentials or data."}, "properties": {"repobilityId": 95635, "scanner": "repobility-threat-engine", "fingerprint": "ab0f75151019276f5d4b068f3374b990feb4e82aee7c29c1de4d15c31f72022e", "category": "quality", "severity": "info", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "http-not-https", "owasp": "A02:2021", "cwe_ids": ["CWE-319"], "precision": 0.917, "promoted_at": "2026-05-18T14:01:32.347999+00:00", "triaged_in_corpus": 12, "observations_count": 4113831, "ai_coder_pattern_id": 15}, "scanner": "repobility-threat-engine", "correlation_key": "fp|ab0f75151019276f5d4b068f3374b990feb4e82aee7c29c1de4d15c31f72022e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/helpers/frontend_asset_helper.rb"}, "region": {"startLine": 35}}}]}, {"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": 95627, "scanner": "repobility-threat-engine", "fingerprint": "5e6189ca867acda4e146994912f3d7fd8f5c55ce148c00adb68fe4391061b07d", "category": "credential_exposure", "severity": "info", "confidence": 0.1, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Cryptographic handling (password hashing, not hardcoded)", "evidence": {"match": "logger.error(\"Unable to re-hash UserPassword for #{user.login}: #{e.message}\")", "reason": "Cryptographic handling (password hashing, not hardcoded)", "rule_id": "SEC020", "scanner": "repobility-threat-engine", "confidence": 0.1, "correlation_key": "secret|app/models/user_password.rb|7|logger.error unable to re-hash userpassword for # user.login : # e.message"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/user_password.rb"}, "region": {"startLine": 75}}}]}, {"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": 95626, "scanner": "repobility-threat-engine", "fingerprint": "68ff1ec6eac825c95b55a3890007291ac0496d91f73bfed58321148adc416828", "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": "logger.error(\"Failed to revoke api token ##{current_user.id}: #{error}\")", "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|token|12|logger.error failed to revoke api token ## current_user.id : # error"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/my/access_tokens_controller.rb"}, "region": {"startLine": 128}}}]}, {"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": 95625, "scanner": "repobility-threat-engine", "fingerprint": "99de56fee568fa0315bdc857406cd831c321ac9a629cc68b14b79cb399f243ba", "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": "logger.error(\"Secret contained in auth source SSO header #{header_name} is not valid.\")", "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|token|12|logger.error secret contained in auth source sso header # header_name is not valid."}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/concerns/auth_source_sso.rb"}, "region": {"startLine": 121}}}]}, {"ruleId": "SEC029", "level": "none", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 33 more): Same pattern found in 33 additional files. Review if needed."}, "properties": {"repobilityId": 95621, "scanner": "repobility-threat-engine", "fingerprint": "09a29f6fb06578b561d63ae2dd291a76dfe5468697d8e07ddfb477e23b1df4cf", "category": "ssrf", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 33 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 33 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|09a29f6fb06578b561d63ae2dd291a76dfe5468697d8e07ddfb477e23b1df4cf"}}}, {"ruleId": "SEC128", "level": "none", "message": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake) (and 19 more): Same pattern found in 19 additional files. Review if needed."}, "properties": {"repobilityId": 95617, "scanner": "repobility-threat-engine", "fingerprint": "bd54825b370df96cfa928aef9dad2eaa620fcffcb67884d1a0ca6a60cfaa3cb7", "category": "quality", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 19 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 19 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC128", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|bd54825b370df96cfa928aef9dad2eaa620fcffcb67884d1a0ca6a60cfaa3cb7"}}}, {"ruleId": "MINED126", "level": "error", "message": {"text": "[MINED126] Workflow container/services image `postgres:16` unpinned: `container/services image: postgres:16` without `@sha256:...` pulls a mutable tag at workflow-run time. Treat workflow container references with the same supply-chain discipline as Dockerfile FROM lines."}, "properties": {"repobilityId": 95800, "scanner": "repobility-supply-chain", "fingerprint": "e42df2aceac653d5cff0d70b0e685aefd8bd14964196bbd7ca6e9ddaed8019c9", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-container-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|e42df2aceac653d5cff0d70b0e685aefd8bd14964196bbd7ca6e9ddaed8019c9"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/seed-all-locales.yml"}, "region": {"startLine": 76}}}]}, {"ruleId": "MINED126", "level": "error", "message": {"text": "[MINED126] Workflow container/services image `postgres:16` unpinned: `container/services image: postgres:16` without `@sha256:...` pulls a mutable tag at workflow-run time. Treat workflow container references with the same supply-chain discipline as Dockerfile FROM lines."}, "properties": {"repobilityId": 95797, "scanner": "repobility-supply-chain", "fingerprint": "a267519633d53a15e24f69877ded68dba7abf28e5e11f2c37d8ce74d74948e92", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-container-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|a267519633d53a15e24f69877ded68dba7abf28e5e11f2c37d8ce74d74948e92"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/packager.yml"}, "region": {"startLine": 22}}}]}, {"ruleId": "MINED130", "level": "error", "message": {"text": "[MINED130] Lockfile pulls package from off-canonical host `github.com`: `package-lock.json` resolved URL for `node_modules/op-blocknote-extensions` is `https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-block...` \u2014 host `github.com` is not the canonical registry. Could be a mirror compromise, dependency confusion attack, or a forgotten private registry."}, "properties": {"repobilityId": 95793, "scanner": "repobility-supply-chain", "fingerprint": "a4e508b1e2540d2a5fbfea7d7e869e40fb76ab402867d5342ae713ba2e2417c7", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "npm-lockfile-off-registry", "owasp": null, "cwe_ids": ["CWE-829"], "languages": ["javascript"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|a4e508b1e2540d2a5fbfea7d7e869e40fb76ab402867d5342ae713ba2e2417c7"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "extensions/op-blocknote-hocuspocus/package-lock.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "[MINED118] Dockerfile FROM `node:22.18` not pinned by digest: `FROM node:22.18` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should pin to `image@sha256:...` for reproducibility + supply-chain integrity."}, "properties": {"repobilityId": 95792, "scanner": "repobility-supply-chain", "fingerprint": "8919ca7b1ccccf88a092bf42f19772ac6b4e2e88aea15de639fbb6b572de32ca", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|8919ca7b1ccccf88a092bf42f19772ac6b4e2e88aea15de639fbb6b572de32ca"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "extensions/op-blocknote-hocuspocus/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "MINED122", "level": "error", "message": {"text": "[MINED122] package.json dep `op-blocknote-extensions` pulled from URL/Git: `dependencies.op-blocknote-extensions` = `https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz` bypasses the npm registry. No integrity hash, no version locking, no registry-side scanning. If the URL or git host is compromised, every `npm install` pulls the new payload."}, "properties": {"repobilityId": 95791, "scanner": "repobility-supply-chain", "fingerprint": "d66a05137c83e45747674cc480eb22b1d367e2056c1d1ec197a29b9d484a80f7", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "npm-dep-git-or-tarball-url", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["javascript"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|d66a05137c83e45747674cc480eb22b1d367e2056c1d1ec197a29b9d484a80f7"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "extensions/op-blocknote-hocuspocus/package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "[MINED118] Dockerfile FROM `ruby:2.6-stretch` not pinned by digest: `FROM ruby:2.6-stretch` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should pin to `image@sha256:...` for reproducibility + supply-chain integrity."}, "properties": {"repobilityId": 95790, "scanner": "repobility-supply-chain", "fingerprint": "891a12daed7aa2533dcbd94771c592547e001fd0790ced3ab1607eb84156b518", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|891a12daed7aa2533dcbd94771c592547e001fd0790ced3ab1607eb84156b518"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/prod/mysql-to-postgres/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "[MINED118] Dockerfile FROM `node:22.21.0` not pinned by digest: `FROM node:22.21.0` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should pin to `image@sha256:...` for reproducibility + supply-chain integrity."}, "properties": {"repobilityId": 95789, "scanner": "repobility-supply-chain", "fingerprint": "79fa258855664304b66f1b5dc1dcd8f3c25650a9c2b399341915323f67aacd30", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|79fa258855664304b66f1b5dc1dcd8f3c25650a9c2b399341915323f67aacd30"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/frontend/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "MINED118", "level": "error", "message": {"text": "[MINED118] Dockerfile FROM `ruby:4.0.2-trixie` not pinned by digest: `FROM ruby:4.0.2-trixie` resolves the tag at build time. The registry CAN re-push a different image for the same tag, so every build is potentially different. Production images should pin to `image@sha256:...` for reproducibility + supply-chain integrity."}, "properties": {"repobilityId": 95788, "scanner": "repobility-supply-chain", "fingerprint": "b5d1477d6493e8f0d72d727ca4bfa8de69c1119028751f392aa44df3ce968ded", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "docker-from-unpinned", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["dockerfile"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|b5d1477d6493e8f0d72d727ca4bfa8de69c1119028751f392aa44df3ce968ded"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/backend/Dockerfile"}, "region": {"startLine": 1}}}]}, {"ruleId": "MINED130", "level": "error", "message": {"text": "[MINED130] Lockfile pulls package from off-canonical host `github.com`: `package-lock.json` resolved URL for `node_modules/op-blocknote-extensions` is `https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-block...` \u2014 host `github.com` is not the canonical registry. Could be a mirror compromise, dependency confusion attack, or a forgotten private registry."}, "properties": {"repobilityId": 95787, "scanner": "repobility-supply-chain", "fingerprint": "5781a47bf11635f636005e7b98cac5fccdd32d11a8e0ff4d4081e9aab2f9d7ef", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "npm-lockfile-off-registry", "owasp": null, "cwe_ids": ["CWE-829"], "languages": ["javascript"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|5781a47bf11635f636005e7b98cac5fccdd32d11a8e0ff4d4081e9aab2f9d7ef"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/package-lock.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "MINED122", "level": "error", "message": {"text": "[MINED122] package.json dep `op-blocknote-extensions` pulled from URL/Git: `dependencies.op-blocknote-extensions` = `https://github.com/opf/op-blocknote-extensions/releases/download/v0.1.0/op-blocknote-extensions-0.1.0.tgz` bypasses the npm registry. No integrity hash, no version locking, no registry-side scanning. If the URL or git host is compromised, every `npm install` pulls the new payload."}, "properties": {"repobilityId": 95786, "scanner": "repobility-supply-chain", "fingerprint": "9f525a9c4085fe2085f2deef6e12424b223f6517b054e33a17deb36b75f5470f", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "npm-dep-git-or-tarball-url", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["javascript"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|9f525a9c4085fe2085f2deef6e12424b223f6517b054e33a17deb36b75f5470f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "frontend/package.json"}, "region": {"startLine": 1}}}]}, {"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: ANY /plugin/:id."}, "properties": {"repobilityId": 95748, "scanner": "repobility-access-control", "fingerprint": "0894d29c2231d9004a5788914879f7a1fa70c3ce6f04c4b17e4acd3d540290fa", "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": "/plugin/:id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|778|auc003", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 778}}}]}, {"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: ANY /options/:option_id."}, "properties": {"repobilityId": 95747, "scanner": "repobility-access-control", "fingerprint": "7a1a704d6de6bbaca0feafcf58b17d4f0fbf34fd554d68d64a10bd41621ed2c5", "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": "/options/:option_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|715|auc003", "identity_targets": ["unknown", "owner", "admin"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 715}}}]}, {"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: ANY /memberships/:membership_id."}, "properties": {"repobilityId": 95746, "scanner": "repobility-access-control", "fingerprint": "b7fa405a9ea0f614e06e1cc5d983d639e4aef6c5cf0fa0b7c06fd4f67dce3cd0", "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": "/memberships/:membership_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|632|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 632}}}]}, {"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: ANY /memberships/:membership_id."}, "properties": {"repobilityId": 95745, "scanner": "repobility-access-control", "fingerprint": "9e1d7ff91413508b721f32366b96b4760c9ea58d31439eb52e2dddd72f0cb5db", "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": "/memberships/:membership_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|631|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 631}}}]}, {"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: ANY /memberships/:membership_id."}, "properties": {"repobilityId": 95744, "scanner": "repobility-access-control", "fingerprint": "2c54e84f8dbb6958baa90e2319b6e14d642dda3b71742d18ff40b65e261f84c7", "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": "/memberships/:membership_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|630|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 630}}}]}, {"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: ANY /members/:user_id."}, "properties": {"repobilityId": 95743, "scanner": "repobility-access-control", "fingerprint": "eb3bba2e55f4b090dffdfa360c9ddf709b7c22bc84cdb4ac54e381102bf3f7da", "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": "/members/:user_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|628|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 628}}}]}, {"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: ANY /by_principal/:principal_id."}, "properties": {"repobilityId": 95742, "scanner": "repobility-access-control", "fingerprint": "cb3d6669c336cda957c840e63d1f1daa5400bc00e1e53a2c2fb288aef5e0602a", "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": "/by_principal/:principal_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|508|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 508}}}]}, {"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: ANY /(projects/:project_id)/search."}, "properties": {"repobilityId": 95741, "scanner": "repobility-access-control", "fingerprint": "a9c8e345ff0d1168fb031a6595b09f376a874b0ea1530a1c39fa1b76c61a25b6", "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": "/(projects/:project_id)/search", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|268|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 268}}}]}, {"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: ANY /options/:option_id."}, "properties": {"repobilityId": 95740, "scanner": "repobility-access-control", "fingerprint": "b913688ed448e21cd5ab4ba46087209f41941ddda55ba5ff7fed05d5c19c08d6", "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": "/options/:option_id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|239|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 239}}}]}, {"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: ANY /move/:id."}, "properties": {"repobilityId": 95739, "scanner": "repobility-access-control", "fingerprint": "5cdb72a2ea6aaea226036d8aa2d4d87c8971867e282f44e895c5d2143e425bd5", "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": "/move/:id", "method": "ANY", "scanner": "repobility-access-control", "framework": "Rails", "correlation_key": "code|auth|config/routes.rb|200|auc003", "identity_targets": ["unknown", "owner"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "config/routes.rb"}, "region": {"startLine": 200}}}]}, {"ruleId": "DKC013", "level": "error", "message": {"text": "Database service has no persistent data volume"}, "properties": {"repobilityId": 95698, "scanner": "repobility-docker", "fingerprint": "68c13af789e9fd2d5f8ff849a5cfe7f40bbfa9d6b9ab6e07a1e0b8877fae0d17", "category": "docker", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Database-like service does not mount a known data directory.", "evidence": {"rule_id": "DKC013", "scanner": "repobility-docker", "service": "web", "references": ["https://docs.docker.com/engine/storage/volumes/"], "correlation_key": "fp|68c13af789e9fd2d5f8ff849a5cfe7f40bbfa9d6b9ab6e07a1e0b8877fae0d17", "expected_targets": ["/var/lib/postgresql/data"]}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/xwiki/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKC011", "level": "error", "message": {"text": "Database service publishes a host port"}, "properties": {"repobilityId": 95693, "scanner": "repobility-docker", "fingerprint": "670f36bc8c39d80370c850e195b231408953ff409393c9b8c7457b39e2ab808e", "category": "docker", "severity": "high", "confidence": 0.84, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "Database-like image publishes host ports without a loopback-only bind.", "evidence": {"ports": [{"raw": "9000:9000", "target": "9000", "host_ip": "", "published": "9000"}, {"raw": "9001:9001", "target": "9001", "host_ip": "", "published": "9001"}], "rule_id": "DKC011", "scanner": "repobility-docker", "service": "minio", "references": ["https://docs.docker.com/compose/how-tos/environment-variables/best-practices/", "https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "exposure_scope": "public", "correlation_key": "fp|670f36bc8c39d80370c850e195b231408953ff409393c9b8c7457b39e2ab808e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/minio/docker-compose.yml"}, "region": {"startLine": 2}}}]}, {"ruleId": "DKC009", "level": "error", "message": {"text": "Compose service bind-mounts a sensitive host path"}, "properties": {"repobilityId": 95690, "scanner": "repobility-docker", "fingerprint": "bfdbadc7fc6dcd16e158aedfa4848e9aba044a9d532593bdb48657de79e96cb8", "category": "docker", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Bind mount source points at a sensitive host path.", "evidence": {"source": "/etc/ssl/certs/ca-certificates.crt", "rule_id": "DKC009", "scanner": "repobility-docker", "service": "keycloak", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|bfdbadc7fc6dcd16e158aedfa4848e9aba044a9d532593bdb48657de79e96cb8"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/keycloak/docker-compose.yml"}, "region": {"startLine": 13}}}]}, {"ruleId": "DKC009", "level": "error", "message": {"text": "Compose service bind-mounts a sensitive host path"}, "properties": {"repobilityId": 95683, "scanner": "repobility-docker", "fingerprint": "1264b4eedd58b31fcf699be609b1f0752032ac39a51a3c61506ac7d11f591a87", "category": "docker", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Bind mount source points at a sensitive host path.", "evidence": {"source": "/etc/ssl/certs", "rule_id": "DKC009", "scanner": "repobility-docker", "service": "gitlab", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|1264b4eedd58b31fcf699be609b1f0752032ac39a51a3c61506ac7d11f591a87"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/gitlab/docker-compose.yml"}, "region": {"startLine": 3}}}]}, {"ruleId": "DKR001", "level": "error", "message": {"text": "Docker final stage runs as root"}, "properties": {"repobilityId": 95672, "scanner": "repobility-docker", "fingerprint": "101931c0267e9b5519901fd5de7bb76894639877d9a580be8aa9c669831bb9df", "category": "docker", "severity": "high", "confidence": 0.95, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Final Dockerfile USER resolves to root.", "evidence": {"rule_id": "DKR001", "scanner": "repobility-docker", "final_user": "root", "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|101931c0267e9b5519901fd5de7bb76894639877d9a580be8aa9c669831bb9df"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/backend/Dockerfile"}, "region": {"startLine": 67}}}]}, {"ruleId": "MINED004", "level": "error", "message": {"text": "[MINED004] Weak Crypto: MD5/SHA1/DES/RC4 used for security context (not just checksums)."}, "properties": {"repobilityId": 95637, "scanner": "repobility-threat-engine", "fingerprint": "e6b7647d6305b190b246a9bc513279281d81eca640aca815015a97ee79f78c7f", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "weak-crypto", "owasp": "A02:2021", "cwe_ids": ["CWE-327"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.347906+00:00", "triaged_in_corpus": 15, "observations_count": 303181, "ai_coder_pattern_id": 13}, "scanner": "repobility-threat-engine", "correlation_key": "fp|e6b7647d6305b190b246a9bc513279281d81eca640aca815015a97ee79f78c7f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/user_password/sha1.rb"}, "region": {"startLine": 35}}}]}, {"ruleId": "MINED004", "level": "error", "message": {"text": "[MINED004] Weak Crypto: MD5/SHA1/DES/RC4 used for security context (not just checksums)."}, "properties": {"repobilityId": 95636, "scanner": "repobility-threat-engine", "fingerprint": "60a9b944e19a7876ce9341a555e4e63a4b322e971a098f501dba8bd538a3e542", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "weak-crypto", "owasp": "A02:2021", "cwe_ids": ["CWE-327"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.347906+00:00", "triaged_in_corpus": 15, "observations_count": 303181, "ai_coder_pattern_id": 13}, "scanner": "repobility-threat-engine", "correlation_key": "fp|60a9b944e19a7876ce9341a555e4e63a4b322e971a098f501dba8bd538a3e542"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/attachment.rb"}, "region": {"startLine": 31}}}]}, {"ruleId": "SEC103", "level": "error", "message": {"text": "[SEC103] LDAP injection \u2014 non-constant search filter: User input concatenated into an LDAP search filter. Attackers inject `*)(uid=*` style payloads to bypass auth or enumerate accounts."}, "properties": {"repobilityId": 95634, "scanner": "repobility-threat-engine", "fingerprint": "8d384f7efb57c58f070465698492831e317a2b8959afd67480cfabefab4d857a", "category": "injection", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".search(tokens,\n                          projects_to_search,\n                          limit: (LIMI", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC103", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "code|injection|token|120|sec103"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/search_controller.rb"}, "region": {"startLine": 120}}}]}, {"ruleId": "SEC109", "level": "error", "message": {"text": "[SEC109] Rails skip_forgery_protection / protect_from_forgery disabled: Rails CSRF protection turned off at controller level. Any state-changing endpoint becomes a CSRF target."}, "properties": {"repobilityId": 95633, "scanner": "repobility-threat-engine", "fingerprint": "419771be690d3d8182f97fe576e5e912a4713aa9c8e286fd7169a473cf10ca2b", "category": "csrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "skip_before_action :verify_authenticity_token", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC109", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|419771be690d3d8182f97fe576e5e912a4713aa9c8e286fd7169a473cf10ca2b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/sys_controller.rb"}, "region": {"startLine": 40}}}]}, {"ruleId": "SEC109", "level": "error", "message": {"text": "[SEC109] Rails skip_forgery_protection / protect_from_forgery disabled: Rails CSRF protection turned off at controller level. Any state-changing endpoint becomes a CSRF target."}, "properties": {"repobilityId": 95632, "scanner": "repobility-threat-engine", "fingerprint": "422ad1d92124255b3579d73142e36dbd58ef01c02095929f4826073e1c89a1ad", "category": "csrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "skip_before_action :verify_authenticity_token", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC109", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|422ad1d92124255b3579d73142e36dbd58ef01c02095929f4826073e1c89a1ad"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/scim_v2/base_controller_actions.rb"}, "region": {"startLine": 36}}}]}, {"ruleId": "SEC109", "level": "error", "message": {"text": "[SEC109] Rails skip_forgery_protection / protect_from_forgery disabled: Rails CSRF protection turned off at controller level. Any state-changing endpoint becomes a CSRF target."}, "properties": {"repobilityId": 95631, "scanner": "repobility-threat-engine", "fingerprint": "ffbe327eecb306b188830a6758837feacd4bcf8524673dfd87f424c9a612e116", "category": "csrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "skip_before_action :verify_authenticity_token", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC109", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|ffbe327eecb306b188830a6758837feacd4bcf8524673dfd87f424c9a612e116"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/omni_auth_login_controller.rb"}, "region": {"startLine": 40}}}]}, {"ruleId": "SEC097", "level": "error", "message": {"text": "[SEC097] Rails: force_ssl disabled / protect_from_forgery missing: Rails app disables SSL or CSRF protection. Concept from Brakeman check_force_ssl / check_forgery_setting \u2014 re-authored from OWASP A07."}, "properties": {"repobilityId": 95630, "scanner": "repobility-threat-engine", "fingerprint": "7bb80367187121c0f8065bcca43d887afcf943cbde177f19df08ae935df8ae57", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "skip_before_action :verify_authenticity_token", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC097", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|7bb80367187121c0f8065bcca43d887afcf943cbde177f19df08ae935df8ae57"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/sys_controller.rb"}, "region": {"startLine": 40}}}]}, {"ruleId": "SEC097", "level": "error", "message": {"text": "[SEC097] Rails: force_ssl disabled / protect_from_forgery missing: Rails app disables SSL or CSRF protection. Concept from Brakeman check_force_ssl / check_forgery_setting \u2014 re-authored from OWASP A07."}, "properties": {"repobilityId": 95629, "scanner": "repobility-threat-engine", "fingerprint": "8a5543ed43aa4caad105b5edff078de5dd82f3057f15710239044bed5d754611", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "skip_before_action :verify_authenticity_token", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC097", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|8a5543ed43aa4caad105b5edff078de5dd82f3057f15710239044bed5d754611"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/scim_v2/base_controller_actions.rb"}, "region": {"startLine": 36}}}]}, {"ruleId": "SEC097", "level": "error", "message": {"text": "[SEC097] Rails: force_ssl disabled / protect_from_forgery missing: Rails app disables SSL or CSRF protection. Concept from Brakeman check_force_ssl / check_forgery_setting \u2014 re-authored from OWASP A07."}, "properties": {"repobilityId": 95628, "scanner": "repobility-threat-engine", "fingerprint": "40a24e88dfc8bbe83775c4b0bee5ebb76b414958e9c3f78450676933c3581b5f", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "skip_before_action :verify_authenticity_token", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC097", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|40a24e88dfc8bbe83775c4b0bee5ebb76b414958e9c3f78450676933c3581b5f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/controllers/omni_auth_login_controller.rb"}, "region": {"startLine": 40}}}]}, {"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": 95620, "scanner": "repobility-threat-engine", "fingerprint": "544ab1848461e3c1f414994fdde8936fbefa174419b043069716f78ab5375f02", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "url(p", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|544ab1848461e3c1f414994fdde8936fbefa174419b043069716f78ab5375f02"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/admin/import/jira/import_runs/select_projects/modal_component.rb"}, "region": {"startLine": 50}}}]}, {"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": 95619, "scanner": "repobility-threat-engine", "fingerprint": "ac02272d8093c1fe2043afde2bd95940349483c7b76bf7449247f0ce46cf7bb1", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "url(p", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|ac02272d8093c1fe2043afde2bd95940349483c7b76bf7449247f0ce46cf7bb1"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/admin/import/jira/import_runs/select_projects/list_footer_component.rb"}, "region": {"startLine": 46}}}]}, {"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": 95618, "scanner": "repobility-threat-engine", "fingerprint": "f21899189444a6085250a563dc6f6e44a67703decfe191fcdf7da2aa26aadb44", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "url(p", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|f21899189444a6085250a563dc6f6e44a67703decfe191fcdf7da2aa26aadb44"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/admin/import/jira/import_runs/select_projects/list_component.rb"}, "region": {"startLine": 50}}}]}, {"ruleId": "SEC128", "level": "error", "message": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake): Async call invoked without `await` returns an unhandled Promise. The outer function resolves before the inner work completes \u2014 DB writes lost, emails not sent, race conditions. This is one of the top-3 errors AI coders make: they understand async-shape but drop the await keyword when chaining multiple ops. Surfaces as flaky tests or silently dropped data in production."}, "properties": {"repobilityId": 95616, "scanner": "repobility-threat-engine", "fingerprint": "867d4645e6154668bc698f93dc8981bfe6cb70bad1951fe2a55ebcf2607adea8", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "options.fetch(:validate_model, false)", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC128", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|867d4645e6154668bc698f93dc8981bfe6cb70bad1951fe2a55ebcf2607adea8"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/contracts/projects/copy_contract.rb"}, "region": {"startLine": 36}}}]}, {"ruleId": "SEC128", "level": "error", "message": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake): Async call invoked without `await` returns an unhandled Promise. The outer function resolves before the inner work completes \u2014 DB writes lost, emails not sent, race conditions. This is one of the top-3 errors AI coders make: they understand async-shape but drop the await keyword when chaining multiple ops. Surfaces as flaky tests or silently dropped data in production."}, "properties": {"repobilityId": 95615, "scanner": "repobility-threat-engine", "fingerprint": "163000a1e8c12dcec09e031c79d31eedad4721558cf32327c219de5d1f084278", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "date_fields.fetch(focused_field.to_s.underscore, :start_date)", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC128", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|163000a1e8c12dcec09e031c79d31eedad4721558cf32327c219de5d1f084278"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/work_packages/date_picker/date_form_component.rb"}, "region": {"startLine": 148}}}]}, {"ruleId": "SEC128", "level": "error", "message": {"text": "[SEC128] Async function without await \u2014 fire-and-forget Promise (AI mistake): Async call invoked without `await` returns an unhandled Promise. The outer function resolves before the inner work completes \u2014 DB writes lost, emails not sent, race conditions. This is one of the top-3 errors AI coders make: they understand async-shape but drop the await keyword when chaining multiple ops. Surfaces as flaky tests or silently dropped data in production."}, "properties": {"repobilityId": 95614, "scanner": "repobility-threat-engine", "fingerprint": "6c5f6a24cd1a3d6deb6497d8e21f282c5fc3592a548e141c2bb62eec37054f20", "category": "quality", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "details.delete(\"entity_id\")", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC128", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|6c5f6a24cd1a3d6deb6497d8e21f282c5fc3592a548e141c2bb62eec37054f20"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/components/activities/item_component.rb"}, "region": {"startLine": 160}}}]}, {"ruleId": "MINED116", "level": "error", "message": {"text": "[MINED116] Workflow uses `secrets.HETZNER_CA_KEY` on a `pull_request` trigger: This workflow triggers on `pull_request`, which checks out the FORK's code. Referencing `${ secrets.HETZNER_CA_KEY }` lets a PR from any fork exfiltrate the secret (modify a script, log the value, etc.). Use `pull_request_target` ONLY with strict checkout discipline (no fork code in the trusted context)."}, "properties": {"repobilityId": 95799, "scanner": "repobility-supply-chain", "fingerprint": "64f97a7df3c8d03ce7d398bfbfea9ed17adb0d0dae01eed1c0fe32545e72c619", "category": "dependency", "severity": "critical", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-pull-request-secrets", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|64f97a7df3c8d03ce7d398bfbfea9ed17adb0d0dae01eed1c0fe32545e72c619"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/pullpreview.yml"}, "region": {"startLine": 60}}}]}, {"ruleId": "MINED116", "level": "error", "message": {"text": "[MINED116] Workflow uses `secrets.HCLOUD_TOKEN` on a `pull_request` trigger: This workflow triggers on `pull_request`, which checks out the FORK's code. Referencing `${ secrets.HCLOUD_TOKEN }` lets a PR from any fork exfiltrate the secret (modify a script, log the value, etc.). Use `pull_request_target` ONLY with strict checkout discipline (no fork code in the trusted context)."}, "properties": {"repobilityId": 95798, "scanner": "repobility-supply-chain", "fingerprint": "f18fcc42473b89927eddf7d9108e953c9ae07ec8f1ede9e4d70852c05f3368c7", "category": "dependency", "severity": "critical", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-pull-request-secrets", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|f18fcc42473b89927eddf7d9108e953c9ae07ec8f1ede9e4d70852c05f3368c7"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/pullpreview.yml"}, "region": {"startLine": 59}}}]}, {"ruleId": "MINED116", "level": "error", "message": {"text": "[MINED116] Workflow uses `secrets.OPENPROJECTCI_GH_SAAS_WORKFLOW_PAT` on a `pull_request` trigger: This workflow triggers on `pull_request`, which checks out the FORK's code. Referencing `${ secrets.OPENPROJECTCI_GH_SAAS_WORKFLOW_PAT }` lets a PR from any fork exfiltrate the secret (modify a script, log the value, etc.). Use `pull_request_target` ONLY with strict checkout discipline (no fork code in the trusted context)."}, "properties": {"repobilityId": 95796, "scanner": "repobility-supply-chain", "fingerprint": "9c6719d0638b5b085877c1729fdd8559dd4b731fc03dfdcdafb0b6488d785513", "category": "dependency", "severity": "critical", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-pull-request-secrets", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|9c6719d0638b5b085877c1729fdd8559dd4b731fc03dfdcdafb0b6488d785513"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/downstream-ci.yml"}, "region": {"startLine": 34}}}]}, {"ruleId": "MINED116", "level": "error", "message": {"text": "[MINED116] Workflow uses `secrets.CAPYBARA_AWS_SECRET_ACCESS_KEY` on a `pull_request` trigger: This workflow triggers on `pull_request`, which checks out the FORK's code. Referencing `${ secrets.CAPYBARA_AWS_SECRET_ACCESS_KEY }` lets a PR from any fork exfiltrate the secret (modify a script, log the value, etc.). Use `pull_request_target` ONLY with strict checkout discipline (no fork code in the trusted context)."}, "properties": {"repobilityId": 95795, "scanner": "repobility-supply-chain", "fingerprint": "c4a6730252b1519edf157192cfdea0658a926395fbbbc090b6368883f3fffe53", "category": "dependency", "severity": "critical", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-pull-request-secrets", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|c4a6730252b1519edf157192cfdea0658a926395fbbbc090b6368883f3fffe53"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test-core.yml"}, "region": {"startLine": 88}}}]}, {"ruleId": "MINED116", "level": "error", "message": {"text": "[MINED116] Workflow uses `secrets.CAPYBARA_AWS_ACCESS_KEY_ID` on a `pull_request` trigger: This workflow triggers on `pull_request`, which checks out the FORK's code. Referencing `${ secrets.CAPYBARA_AWS_ACCESS_KEY_ID }` lets a PR from any fork exfiltrate the secret (modify a script, log the value, etc.). Use `pull_request_target` ONLY with strict checkout discipline (no fork code in the trusted context)."}, "properties": {"repobilityId": 95794, "scanner": "repobility-supply-chain", "fingerprint": "f18dbf6bf336a582f3496e8ed4e4adccf98727d8ea49f5b10c9bec6532f14ed4", "category": "dependency", "severity": "critical", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-pull-request-secrets", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|f18dbf6bf336a582f3496e8ed4e4adccf98727d8ea49f5b10c9bec6532f14ed4"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/test-core.yml"}, "region": {"startLine": 87}}}]}, {"ruleId": "DKC007", "level": "error", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95731, "scanner": "repobility-docker", "fingerprint": "cf9c65ebc361ffd923d80488a2c8c41aec5445bb3d5098d2591e34a89c7cb783", "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": "hocuspocus-test", "variable": "SECRET", "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|cf9c65ebc361ffd923d80488a2c8c41aec5445bb3d5098d2591e34a89c7cb783", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 125}}}]}, {"ruleId": "DKC007", "level": "error", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95728, "scanner": "repobility-docker", "fingerprint": "82eb5dad2f2d03dfba2751884263ae84b3b88dfda814cf427cf1a5b8a207acf3", "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": "db-test", "variable": "POSTGRES_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|82eb5dad2f2d03dfba2751884263ae84b3b88dfda814cf427cf1a5b8a207acf3", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker-compose.yml"}, "region": {"startLine": 113}}}]}, {"ruleId": "DKC007", "level": "error", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95714, "scanner": "repobility-docker", "fingerprint": "7b531dcf577e4dc57979eaa7e7c0fa3ded9433630e1dc597a578f89644a10a24", "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": "hocuspocus", "variable": "SECRET", "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|7b531dcf577e4dc57979eaa7e7c0fa3ded9433630e1dc597a578f89644a10a24", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 79}}}]}, {"ruleId": "DKC007", "level": "error", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95710, "scanner": "repobility-docker", "fingerprint": "b9269dd80f86d92a4ae6d903de19b6cda74e1ae3f5b05ea53e9a82edc039cd01", "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": "worker", "variable": "OPENPROJECT_COLLABORATIVE__EDITING__HOCUSPOCUS__SECRET", "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|b9269dd80f86d92a4ae6d903de19b6cda74e1ae3f5b05ea53e9a82edc039cd01", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 73}}}]}, {"ruleId": "DKC007", "level": "error", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95706, "scanner": "repobility-docker", "fingerprint": "dcd0c134917f56a2fd5d22a315db48968d7d8c745c0d7014b4674d20e9d013d3", "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": "web", "variable": "OPENPROJECT_COLLABORATIVE__EDITING__HOCUSPOCUS__SECRET", "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|dcd0c134917f56a2fd5d22a315db48968d7d8c745c0d7014b4674d20e9d013d3", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 64}}}]}, {"ruleId": "DKC007", "level": "error", "message": {"text": "Compose service contains a literal secret environment value"}, "properties": {"repobilityId": 95703, "scanner": "repobility-docker", "fingerprint": "1fdae5ba37e8d800c89aeb3f58b76857acf331bf9890961a243965b5e112389f", "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": "db", "variable": "POSTGRES_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|1fdae5ba37e8d800c89aeb3f58b76857acf331bf9890961a243965b5e112389f", "compose_secrets_declared": false}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/pullpreview/docker-compose.yml"}, "region": {"startLine": 51}}}]}, {"ruleId": "DKC008", "level": "error", "message": {"text": "Compose service mounts the Docker socket"}, "properties": {"repobilityId": 95695, "scanner": "repobility-docker", "fingerprint": "cef1d2ce439cae30112afd2724860593f8dc177ebd27279c461172815d4f5418", "category": "docker", "severity": "critical", "confidence": 0.98, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Volume mount references /var/run/docker.sock.", "evidence": {"rule_id": "DKC008", "scanner": "repobility-docker", "service": "traefik", "references": ["https://cheatsheetseries.owasp.org/cheatsheets/Docker_Security_Cheat_Sheet.html"], "correlation_key": "fp|cef1d2ce439cae30112afd2724860593f8dc177ebd27279c461172815d4f5418"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/dev/tls/docker-compose.yml"}, "region": {"startLine": 1}}}]}, {"ruleId": "DKR005", "level": "error", "message": {"text": "Docker image bakes a secret-like ENV value"}, "properties": {"repobilityId": 95676, "scanner": "repobility-docker", "fingerprint": "d6dc7ceae7ce8e802838f15c4ddab301d16c9e74139fa5ad3a17890e89444af0", "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": "SECRET_KEY_BASE", "references": ["https://docs.docker.com/build/building/secrets/", "https://docs.docker.com/compose/how-tos/environment-variables/best-practices/"], "correlation_key": "fp|d6dc7ceae7ce8e802838f15c4ddab301d16c9e74139fa5ad3a17890e89444af0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docker/prod/Dockerfile"}, "region": {"startLine": 32}}}]}, {"ruleId": "MINED018", "level": "error", "message": {"text": "[MINED018] Unsafe Deserialization Pickle: pickle.loads / yaml.load (without Loader=SafeLoader) / unmarshal of network/file data \u2014 RCE."}, "properties": {"repobilityId": 95645, "scanner": "repobility-threat-engine", "fingerprint": "bb5a245e285da4af3515484ca59d7c243be760856fa0497548e1da87c7d5becb", "category": "quality", "severity": "critical", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"mined": true, "mining": {"slug": "unsafe-deserialization-pickle", "owasp": "A08:2021", "cwe_ids": ["CWE-502"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.347940+00:00", "triaged_in_corpus": 20, "observations_count": 58759, "ai_coder_pattern_id": 32}, "scanner": "repobility-threat-engine", "correlation_key": "fp|bb5a245e285da4af3515484ca59d7c243be760856fa0497548e1da87c7d5becb"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/queries/work_packages/filter_serializer.rb"}, "region": {"startLine": 42}}}]}, {"ruleId": "SEC116", "level": "error", "message": {"text": "[SEC116] Ruby YAML.load / Marshal.load on untrusted input: `YAML.load` (pre-3.1) and `Marshal.load` instantiate arbitrary Ruby classes \u2014 direct RCE on untrusted input. `unsafe_load` is even more dangerous."}, "properties": {"repobilityId": 95644, "scanner": "repobility-threat-engine", "fingerprint": "b39a8fd71648f6464e0e376e795118614bb663ed41bc7e0b864f97a62bf4700f", "category": "deserialization", "severity": "critical", "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": "SEC116", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "code|deserialization|token|42|sec116"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/queries/work_packages/filter_serializer.rb"}, "region": {"startLine": 42}}}]}, {"ruleId": "SEC079", "level": "error", "message": {"text": "[SEC079] Python: yaml.load without SafeLoader: yaml.load() without explicit SafeLoader can execute arbitrary Python objects (CVE-2017-18342). Ported from bandit B506 / dlint DUO109 (Apache-2.0 / BSD-3)."}, "properties": {"repobilityId": 95643, "scanner": "repobility-threat-engine", "fingerprint": "01271f429d9142bee25374379d4c98bf36abe7b50144a5c4d3aaafa46696bc3d", "category": "quality", "severity": "critical", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "YAML.load(yaml, permitted_classes: [Symbol, Date])", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC079", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|01271f429d9142bee25374379d4c98bf36abe7b50144a5c4d3aaafa46696bc3d"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/queries/work_packages/filter_serializer.rb"}, "region": {"startLine": 42}}}]}, {"ruleId": "SEC096", "level": "error", "message": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql: ActiveRecord where() / find_by_sql with interpolation enables SQL injection. Concept from Brakeman check_sql \u2014 re-authored from OWASP CWE-89."}, "properties": {"repobilityId": 95640, "scanner": "repobility-threat-engine", "fingerprint": "142d88b0cab522997206270d08abeb160a25d95130c77f8a3f7a0320da9b53e5", "category": "quality", "severity": "critical", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".where(\"#{Project::Phase.table_name}.project_id = #{", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC096", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|142d88b0cab522997206270d08abeb160a25d95130c77f8a3f7a0320da9b53e5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/queries/projects/filters/filter_on_project_phase.rb"}, "region": {"startLine": 155}}}]}, {"ruleId": "SEC096", "level": "error", "message": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql: ActiveRecord where() / find_by_sql with interpolation enables SQL injection. Concept from Brakeman check_sql \u2014 re-authored from OWASP CWE-89."}, "properties": {"repobilityId": 95639, "scanner": "repobility-threat-engine", "fingerprint": "6b6cfbbd9561952d287448701fa3a63db9b72c8faba76128d15e6132bab433e5", "category": "quality", "severity": "critical", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".where(\"#{", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC096", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|6b6cfbbd9561952d287448701fa3a63db9b72c8faba76128d15e6132bab433e5"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/journal.rb"}, "region": {"startLine": 205}}}]}, {"ruleId": "SEC096", "level": "error", "message": {"text": "[SEC096] Rails: SQL injection via where(\"#{...}\") or find_by_sql: ActiveRecord where() / find_by_sql with interpolation enables SQL injection. Concept from Brakeman check_sql \u2014 re-authored from OWASP CWE-89."}, "properties": {"repobilityId": 95638, "scanner": "repobility-threat-engine", "fingerprint": "7919f7178ae3d701006347b5fe91d5ea1ae38de17f930dc5494038f16654782a", "category": "quality", "severity": "critical", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": ".where(\"category_id = #{", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC096", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|7919f7178ae3d701006347b5fe91d5ea1ae38de17f930dc5494038f16654782a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "app/models/category.rb"}, "region": {"startLine": 53}}}]}]}]}