Source-code level security scanner. Walks decompiled APK source and detects security issues mapped to OWASP Mobile Top 10 (2024).
| 6 | |
| 7 | |
| 8 | class CodeScanner: |
| 9 | """ |
| 10 | Source-code level security scanner. Walks decompiled APK source and |
| 11 | detects security issues mapped to OWASP Mobile Top 10 (2024). |
| 12 | """ |
| 13 | |
| 14 | SCAN_EXTENSIONS = (".java", ".kt", ".xml", ".js") |
| 15 | |
| 16 | def __init__(self, source_path: str): |
| 17 | self.source_path = source_path |
| 18 | |
| 19 | # ------------------------------------------------------------------ |
| 20 | # Public API |
| 21 | # ------------------------------------------------------------------ |
| 22 | |
| 23 | def scan_all(self) -> list: |
| 24 | findings = [] |
| 25 | findings += self.check_crypto() |
| 26 | findings += self.check_webview() |
| 27 | findings += self.check_ssl() |
| 28 | findings += self.check_dynamic_code() |
| 29 | findings += self.check_data_storage() |
| 30 | findings += self.check_logging() |
| 31 | findings += self.check_intent_issues() |
| 32 | findings += self.check_zip_traversal() |
| 33 | findings.sort(key=lambda f: SEVERITY_ORDER.get(f["severity"], 99)) |
| 34 | return findings |
| 35 | |
| 36 | # ------------------------------------------------------------------ |
| 37 | # Crypto |
| 38 | # ------------------------------------------------------------------ |
| 39 | |
| 40 | def check_crypto(self) -> list: |
| 41 | checks = [ |
| 42 | { |
| 43 | "id": "CRYPTO_ECB_MODE", |
| 44 | "title": "ECB Mode Encryption", |
| 45 | "severity": "CRITICAL", |
| 46 | "owasp": "M10: Insufficient Cryptography", |
| 47 | "description": ( |
| 48 | "ECB (Electronic Codebook) mode encrypts identical plaintext blocks " |
| 49 | "to identical ciphertext, leaking data patterns. Attackers can " |
| 50 | "detect and manipulate encrypted data without the key." |
| 51 | ), |
| 52 | "pattern": r'Cipher\.getInstance\s*\(.*ECB', |
| 53 | }, |
| 54 | { |
| 55 | "id": "CRYPTO_HARDCODED_KEY", |
| 56 | "title": "Hardcoded Cryptographic Key", |
| 57 | "severity": "CRITICAL", |
| 58 | "owasp": "M1: Improper Credential Usage", |
| 59 | "description": ( |
| 60 | "A cryptographic key is hardcoded as a string literal in " |
| 61 | "SecretKeySpec. Any attacker who decompiles the APK can extract " |
| 62 | "the key and decrypt all protected data." |
| 63 | ), |
| 64 | "pattern": r'new\s+SecretKeySpec\s*\(\s*["\']', |
| 65 | }, |