{"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": "AIC003", "name": "Duplicated implementation block across source files", "shortDescription": {"text": "Duplicated implementation block across source files"}, "fullDescription": {"text": "Duplicated blocks are a common artifact when generated code is pasted or recreated instead of reused. They increase maintenance cost because every future bug fix must be found in multiple locations."}, "properties": {"scanner": "repobility-ai-code-hygiene", "category": "quality", "severity": "medium", "confidence": 0.86, "cwe": "", "owasp": ""}}, {"id": "SEC012", "name": "[SEC012] ZipSlip \u2014 Archive Path Traversal: Archive extraction without path validation allows writing files outside the t", "shortDescription": {"text": "[SEC012] ZipSlip \u2014 Archive Path Traversal: Archive extraction without path validation allows writing files outside the target directory."}, "fullDescription": {"text": "Validate extracted paths with os.path.realpath() and ensure they stay within the target directory."}, "properties": {"scanner": "repobility-threat-engine", "category": "path_traversal", "severity": "medium", "confidence": 1.0, "cwe": "", "owasp": ""}}, {"id": "SEC029", "name": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 11 more): Same pattern found in 11 addi", "shortDescription": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 11 more): Same pattern found in 11 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": "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": "info", "confidence": 0.15, "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.15, "cwe": "", "owasp": ""}}, {"id": "SEC013", "name": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows ", "shortDescription": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "fullDescription": {"text": "Use os.path.realpath() and verify the path starts with your expected base directory. Use secure_filename() for uploads."}, "properties": {"scanner": "repobility-threat-engine", "category": "path_traversal", "severity": "high", "confidence": 0.8, "cwe": "", "owasp": ""}}, {"id": "CORE_NO_TESTS", "name": "No test files found", "shortDescription": {"text": "No test files found"}, "fullDescription": {"text": "Add a test directory (tests/ or __tests__/) with unit tests for core functionality. Use pytest (Python), Jest (JS/TS), or go test (Go). Start with tests for critical business logic and security-sensitive functions."}, "properties": {"scanner": "repobility-core", "category": "testing", "severity": "high", "confidence": null, "cwe": "", "owasp": ""}}]}}, "automationDetails": {"id": "repobility/143"}, "properties": {"repository": "google-ai-edge/gallery", "repoUrl": "https://github.com/google-ai-edge/gallery.git", "branch": "main"}, "results": [{"ruleId": "AIC003", "level": "warning", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 4583, "scanner": "repobility-ai-code-hygiene", "fingerprint": "6591f25fd7e0e3a09e70894a1913b8d393dffe78a217b11af11da68ee1b7ec83", "category": "quality", "severity": "medium", "confidence": 0.86, "triageState": "fixed", "verdict": "confirmed", "isResolved": true, "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/SmallFilledTonalButton.kt", "duplicate_line": 28, "correlation_key": "fp|6591f25fd7e0e3a09e70894a1913b8d393dffe78a217b11af11da68ee1b7ec83"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/SmallOutlinedButton.kt"}, "region": {"startLine": 28}}}]}, {"ruleId": "SEC012", "level": "warning", "message": {"text": "[SEC012] ZipSlip \u2014 Archive Path Traversal: Archive extraction without path validation allows writing files outside the target directory."}, "properties": {"repobilityId": 3696, "scanner": "repobility-threat-engine", "fingerprint": "7939519ad275a8b9a13356c31e9279547bfdedd1ec6f390dd62acd1f5a81e803", "category": "path_traversal", "severity": "medium", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "zipEntry.name", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC012", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "code|path_traversal|token|283|sec012"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/worker/DownloadWorker.kt"}, "region": {"startLine": 283}}}]}, {"ruleId": "AIC003", "level": "warning", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3693, "scanner": "repobility-ai-code-hygiene", "fingerprint": "974698b3c0568ff2ccd33ea5d371836171fdea865b598d3f34fed1087b2a3246", "category": "quality", "severity": "medium", "confidence": 0.86, "triageState": "fixed", "verdict": "confirmed", "isResolved": true, "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": "Android/src/app/src/main/assets/skills/calculate-hash/scripts/index.js", "duplicate_line": 1, "correlation_key": "fp|974698b3c0568ff2ccd33ea5d371836171fdea865b598d3f34fed1087b2a3246"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "skills/built-in/calculate-hash/scripts/index.js"}, "region": {"startLine": 1}}}]}, {"ruleId": "AIC003", "level": "warning", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3692, "scanner": "repobility-ai-code-hygiene", "fingerprint": "9fd3df66434dbbe64d08770ca2e0df76160d3b4993ad1be7438496940521fe43", "category": "quality", "severity": "medium", "confidence": 0.86, "triageState": "fixed", "verdict": "confirmed", "isResolved": true, "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromUrlDialog.kt", "duplicate_line": 68, "correlation_key": "fp|9fd3df66434dbbe64d08770ca2e0df76160d3b4993ad1be7438496940521fe43"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/modelmanager/ModelImportDialog.kt"}, "region": {"startLine": 154}}}]}, {"ruleId": "AIC003", "level": "warning", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3691, "scanner": "repobility-ai-code-hygiene", "fingerprint": "0036dd4f56268ca888185bf2f41122709d5e660e8fa92fd7543d91ddaeb15b3e", "category": "quality", "severity": "medium", "confidence": 0.86, "triageState": "fixed", "verdict": "confirmed", "isResolved": true, "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AgentChatTaskModule.kt", "duplicate_line": 71, "correlation_key": "fp|0036dd4f56268ca888185bf2f41122709d5e660e8fa92fd7543d91ddaeb15b3e"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/llmsingleturn/LlmSingleTurnTaskModule.kt"}, "region": {"startLine": 49}}}]}, {"ruleId": "AIC003", "level": "warning", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3690, "scanner": "repobility-ai-code-hygiene", "fingerprint": "ac188a70a4311ae676213652360b56bfe935f4203fdf985f1845137d126ee9a3", "category": "quality", "severity": "medium", "confidence": 0.86, "triageState": "fixed", "verdict": "confirmed", "isResolved": true, "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/runtime/aicore/AICoreModelHelper.kt", "duplicate_line": 193, "correlation_key": "fp|ac188a70a4311ae676213652360b56bfe935f4203fdf985f1845137d126ee9a3"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/llmchat/LlmChatModelHelper.kt"}, "region": {"startLine": 206}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 8464, "scanner": "repobility-ai-code-hygiene", "fingerprint": "79ee0c12a64aa12ec15bc5416391a53556149b454dffee22e45cde4df48bb349", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/SmallFilledTonalButton.kt", "duplicate_line": 30, "correlation_key": "fp|79ee0c12a64aa12ec15bc5416391a53556149b454dffee22e45cde4df48bb349"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/SmallOutlinedButton.kt"}, "region": {"startLine": 30}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 8463, "scanner": "repobility-ai-code-hygiene", "fingerprint": "aa7eab9d91b0a963050ff6cb460c5ce4fb5760a4d2b669490c6b8412e9b518dd", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromFeaturedListBottomSheet.kt", "duplicate_line": 125, "correlation_key": "fp|aa7eab9d91b0a963050ff6cb460c5ce4fb5760a4d2b669490c6b8412e9b518dd"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/McpToolManagerBottomSheet.kt"}, "region": {"startLine": 82}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 8462, "scanner": "repobility-ai-code-hygiene", "fingerprint": "6081de00f47352294bc7b35cf1f9e868923eb20085532f6236fadfda76b7d033", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromFeaturedListBottomSheet.kt", "duplicate_line": 166, "correlation_key": "fp|6081de00f47352294bc7b35cf1f9e868923eb20085532f6236fadfda76b7d033"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/McpManagerBottomSheet.kt"}, "region": {"startLine": 202}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 8461, "scanner": "repobility-ai-code-hygiene", "fingerprint": "bcbe77857af5d9a9592d5f6ce99d7502144753c9b7914c1c43efa55bc5b3c896", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddMcpServerFromUrlDialog.kt", "duplicate_line": 244, "correlation_key": "fp|bcbe77857af5d9a9592d5f6ce99d7502144753c9b7914c1c43efa55bc5b3c896"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromLocalImportDialog.kt"}, "region": {"startLine": 125}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 4816, "scanner": "repobility-ai-code-hygiene", "fingerprint": "8d3106843fc7c3bf2e1d147ee980661d9e35382634eba32f94a9e24cd590aadf", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/modelmanager/GlobalModelManager.kt", "duplicate_line": 199, "correlation_key": "fp|8d3106843fc7c3bf2e1d147ee980661d9e35382634eba32f94a9e24cd590aadf"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/notifications/NotificationsScreen.kt"}, "region": {"startLine": 99}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 4588, "scanner": "repobility-ai-code-hygiene", "fingerprint": "5fdb2f7e8a2e7adef84b74531afd31a24b533428df21d6520b5b592dbddff0db", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromUrlDialog.kt", "duplicate_line": 68, "correlation_key": "fp|5fdb2f7e8a2e7adef84b74531afd31a24b533428df21d6520b5b592dbddff0db"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/modelmanager/ModelImportDialog.kt"}, "region": {"startLine": 155}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 4587, "scanner": "repobility-ai-code-hygiene", "fingerprint": "f819f0bde33ffd482b16fb819f1d5e6754442594e4c009155bcbc3ca77cce4d9", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AgentChatTaskModule.kt", "duplicate_line": 111, "correlation_key": "fp|f819f0bde33ffd482b16fb819f1d5e6754442594e4c009155bcbc3ca77cce4d9"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/llmsingleturn/LlmSingleTurnTaskModule.kt"}, "region": {"startLine": 53}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 4586, "scanner": "repobility-ai-code-hygiene", "fingerprint": "f13e2c0a23514e35e3857593943ca35cdbc3d3adfc5c4e1d73bdaa306fd8c5ce", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/llmchat/LlmChatTaskModule.kt", "duplicate_line": 52, "correlation_key": "fp|f13e2c0a23514e35e3857593943ca35cdbc3d3adfc5c4e1d73bdaa306fd8c5ce"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/llmsingleturn/LlmSingleTurnTaskModule.kt"}, "region": {"startLine": 32}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 4585, "scanner": "repobility-ai-code-hygiene", "fingerprint": "5c426ab75893c6a2da572f2585f07bd21de629073003ab6fbfdf62fb8c9b38bf", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/runtime/aicore/AICoreModelHelper.kt", "duplicate_line": 41, "correlation_key": "fp|5c426ab75893c6a2da572f2585f07bd21de629073003ab6fbfdf62fb8c9b38bf"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/llmchat/LlmChatModelHelper.kt"}, "region": {"startLine": 39}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 4584, "scanner": "repobility-ai-code-hygiene", "fingerprint": "f8ad7d81dd0a516f718c3d10f3fa5ef5a49d9e7fc552639df72069f84b14c84f", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/chat/ChatHistorySideSheet.kt", "duplicate_line": 147, "correlation_key": "fp|f8ad7d81dd0a516f718c3d10f3fa5ef5a49d9e7fc552639df72069f84b14c84f"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/chat/TextInputHistorySheet.kt"}, "region": {"startLine": 157}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3689, "scanner": "repobility-ai-code-hygiene", "fingerprint": "4b94878c4fbe614d81e2ea51a016af3cfc112d11377aad60606b1d29aaac589a", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromUrlDialog.kt", "duplicate_line": 68, "correlation_key": "fp|4b94878c4fbe614d81e2ea51a016af3cfc112d11377aad60606b1d29aaac589a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/home/SettingsDialog.kt"}, "region": {"startLine": 91}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3688, "scanner": "repobility-ai-code-hygiene", "fingerprint": "ebb2ca5819cc633bca6ce838033444baaff7deb17c99f10877887f5e98d0f176", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/mobileactions/MobileActionsScreen.kt", "duplicate_line": 206, "correlation_key": "fp|ebb2ca5819cc633bca6ce838033444baaff7deb17c99f10877887f5e98d0f176"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/textandvoiceinput/HoldToDictate.kt"}, "region": {"startLine": 47}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3687, "scanner": "repobility-ai-code-hygiene", "fingerprint": "6169e303895a43ad5d9507032b6abdbe286f4af9519a07a2d5437425e463cfed", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/modelitem/DeleteModelButton.kt", "duplicate_line": 46, "correlation_key": "fp|6169e303895a43ad5d9507032b6abdbe286f4af9519a07a2d5437425e463cfed"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/ui/common/modelitem/ModelItem.kt"}, "region": {"startLine": 399}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3686, "scanner": "repobility-ai-code-hygiene", "fingerprint": "02df98772210a3852e8e1411be5de749ebbe58c09221ffe125a50d519ce45fd9", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/mobileactions/MobileActionsScreen.kt", "duplicate_line": 203, "correlation_key": "fp|02df98772210a3852e8e1411be5de749ebbe58c09221ffe125a50d519ce45fd9"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/tinygarden/TinyGardenScreen.kt"}, "region": {"startLine": 115}}}]}, {"ruleId": "AIC003", "level": "note", "message": {"text": "Duplicated implementation block across source files"}, "properties": {"repobilityId": 3685, "scanner": "repobility-ai-code-hygiene", "fingerprint": "361d1f96842c10452bf6dc6714c45e671a63208b0e04738ac1cd29c6d3c1f94a", "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": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromLocalImportDialog.kt", "duplicate_line": 116, "correlation_key": "fp|361d1f96842c10452bf6dc6714c45e671a63208b0e04738ac1cd29c6d3c1f94a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromUrlDialog.kt"}, "region": {"startLine": 129}}}]}, {"ruleId": "SEC029", "level": "none", "message": {"text": "[SEC029] Server-Side Request Forgery (SSRF) \u2014 outbound HTTP from user input (and 11 more): Same pattern found in 11 additional files. Review if needed."}, "properties": {"repobilityId": 27987, "scanner": "repobility-threat-engine", "fingerprint": "6e6b1fa9aa37cd5353c53477b8935ccc1c8f42b61f420ebd0ceb44871ba243eb", "category": "ssrf", "severity": "info", "confidence": 0.2, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Deduplicated summary only: 11 additional occurrences found. The top occurrences remain visible as actionable findings.", "evidence": {"reason": "Deduplicated summary only: 11 additional occurrences found. The top occurrences remain visible as actionable findings.", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 0.2, "correlation_key": "fp|6e6b1fa9aa37cd5353c53477b8935ccc1c8f42b61f420ebd0ceb44871ba243eb"}}}, {"ruleId": "SEC015", "level": "none", "message": {"text": "[SEC015] Insecure Randomness for Security: Weak PRNG used in security-sensitive context. Output is predictable."}, "properties": {"repobilityId": 3695, "scanner": "repobility-threat-engine", "fingerprint": "736b43a81f0869955c188445a3ba414bf52a38d95fe5cc2003c434e43b1f5f4a", "category": "crypto", "severity": "info", "confidence": 0.15, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Weak PRNG appears to be used for non-security behavior (UI, sampling, demos, shuffling, or backoff), not for secrets", "evidence": {"match": "Math.random()", "reason": "Weak PRNG appears to be used for non-security behavior (UI, sampling, demos, shuffling, or backoff), not for secrets", "rule_id": "SEC015", "scanner": "repobility-threat-engine", "confidence": 0.15, "correlation_key": "code|crypto|token|75|sec015"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "skills/featured/restaurant-roulette/scripts/index.js"}, "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": 3694, "scanner": "repobility-threat-engine", "fingerprint": "1875a231b73091952a48cadcc2158048ee5b7075736854999ac917fd6c3d1bab", "category": "credential_exposure", "severity": "info", "confidence": 0.15, "triageState": "false_positive", "verdict": "likely_fp", "isResolved": true, "reason": "Log line appears to mention secret metadata or a redacted value rather than printing the secret", "evidence": {"match": "console.warn('GEMINI_API_KEY is missing. Calls to Gemini API will likely fail.')", "reason": "Log line appears to mention secret metadata or a redacted value rather than printing the secret", "rule_id": "SEC020", "scanner": "repobility-threat-engine", "confidence": 0.15, "correlation_key": "secret|token|3|console.warn gemini_api_key is missing. calls to gemini api will likely fail."}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "skills/featured/restaurant-roulette/scripts/index.js"}, "region": {"startLine": 36}}}]}, {"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": 27986, "scanner": "repobility-threat-engine", "fingerprint": "9f98bb9b4265ecbd92f59643f4745805decfe3e618c69eabced2671c6ffb2679", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "Url(\n        u", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|9f98bb9b4265ecbd92f59643f4745805decfe3e618c69eabced2671c6ffb2679"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/AddSkillFromFeaturedListBottomSheet.kt"}, "region": {"startLine": 114}}}]}, {"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": 27985, "scanner": "repobility-threat-engine", "fingerprint": "cb99cecbefd26efe30bdef6801ac1d1391c425ee020df5c9fe0d071c9991d74a", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "URL(u", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|cb99cecbefd26efe30bdef6801ac1d1391c425ee020df5c9fe0d071c9991d74a"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/common/Utils.kt"}, "region": {"startLine": 76}}}]}, {"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": 27984, "scanner": "repobility-threat-engine", "fingerprint": "06f0c0f4774bbceac6ab1a690ad0a68ad5bd78f2140cc211798160ba4432e33b", "category": "ssrf", "severity": "high", "confidence": 1.0, "triageState": "open", "verdict": "confirmed", "isResolved": false, "reason": "Pattern matched with no mitigating context found", "evidence": {"match": "URL(i", "reason": "Pattern matched with no mitigating context found", "rule_id": "SEC029", "scanner": "repobility-threat-engine", "confidence": 1.0, "correlation_key": "fp|06f0c0f4774bbceac6ab1a690ad0a68ad5bd78f2140cc211798160ba4432e33b"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/FcmMessagingService.kt"}, "region": {"startLine": 103}}}]}, {"ruleId": "SEC013", "level": "error", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "properties": {"repobilityId": 8465, "scanner": "repobility-threat-engine", "fingerprint": "16e7365f1b50d6225b9f9d8e2739223d1e6a644f8a65fbb7593b9185541b2b2b", "category": "path_traversal", "severity": "high", "confidence": 0.8, "triageState": "open", "verdict": "likely", "isResolved": false, "reason": "User-controlled input detected in file path construction", "evidence": {"match": "open(skillMdPath).use { input", "reason": "User-controlled input detected in file path construction", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.8, "correlation_key": "code|path_traversal|token|184|sec013"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/SkillManagerViewModel.kt"}, "region": {"startLine": 184}}}]}, {"ruleId": "SEC013", "level": "error", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "properties": {"repobilityId": 5790, "scanner": "repobility-threat-engine", "fingerprint": "e2f7f92d1490e6094e25e2cc2317ed9bab71feb208f3932416cb50e8f2da9aef", "category": "path_traversal", "severity": "high", "confidence": 0.8, "triageState": "fixed", "verdict": "likely", "isResolved": true, "reason": "User-controlled input detected in file path construction", "evidence": {"match": "open(skillMdPath).use { input", "reason": "User-controlled input detected in file path construction", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.8, "correlation_key": "code|path_traversal|token|178|sec013"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/SkillManagerViewModel.kt"}, "region": {"startLine": 178}}}]}, {"ruleId": "SEC013", "level": "error", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "properties": {"repobilityId": 4989, "scanner": "repobility-threat-engine", "fingerprint": "f1e44369e0700149ca03af1f34a23588a03220c326cca56ac8a488784afff09e", "category": "path_traversal", "severity": "high", "confidence": 0.8, "triageState": "fixed", "verdict": "likely", "isResolved": true, "reason": "User-controlled input detected in file path construction", "evidence": {"match": "open(skillMdPath).use { input", "reason": "User-controlled input detected in file path construction", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.8, "correlation_key": "code|path_traversal|token|197|sec013"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/SkillManagerViewModel.kt"}, "region": {"startLine": 197}}}]}, {"ruleId": "SEC013", "level": "error", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "properties": {"repobilityId": 4589, "scanner": "repobility-threat-engine", "fingerprint": "5c645bf95c031e9b2e59fef0aa953691aca4ad0bd0c0368d3fc8f85cba716c58", "category": "path_traversal", "severity": "high", "confidence": 0.8, "triageState": "fixed", "verdict": "likely", "isResolved": true, "reason": "User-controlled input detected in file path construction", "evidence": {"match": "open(skillMdPath).use { input", "reason": "User-controlled input detected in file path construction", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.8, "correlation_key": "code|path_traversal|token|201|sec013"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/SkillManagerViewModel.kt"}, "region": {"startLine": 201}}}]}, {"ruleId": "SEC013", "level": "error", "message": {"text": "[SEC013] Path Traversal \u2014 User Input in File Path: User-controlled input used in file path without sanitization. Allows reading arbitrary files."}, "properties": {"repobilityId": 3697, "scanner": "repobility-threat-engine", "fingerprint": "d8e50f61d84f809338e2b27fe341a188c32cd6ea0f6ba003f5a5512aaafb0695", "category": "path_traversal", "severity": "high", "confidence": 0.8, "triageState": "fixed", "verdict": "likely", "isResolved": true, "reason": "User-controlled input detected in file path construction", "evidence": {"match": "open(skillMdPath).use { input", "reason": "User-controlled input detected in file path construction", "rule_id": "SEC013", "scanner": "repobility-threat-engine", "confidence": 0.8, "correlation_key": "code|path_traversal|token|180|sec013"}}, "locations": [{"physicalLocation": {"artifactLocation": {"uri": "Android/src/app/src/main/java/com/google/ai/edge/gallery/customtasks/agentchat/SkillManagerViewModel.kt"}, "region": {"startLine": 180}}}]}, {"ruleId": "CORE_NO_TESTS", "level": "error", "message": {"text": "No test files found"}, "properties": {"repobilityId": 3684, "scanner": "repobility-core", "fingerprint": "0200e9918bc2a7bf9c116d0907e50ac3df640c758b93852cf1890ec6e14d870d", "category": "testing", "severity": "high", "confidence": null, "triageState": "open", "verdict": "", "isResolved": false, "reason": "", "evidence": {"rule_id": "CORE_NO_TESTS", "scanner": "repobility-core", "correlation_key": "repo|testing|core_no_tests"}}}]}]}