The problem: a finding is not a fact about impact
An Android scanner can extract manifest flags and inspect bundled resources. It cannot, from those observations alone, establish that a sensitive operation is reachable, that an attacker can cross an authorization boundary, or that users have been harmed. I wanted evidence records from the Private research record to preserve that distinction.
The public ahmad-sec CLI is an experimental static-analysis project, not an exploitation framework or a certified penetration-testing service. Its scan command (private record) combines local APK metadata with manifest, exported-component, network-configuration and selected secret-pattern observations. The report builder then turns those observations into a structured JSON document for a reviewer.
One authorized input, two forms of output
The documented workflow starts with a local APK that the researcher owns or has explicit permission to assess. After installing the project in an isolated Python environment, the command below prints findings to the terminal and optionally creates a local JSON evidence file:
python3 -m venv .venv
source .venv/bin/activate
python -m pip install -e '.[dev]'
ahmad-sec apk scan /path/to/authorized.apk \
--json-out evidence-local.json
This syntax is taken from the repository's evidence report documentation (private record). It is an example command, not a record of a scan performed for this article. The --json-out option is optional; it does not upload a report, submit a vulnerability, or scan remote targets.
What an evidence record is designed to preserve
The report is explicitly labelled assessment_type: offline_static and uses schema version 1.0. The target summary records an APK filename, package name, SHA-256 value when supplied, and target SDK information; it avoids including the complete local host path. Its finding records distinguish a rule identifier, severity, confidence, observed component or resource, collection method, risk score and validation state.
The following is a short illustrative excerpt of field names and a configuration signal, not a complete generated report or proof of a real vulnerability:
{
"assessment_type": "offline_static",
"findings": [
{
"rule_id": "AST-SEC-001",
"severity": "MEDIUM",
"confidence": "HIGH",
"validation_status": "requires_manual_validation",
"evidence": {
"collection_method": "offline_apk_static_analysis",
"observation": "android:usesCleartextTraffic=\"true\""
}
}
]
}
The network rule (private record) reports the cleartext flag when it is explicitly enabled and a network-security configuration resource does not take precedence. That is a configuration observation. Whether the application actually sends sensitive information over HTTP requires separate, authorized investigation.
Stable identifiers without pretending to have CVEs
In the reporting implementation (private record), a finding's rule, title, component, source and original evidence are serialized in a predictable order and hashed to produce a short deterministic instance ID. Duplicate instance IDs are filtered, and observations are sorted consistently. Timestamps are intentionally excluded from the report structure, making equivalent inputs easier to compare between runs.
These IDs are local correlation aids—not CVE identifiers, exploit demonstrations, or externally verified security advisories. A change in the underlying evidence can change the identifier. Consistent formatting improves review, but it cannot make an untested security claim true.
Redaction and export safety are layers, not guarantees
Some potential credentials can be matched by pattern. The secret rules (private record) mask matched candidates in observations rather than printing the complete candidate; the JSON reporter applies additional masking against its known patterns. The implementation also normalizes certain archive paths and removes complete host paths from the target summary.
The writer uses exclusive file creation rather than silently overwriting an existing file, rejects a symbolic-link destination and requests owner-only file permissions on POSIX systems. Those are meaningful safeguards in the source code (private record), but they are not an assurance that every possible secret, data format or malicious APK will be handled safely. A report remains potentially sensitive and needs human review before sharing.
The repository includes tests for deterministic output, duplicate filtering, redaction of a synthetic key, private file permissions, non-overwrite behavior and symlink rejection (private record). These tests demonstrate intended behaviors in fixtures; this article does not claim a fresh production audit or a new verified vulnerability.
Turning a warning into an investigation decision
Consider two examples. An explicitly exported Android component is an entry point to review, but its reachability, required permissions and sensitive behavior still need examination. The component detector (private record) accordingly marks explicit exports as informational and records any declared permission for further assessment. Similarly, a cleartext-traffic flag may justify checking relevant traffic flows, yet the flag by itself is not evidence that sensitive data crossed the network in plaintext.
I would review each result in this order: confirm the APK and authorized assessment scope; reproduce the static observation; inspect affected code and permissions; test reachability and sensitive behavior only in an approved environment; assess the security consequence; and document a safe remediation and regression test if a real issue is validated. The research process (private record) explicitly separates observations, candidate risks, confirmed issues and remediated findings.
Evidence should help a reviewer decide what to verify next. It should never substitute for that verification.
What this case study actually establishes
The public implementation demonstrates an approach to structuring offline Android assessment observations, reducing some disclosure risks and making report comparison more reproducible. It also documents important limitations: selected secret-pattern scanning has incomplete coverage; configuration flags may not reflect real attack paths; and evidence requires contextual, authorized manual validation. This is a walkthrough of documented code and tests, not a claim that the toolkit has found exploitable issues in third-party apps.
Start with the evidence report builder (private record), then review its synthetic tests (private record) and schema documentation (private record). Never publish raw APKs, tokens or confidential research evidence.