{"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": "scanner-e6c7afc57d4527eb", "name": "Stray `console.log` in TS/JS \u2014 server.js:72", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 server.js:72"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-8ba8d8186e719869", "name": "Stray `console.log` in TS/JS \u2014 seed.js:34", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 seed.js:34"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-1e5dfe63b8b48700", "name": "Stray `console.log` in TS/JS \u2014 add-dev-account.js:13", "shortDescription": {"text": "Stray `console.log` in TS/JS \u2014 add-dev-account.js:13"}, "fullDescription": {"text": "Replace with the toast helper, an error boundary, or remove. `console.warn` / `console.error` are acceptable.\n\nWhy: Hygiene \u2014 easy to leak debug output.\nRule id: fq.console-leak"}, "properties": {"scanner": "scanner-primary", "layer": "frontend", "severity": "low", "confidence": 1.0}}, {"id": "scanner-a37e2a7b81454995", "name": "Insecure pattern 'direct_innerhtml_assignment' in mobile.html:581", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in mobile.html:581"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-19ff507121d988f1", "name": "Insecure pattern 'direct_innerhtml_assignment' in login.html:261", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in login.html:261"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-9ab36174d70a4079", "name": "Insecure pattern 'direct_innerhtml_assignment' in projects.html:305", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in projects.html:305"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-a04acd90ed3bfd1d", "name": "Insecure pattern 'insert_adjacent_html' in projects.html:458", "shortDescription": {"text": "Insecure pattern 'insert_adjacent_html' in projects.html:458"}, "fullDescription": {"text": "Found a known-risky pattern (insert_adjacent_html). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-c9586dac2ef362eb", "name": "Insecure pattern 'direct_innerhtml_assignment' in reset-password.html:315", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in reset-password.html:315"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-52f7fe15d7867f5f", "name": "Insecure pattern 'direct_innerhtml_assignment' in test-i18n.html:140", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in test-i18n.html:140"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-330cc4196bf19a79", "name": "Insecure pattern 'cors_wildcard' in server.js:564", "shortDescription": {"text": "Insecure pattern 'cors_wildcard' in server.js:564"}, "fullDescription": {"text": "Found a known-risky pattern (cors_wildcard). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-21ef5e8fa6b0a509", "name": "Insecure pattern 'direct_innerhtml_assignment' in desktop.html:764", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in desktop.html:764"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-64a22904e5904e7a", "name": "Insecure pattern 'direct_innerhtml_assignment' in contact.html:295", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in contact.html:295"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5c39fd1f35e2f469", "name": "Insecure pattern 'direct_innerhtml_assignment' in signup.html:351", "shortDescription": {"text": "Insecure pattern 'direct_innerhtml_assignment' in signup.html:351"}, "fullDescription": {"text": "Found a known-risky pattern (direct_innerhtml_assignment). Review and replace if possible."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-6372cebde0220094", "name": "No auth library detected", "shortDescription": {"text": "No auth library detected"}, "fullDescription": {"text": "The scanner did not find any standard auth library (JWT, OAuth, NextAuth, Auth0, etc.). The repo has auth/admin/session surface indicators, so auth may live in custom code, in a separate service, or be missing."}, "properties": {"scanner": "scanner-primary", "layer": "security", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-8bfa3acf56820967", "name": "Very large file: server.js (1319 lines)", "shortDescription": {"text": "Very large file: server.js (1319 lines)"}, "fullDescription": {"text": "Files with >800 lines often hide complexity hotspots and discourage tests."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-6893a6c8b0861585", "name": "Very low test-to-source ratio", "shortDescription": {"text": "Very low test-to-source ratio"}, "fullDescription": {"text": "0 test file(s) for 3 source file(s) (ratio 0.00). Consider adding integration or unit tests for critical paths."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-141b30a41e03817b", "name": "No license file detected", "shortDescription": {"text": "No license file detected"}, "fullDescription": {"text": "No LICENSE/COPYING/NOTICE file was found. Generated repositories often omit licensing, which blocks reuse and automated intake."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-faccb9061e9b52a0", "name": "No README detected", "shortDescription": {"text": "No README detected"}, "fullDescription": {"text": "No README file was found. Generated repos without README context are hard to operate, validate, or safely hand off."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-3ab5d313dda8e5f9", "name": "Debug logging residue appears in source files", "shortDescription": {"text": "Debug logging residue appears in source files"}, "fullDescription": {"text": "Found 26 console/debugger/print-style debug statements in non-test source. This is a common fast-generation residue before production cleanup."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}, {"id": "scanner-b9088664ace7f748", "name": "Composite production-readiness gap", "shortDescription": {"text": "Composite production-readiness gap"}, "fullDescription": {"text": "Multiple low-cost hardening controls are missing together: license, ci, tests, operator-readme. Opus verification showed these co-occurring gaps are a better readiness signal than reading each flag in isolation."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-118d9c0720b06f5e", "name": "Commented-code block (5 lines) in server.js:1247", "shortDescription": {"text": "Commented-code block (5 lines) in server.js:1247"}, "fullDescription": {"text": "A long run of `//` or `#` lines usually means abandoned code. Delete or move to git history. Keeps the canvas + dead-code detection honest."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "info", "confidence": 1.0}}, {"id": "scanner-532530c382fc72eb", "name": "`fetch()` without try/.catch or AbortSignal \u2014 server.js:263", "shortDescription": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server.js:263"}, "fullDescription": {"text": "Bare `fetch(...)` will throw an unhandled rejection on network failure. Wrap in try/catch, attach a `.catch(...)`, or pass an AbortSignal with a timeout."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "medium", "confidence": 1.0}}, {"id": "scanner-5fa5af25316da646", "name": "16 env vars used in code but missing from .env.example", "shortDescription": {"text": "16 env vars used in code but missing from .env.example"}, "fullDescription": {"text": "Drift between code and config docs. The first few: `BREVO_API_EXPIRY_DAYS`, `BREVO_API_KEY`, `BREVO_FROM`, `BREVO_KEEPALIVE_TO`, `GMAIL_APP_PASSWORD`, `GMAIL_USER`, `LOCK_DURATION_MS`, `MAX_LOGIN_ATTEMPTS` + 8 more. Add them (with a placeholder/comment) to .env.example so onboarding doesn't break."}, "properties": {"scanner": "scanner-primary", "layer": "quality", "severity": "low", "confidence": 1.0}}]}}, "automationDetails": {"id": "repobility/26600"}, "properties": {"repository": "IMTDGo/WebPhoto", "repoUrl": "https://github.com/IMTDGo/WebPhoto", "branch": "main"}, "results": [{"ruleId": "scanner-e6c7afc57d4527eb", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 server.js:72"}, "properties": {"repobilityId": "a9deebb5fdc93edc", "scanner": "scanner-primary", "fingerprint": "e6c7afc57d4527eb", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-8ba8d8186e719869", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 seed.js:34"}, "properties": {"repobilityId": "9e9ae1b5c1626834", "scanner": "scanner-primary", "fingerprint": "8ba8d8186e719869", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-1e5dfe63b8b48700", "level": "note", "message": {"text": "Stray `console.log` in TS/JS \u2014 add-dev-account.js:13"}, "properties": {"repobilityId": "d93d235e2308ac15", "scanner": "scanner-primary", "fingerprint": "1e5dfe63b8b48700", "layer": "frontend", "severity": "low", "confidence": 1.0, "tags": ["frontend-quality", "fq.console-leak"]}}, {"ruleId": "scanner-a37e2a7b81454995", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in mobile.html:581"}, "properties": {"repobilityId": "39c1e01516c2959e", "scanner": "scanner-primary", "fingerprint": "a37e2a7b81454995", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "mobile.html"}, "region": {"startLine": 581}}}]}, {"ruleId": "scanner-19ff507121d988f1", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in login.html:261"}, "properties": {"repobilityId": "617b51c994b02988", "scanner": "scanner-primary", "fingerprint": "19ff507121d988f1", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "login.html"}, "region": {"startLine": 261}}}]}, {"ruleId": "scanner-9ab36174d70a4079", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in projects.html:305"}, "properties": {"repobilityId": "198cb1a82f07b312", "scanner": "scanner-primary", "fingerprint": "9ab36174d70a4079", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "projects.html"}, "region": {"startLine": 305}}}]}, {"ruleId": "scanner-a04acd90ed3bfd1d", "level": "warning", "message": {"text": "Insecure pattern 'insert_adjacent_html' in projects.html:458"}, "properties": {"repobilityId": "81bbc5135db925a9", "scanner": "scanner-primary", "fingerprint": "a04acd90ed3bfd1d", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "insert_adjacent_html"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "projects.html"}, "region": {"startLine": 458}}}]}, {"ruleId": "scanner-c9586dac2ef362eb", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in reset-password.html:315"}, "properties": {"repobilityId": "1e2b9718a5c413bc", "scanner": "scanner-primary", "fingerprint": "c9586dac2ef362eb", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "reset-password.html"}, "region": {"startLine": 315}}}]}, {"ruleId": "scanner-52f7fe15d7867f5f", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in test-i18n.html:140"}, "properties": {"repobilityId": "b3de69ffb31ab653", "scanner": "scanner-primary", "fingerprint": "52f7fe15d7867f5f", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "test-i18n.html"}, "region": {"startLine": 140}}}]}, {"ruleId": "scanner-330cc4196bf19a79", "level": "warning", "message": {"text": "Insecure pattern 'cors_wildcard' in server.js:564"}, "properties": {"repobilityId": "0d9bca6c0839725e", "scanner": "scanner-primary", "fingerprint": "330cc4196bf19a79", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "cors_wildcard"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "server.js"}, "region": {"startLine": 564}}}]}, {"ruleId": "scanner-21ef5e8fa6b0a509", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in desktop.html:764"}, "properties": {"repobilityId": "81d7af84c93732f0", "scanner": "scanner-primary", "fingerprint": "21ef5e8fa6b0a509", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "desktop.html"}, "region": {"startLine": 764}}}]}, {"ruleId": "scanner-64a22904e5904e7a", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in contact.html:295"}, "properties": {"repobilityId": "4dcf46521649b98a", "scanner": "scanner-primary", "fingerprint": "64a22904e5904e7a", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "contact.html"}, "region": {"startLine": 295}}}]}, {"ruleId": "scanner-5c39fd1f35e2f469", "level": "warning", "message": {"text": "Insecure pattern 'direct_innerhtml_assignment' in signup.html:351"}, "properties": {"repobilityId": "bedfcd9df8b23275", "scanner": "scanner-primary", "fingerprint": "5c39fd1f35e2f469", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["owasp", "direct_innerhtml_assignment"]}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "signup.html"}, "region": {"startLine": 351}}}]}, {"ruleId": "scanner-6372cebde0220094", "level": "warning", "message": {"text": "No auth library detected"}, "properties": {"repobilityId": "a5b6035a5bbf8054", "scanner": "scanner-primary", "fingerprint": "6372cebde0220094", "layer": "security", "severity": "medium", "confidence": 1.0, "tags": ["coverage", "auth"]}}, {"ruleId": "scanner-8bfa3acf56820967", "level": "note", "message": {"text": "Very large file: server.js (1319 lines)"}, "properties": {"repobilityId": "1479ba50e708c5c1", "scanner": "scanner-primary", "fingerprint": "8bfa3acf56820967", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["complexity"]}}, {"ruleId": "scanner-6893a6c8b0861585", "level": "warning", "message": {"text": "Very low test-to-source ratio"}, "properties": {"repobilityId": "54a7de3f06314bf0", "scanner": "scanner-primary", "fingerprint": "6893a6c8b0861585", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["tests", "coverage"]}}, {"ruleId": "scanner-141b30a41e03817b", "level": "note", "message": {"text": "No license file detected"}, "properties": {"repobilityId": "7a31ed6582f5d9a0", "scanner": "scanner-primary", "fingerprint": "141b30a41e03817b", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["license", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-faccb9061e9b52a0", "level": "note", "message": {"text": "No README detected"}, "properties": {"repobilityId": "ce06a51e55d16cec", "scanner": "scanner-primary", "fingerprint": "faccb9061e9b52a0", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["docs", "readme", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-3ab5d313dda8e5f9", "level": "note", "message": {"text": "Debug logging residue appears in source files"}, "properties": {"repobilityId": "9c572a0eab379def", "scanner": "scanner-primary", "fingerprint": "3ab5d313dda8e5f9", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["debug", "cleanup", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-b9088664ace7f748", "level": "warning", "message": {"text": "Composite production-readiness gap"}, "properties": {"repobilityId": "b8316b778ee14e13", "scanner": "scanner-primary", "fingerprint": "b9088664ace7f748", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["production-readiness", "repo-hardening", "generated-repo-pattern"]}}, {"ruleId": "scanner-118d9c0720b06f5e", "level": "none", "message": {"text": "Commented-code block (5 lines) in server.js:1247"}, "properties": {"repobilityId": "0f1899582fe1d6c1", "scanner": "scanner-primary", "fingerprint": "118d9c0720b06f5e", "layer": "quality", "severity": "info", "confidence": 1.0, "tags": ["integrity", "commented-code", "dead-code"]}}, {"ruleId": "scanner-532530c382fc72eb", "level": "warning", "message": {"text": "`fetch()` without try/.catch or AbortSignal \u2014 server.js:263"}, "properties": {"repobilityId": "bc0802bba087e8e3", "scanner": "scanner-primary", "fingerprint": "532530c382fc72eb", "layer": "quality", "severity": "medium", "confidence": 1.0, "tags": ["integrity", "fragile-runtime", "robustness"]}}, {"ruleId": "scanner-5fa5af25316da646", "level": "note", "message": {"text": "16 env vars used in code but missing from .env.example"}, "properties": {"repobilityId": "e0919a3f6a45e8c2", "scanner": "scanner-primary", "fingerprint": "5fa5af25316da646", "layer": "quality", "severity": "low", "confidence": 1.0, "tags": ["integrity", "config-drift"]}}]}]}