{"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": "GHSA-58qx-3vcg-4xpx", "name": "ws: GHSA-58qx-3vcg-4xpx", "shortDescription": {"text": "ws: GHSA-58qx-3vcg-4xpx"}, "fullDescription": {"text": "ws: Uninitialized memory disclosure"}, "properties": {"scanner": "osv-scanner", "category": "dependency", "severity": "medium", "confidence": 0.88, "cwe": "", "owasp": ""}}, {"id": "ERR002", "name": "[ERR002] Empty Catch Block: Empty catch blocks hide errors.", "shortDescription": {"text": "[ERR002] Empty Catch Block: Empty catch blocks hide errors."}, "fullDescription": {"text": "Log the error or rethrow it. Use console.error() at minimum."}, "properties": {"scanner": "repobility-threat-engine", "category": "error_handling", "severity": "medium", "confidence": 0.45, "cwe": "", "owasp": ""}}, {"id": "SEC136", "name": "[SEC136] AI-typical over-broad exception handler swallowing all errors: Catch-all exception block that silently returns ", "shortDescription": {"text": "[SEC136] AI-typical over-broad exception handler swallowing all errors: Catch-all exception block that silently returns success or no-ops. AI agents reach for this pattern when a flaky test or an unfamiliar API throws \u2014 wrap, swallow, retur"}, "fullDescription": {"text": "Catch the specific exception type, log at error level with full exception info, and return a failure-shaped result. If the operation is genuinely best-effort, log at warning and document why in a comment so the next reader (or scanner) knows."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "medium", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "DEPCUR-NPM", "name": "npm package `jsdom` is 2 major version(s) behind (27.4.0 -> 29.1.1)", "shortDescription": {"text": "npm package `jsdom` is 2 major version(s) behind (27.4.0 -> 29.1.1)"}, "fullDescription": {"text": "`jsdom` is pinned/resolved at 27.4.0 but the latest stable release on the npm registry is 29.1.1 (2 major version(s) behind). Outdated dependencies accumulate unpatched bugs and make future security upgrades harder. This is the version-currency signal Dependabot version-update PRs raise."}, "properties": {"scanner": "repobility-dependency-currency", "category": "dependency", "severity": "medium", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "CORE_LARGE_FILES", "name": "Average file size is 680 lines (recommend <300)", "shortDescription": {"text": "Average file size is 680 lines (recommend <300)"}, "fullDescription": {"text": "Refactor large files by extracting related functions into separate modules. Target files with 300+ lines first. Use the Single Responsibility Principle \u2014 each module should have one clear purpose."}, "properties": {"scanner": "repobility-core", "category": "quality", "severity": "medium", "confidence": null, "cwe": "", "owasp": ""}}, {"id": "SEC029", "name": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled ", "shortDescription": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes e"}, "fullDescription": {"text": "Validate the URL against an allowlist BEFORE fetching:\n  ALLOWED = {'images.example.com', 'cdn.example.com'}\n  host = urlparse(url).hostname\n  if host not in ALLOWED: abort(400)\nOr use a server-side proxy (Imgproxy / serve-files-only-from-S3) that isolates outbound network access from the request handler.\nBlock private CIDRs explicitly: 10/8, 172.16/12, 192.168/16, 169.254/16."}, "properties": {"scanner": "repobility-threat-engine", "category": "ssrf", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "MINED115", "name": "Action `actions/setup-node` pinned to mutable ref `@v6`", "shortDescription": {"text": "Action `actions/setup-node` pinned to mutable ref `@v6`"}, "fullDescription": {"text": "`uses: actions/setup-node@v6` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-actions/changed-files compromise (2025) instantly affect ~23K repos. Pin to a 40-char commit SHA + lock with Dependabot or renovate."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}]}}, "automationDetails": {"id": "repobility/850"}, "properties": {"repository": "leonardomso/33-js-concepts", "repoUrl": "https://github.com/leonardomso/33-js-concepts", "branch": "master"}, "results": [{"ruleId": "GHSA-58qx-3vcg-4xpx", "level": "warning", "message": {"text": "ws: GHSA-58qx-3vcg-4xpx"}, "properties": {"repobilityId": 76813, "scanner": "osv-scanner", "fingerprint": "1b788fa8525382946c739270c1849aaa868327cf2c4216daf211eef3de5db45b", "category": "dependency", "severity": "medium", "confidence": 0.88, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"match": "", "aliases": ["CVE-2026-45736"], "package": "ws", "rule_id": "GHSA-58qx-3vcg-4xpx", "scanner": "osv-scanner", "correlation_key": "vuln|ws|CVE-2026-45736|package-lock.json"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package-lock.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "ERR002", "level": "warning", "message": {"text": "[ERR002] Empty Catch Block: Empty catch blocks hide errors."}, "properties": {"repobilityId": 76812, "scanner": "repobility-threat-engine", "fingerprint": "2deb0331d44d2d713b6ace6341dd3a36079c5182c1f6ce877d0cd7bf85676cd3", "category": "error_handling", "severity": "medium", "confidence": 0.45, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Pattern matched with no mitigating context found | [R34 auto-suppress: documentation/example path]", "evidence": {"match": "catch (_error) {}", "reason": "Pattern matched with no mitigating context found | [R34 auto-suppress: documentation/example path]", "rule_id": "ERR002", "scanner": "repobility-threat-engine", "confidence": 0.45, "correlation_key": "fp|2deb0331d44d2d713b6ace6341dd3a36079c5182c1f6ce877d0cd7bf85676cd3"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/schema-inject.js"}, "region": {"startLine": 67}}}]}, {"ruleId": "SEC136", "level": "warning", "message": {"text": "[SEC136] AI-typical over-broad exception handler swallowing all errors: Catch-all exception block that silently returns success or no-ops. AI agents reach for this pattern when a flaky test or an unfamiliar API throws \u2014 wrap, swallow, return success. Real bugs are masked, observability is destroyed, and callers think the operation worked. CWE-396 (improperly-generalized exception). Distinct from intentional fallback because there's no log line and the success value is fabricated."}, "properties": {"repobilityId": 76811, "scanner": "repobility-threat-engine", "fingerprint": "1bd699bccb933f516e62c1af015b605db3197a6da093ad565adb4529c33457f8", "category": "quality", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "} catch (_error) {\n      return [];\n    }", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC136", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|1bd699bccb933f516e62c1af015b605db3197a6da093ad565adb4529c33457f8"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/schema-inject.js"}, "region": {"startLine": 239}}}]}, {"ruleId": "DEPCUR-NPM", "level": "warning", "message": {"text": "npm package `jsdom` is 2 major version(s) behind (27.4.0 -> 29.1.1)"}, "properties": {"repobilityId": 76809, "scanner": "repobility-dependency-currency", "fingerprint": "f3c79e3c335ab967a0457b204072c1b3e20960ef21b1989251f70c1dab40e20c", "category": "dependency", "severity": "medium", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"gap": "2 major version(s) behind", "signal": "currency", "cwe_ids": [], "package": "jsdom", "scanner": "repobility-dependency-currency", "ecosystem": "npm", "languages": ["javascript"], "latest_version": "29.1.1", "correlation_key": "fp|f3c79e3c335ab967a0457b204072c1b3e20960ef21b1989251f70c1dab40e20c", "current_version": "27.4.0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "package.json"}, "region": {"startLine": 1}}}]}, {"ruleId": "CORE_LARGE_FILES", "level": "warning", "message": {"text": "Average file size is 680 lines (recommend <300)"}, "properties": {"repobilityId": 76806, "scanner": "repobility-core", "fingerprint": "64409cccdc6c943289d27f568cd3f21920cfd6e8caf371706c550e7015164376", "category": "quality", "severity": "medium", "confidence": null, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"rule_id": "CORE_LARGE_FILES", "scanner": "repobility-core", "correlation_key": "fp|64409cccdc6c943289d27f568cd3f21920cfd6e8caf371706c550e7015164376"}}}, {"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": 76810, "scanner": "repobility-threat-engine", "fingerprint": "6fc3542925413a1adece92ad8c6f6b9ec546c1b5eda7994f4f993614821a5210", "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|6fc3542925413a1adece92ad8c6f6b9ec546c1b5eda7994f4f993614821a5210"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/schema-inject.js"}, "region": {"startLine": 55}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "Action `actions/setup-node` pinned to mutable ref `@v6`"}, "properties": {"repobilityId": 76808, "scanner": "repobility-supply-chain", "fingerprint": "3a3e6e4e166be445db581b2c6423d46c1fa1b4db2ea4fad94288230a93082ac0", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|3a3e6e4e166be445db581b2c6423d46c1fa1b4db2ea4fad94288230a93082ac0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/tests.yml"}, "region": {"startLine": 18}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "Action `actions/checkout` pinned to mutable ref `@v6`"}, "properties": {"repobilityId": 76807, "scanner": "repobility-supply-chain", "fingerprint": "bd2f21e9ee98be741c1c9fa434760756c1b424d5b1d68bdf9c9543e1bf8ed8a0", "category": "dependency", "severity": "high", "confidence": 0.9, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"mined": true, "mining": {"slug": "gha-mutable-ref", "owasp": "A08:2021", "cwe_ids": ["CWE-829"], "languages": ["yaml"], "observations_count": 0}, "scanner": "repobility-supply-chain", "correlation_key": "fp|bd2f21e9ee98be741c1c9fa434760756c1b424d5b1d68bdf9c9543e1bf8ed8a0"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/tests.yml"}, "region": {"startLine": 15}}}]}]}]}