{"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": "SEC046", "name": "[SEC046] Client-side open redirect \u2014 window.location = server-supplied URL: Assigning window.location from a server-supp", "shortDescription": {"text": "[SEC046] Client-side open redirect \u2014 window.location = server-supplied URL: Assigning window.location from a server-supplied URL trusts the server endpoint to never return a hostile destination. If that endpoint is ever subverted (compromis"}, "fullDescription": {"text": "Validate the URL is same-origin or on an explicit allowlist before assignment:\n  const u = new URL(serverUrl, location.href);\n  if (u.origin !== location.origin && !ALLOWED.includes(u.host)) return;\n  location.assign(u);\nEven better: have the server return a path (/checkout/done) instead of a full URL, and only allow same-origin navigation."}, "properties": {"scanner": "repobility-threat-engine", "category": "open_redirect", "severity": "medium", "confidence": 1.0, "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": "SEC006", "name": "[SEC006] XSS Risk: Direct HTML injection without sanitization.", "shortDescription": {"text": "[SEC006] XSS Risk: Direct HTML injection without sanitization."}, "fullDescription": {"text": "Use textContent instead of innerHTML. Sanitize with DOMPurify."}, "properties": {"scanner": "repobility-threat-engine", "category": "injection", "severity": "low", "confidence": 0.4, "cwe": "", "owasp": ""}}, {"id": "CORE_NO_LICENSE", "name": "No LICENSE file", "shortDescription": {"text": "No LICENSE file"}, "fullDescription": {"text": "Add a LICENSE file to your repository. Use choosealicense.com to pick the right license (MIT for permissive, Apache 2.0 for patent protection, GPL for copyleft)."}, "properties": {"scanner": "repobility-core", "category": "documentation", "severity": "low", "confidence": null, "cwe": "", "owasp": ""}}, {"id": "MINED083", "name": "[MINED083] Java Thread Start: Raw thread creation. Should use ExecutorService for managed pool.", "shortDescription": {"text": "[MINED083] Java Thread Start: Raw thread creation. Should use ExecutorService for managed pool."}, "fullDescription": {"text": "Review and fix per the pattern semantics. See CWE-664 /  for context."}, "properties": {"scanner": "repobility-threat-engine", "category": "quality", "severity": "info", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "MINED115", "name": "[MINED115] Action `peter-evans/create-or-update-comment` pinned to mutable ref `@v2`: `uses: peter-evans/create-or-updat", "shortDescription": {"text": "[MINED115] Action `peter-evans/create-or-update-comment` pinned to mutable ref `@v2`: `uses: peter-evans/create-or-update-comment@v2` resolves at workflow-run time. Tags and branches can be re-pushed by the action owner; that made the tj-ac"}, "fullDescription": {"text": "Replace with: `uses: peter-evans/create-or-update-comment@<40-char-sha>  # v2` and let Dependabot bump it on a scheduled cadence."}, "properties": {"scanner": "repobility-supply-chain", "category": "dependency", "severity": "high", "confidence": 0.9, "cwe": "", "owasp": ""}}, {"id": "SEC029", "name": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled ", "shortDescription": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input: Outbound HTTP request to a user-controlled URL without allowlist validation. Attackers can probe internal services (169.254.169.254 metadata, internal Kubernetes e"}, "fullDescription": {"text": "Validate the URL against an allowlist BEFORE fetching:\n  ALLOWED = {'images.example.com', 'cdn.example.com'}\n  host = urlparse(url).hostname\n  if host not in ALLOWED: abort(400)\nOr use a server-side proxy (Imgproxy / serve-files-only-from-S3) that isolates outbound network access from the request handler.\nBlock private CIDRs explicitly: 10/8, 172.16/12, 192.168/16, 169.254/16."}, "properties": {"scanner": "repobility-threat-engine", "category": "ssrf", "severity": "high", "confidence": 1.0, "cwe": "", "owasp": ""}}]}}, "automationDetails": {"id": "repobility/986"}, "properties": {"repository": "woodser/monero-java", "repoUrl": "https://github.com/woodser/monero-java", "branch": "master"}, "results": [{"ruleId": "SEC046", "level": "warning", "message": {"text": "[SEC046] Client-side open redirect \u2014 window.location = server-supplied URL: Assigning window.location from a server-supplied URL trusts the server endpoint to never return a hostile destination. If that endpoint is ever subverted (compromised admin, JSON injection, MITM on a webhook), users get redirected to a phishing site they trust because the original page is yours. CWE-601 (server-side OR client-side). Complement to server-side SEC030."}, "properties": {"repobilityId": 92912, "scanner": "repobility-threat-engine", "fingerprint": "484bc92004a3c6c21b011abe048d083b5957d1329350cde337bcfe3692d64186", "category": "open_redirect", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "window.location = getURL", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC046", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|484bc92004a3c6c21b011abe048d083b5957d1329350cde337bcfe3692d64186"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/javadocs/search-page.js"}, "region": {"startLine": 104}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 92915, "scanner": "repobility-ai-code-hygiene", "fingerprint": "71ab1afe5253cbfc5b74674008fc4a794e16dd2fefd3ba03b401571498839afa", "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": "src/main/java/monero/daemon/model/MoneroDaemonSyncInfo.java", "duplicate_line": 48, "correlation_key": "fp|71ab1afe5253cbfc5b74674008fc4a794e16dd2fefd3ba03b401571498839afa"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/main/java/monero/daemon/model/MoneroSubmitTxResult.java"}, "region": {"startLine": 101}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 92914, "scanner": "repobility-ai-code-hygiene", "fingerprint": "30f80819308f7b756c7fca29b7201dab207cf5930f27e3011bd961fc6443f9f9", "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": "src/main/java/monero/daemon/model/MoneroDaemonSyncInfo.java", "duplicate_line": 48, "correlation_key": "fp|30f80819308f7b756c7fca29b7201dab207cf5930f27e3011bd961fc6443f9f9"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/main/java/monero/daemon/model/MoneroHardForkInfo.java"}, "region": {"startLine": 63}}}]}, {"ruleId": "SEC006", "level": "note", "message": {"text": "[SEC006] XSS Risk: Direct HTML injection without sanitization."}, "properties": {"repobilityId": 92910, "scanner": "repobility-threat-engine", "fingerprint": "bd0c9a5fe679516ff4c51cdcb087415e5ffb5e174f416c79f89e6a3dbd6bfac4", "category": "injection", "severity": "low", "confidence": 0.4, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "No user-input source (request/query/fetch/URL) found \u2014 may be static content", "evidence": {"match": ".innerHTML = c", "reason": "No user-input source (request/query/fetch/URL) found \u2014 may be static content", "rule_id": "SEC006", "scanner": "repobility-threat-engine", "confidence": 0.4, "correlation_key": "code|injection|docs/javadocs/script.js|220|sec006"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/javadocs/script.js"}, "region": {"startLine": 220}}}]}, {"ruleId": "CORE_NO_LICENSE", "level": "note", "message": {"text": "No LICENSE file"}, "properties": {"repobilityId": 92909, "scanner": "repobility-core", "fingerprint": "9314e9238cd99885865b92490d1aaa96ca62b1390c9377878d5f3d99227e1c3c", "category": "documentation", "severity": "low", "confidence": null, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"rule_id": "CORE_NO_LICENSE", "scanner": "repobility-core", "correlation_key": "repo|documentation|core_no_license"}}}, {"ruleId": "MINED083", "level": "none", "message": {"text": "[MINED083] Java Thread Start: Raw thread creation. Should use ExecutorService for managed pool."}, "properties": {"repobilityId": 92913, "scanner": "repobility-threat-engine", "fingerprint": "d50ccb03aa9f95f5c385e66ef191d3dd10e84c7030a3d6938d8db9d334b96775", "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": "java-thread-start", "owasp": null, "cwe_ids": ["CWE-664"], "languages": ["java"], "precision": 1.0, "promoted_at": "2026-05-18T14:01:32.348131+00:00", "triaged_in_corpus": 12, "observations_count": 1591, "ai_coder_pattern_id": 128}, "scanner": "repobility-threat-engine", "correlation_key": "fp|d50ccb03aa9f95f5c385e66ef191d3dd10e84c7030a3d6938d8db9d334b96775"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "src/main/java/monero/common/TaskLooper.java"}, "region": {"startLine": 61}}}]}, {"ruleId": "MINED115", "level": "error", "message": {"text": "[MINED115] Action `peter-evans/create-or-update-comment` pinned to mutable ref `@v2`: `uses: peter-evans/create-or-update-comment@v2` 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": {"repobilityId": 92916, "scanner": "repobility-supply-chain", "fingerprint": "c798e167cc953f17fb1946aadf2edb23a55183bf855f7773d089426832af1743", "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|c798e167cc953f17fb1946aadf2edb23a55183bf855f7773d089426832af1743"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": ".github/workflows/label.yml"}, "region": {"startLine": 13}}}]}, {"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": 92911, "scanner": "repobility-threat-engine", "fingerprint": "07d4560832218d049b6812b87c78f85ef0ab15b874e0016acf39fd6d2c8337d8", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "URL(f", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|07d4560832218d049b6812b87c78f85ef0ab15b874e0016acf39fd6d2c8337d8"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "docs/javadocs/search-page.js"}, "region": {"startLine": 104}}}]}]}]}