Most services that analyze an APK online return a verdict and little else. The verdict states that a file is malicious. It does not establish what the application does, which evidence supports the classification, or what an analyst should escalate.
This article documents the Droidwatch analysis pipeline end to end: the accepted inputs, the stages that execute on upload, every block of the resulting report, and the point at which static analysis stops producing usable evidence.
The analyst-side reasoning — how to work a suspicious sample rather than how the platform processes it — is covered separately in the APK triage workflow.
Accepted input formats
Five formats are accepted. All are Android except the last.
| Format | Description |
|---|---|
.apk |
Standard Android application package |
.aab |
Android App Bundle, the Play distribution format |
.xapk |
Split-APK container, common on third-party stores |
.dex |
Bare Dalvik executable, for pre-extracted bytecode |
.ipa |
iOS application archive — static analysis only |
Maximum file size is determined by plan: 150 MB without an account, 200 MB on Free, 500 MB on Pro, 750 MB on Team, and 1 GB on Enterprise. Production banking applications generally fall well below the Free ceiling; packages exceeding 500 MB are typically games.
Two submission paths exist. The browser upload handles single files. The API handles everything else and is documented below.
Analysis pipeline
A single submission triggers a 28-stage pipeline producing more than 25 independent analyses. The stages belong to one run rather than to separate products, which is material to interpretation: a finding produced by one stage can alter how a later stage scores the sample.
The stages fall into six areas. Identifying the area that produced a finding establishes how much weight that finding carries.
1. Package and identity
Manifest parsing, package name, version name and code, SHA-256, min_sdk, target_sdk, and the signing certificate chain. This area also performs the Google Play comparison: whether the package exists on Play and, if so, whether its certificate matches the certificate Play distributes.
A certificate mismatch is the highest-value single output of the pipeline. It reclassifies a sample from "suspicious application" to "confirmed repackaging", which is a distinct incident type with a distinct owner inside the organisation.
2. Bytecode
Deep DEX analysis via androguard: classes, methods, API usage, reflection, dynamic class loading, and the obfuscation posture of the build. Dropper behaviour surfaces here. An APK whose payload is retrieved after installation presents as unremarkable in every other area.
3. Native code and packaging
Shared objects, packer signatures, high-entropy assets, and any component shipped in the package that the manifest does not account for.
4. Family detection
YARA rules combined with heuristics. Family attribution is the most operationally useful single fact a report can carry, because it imports the existing body of knowledge on that family's infrastructure, targeting and behaviour.
5. Supply chain
Droidwatch fingerprints 87 third-party SDKs by signature and queries OSV.dev at analysis time for known vulnerabilities.
These are two separate measurements, and the distinction matters. OSV covers 12 of the 87. Advertising and attribution SDKs are closed-source and are not represented in public vulnerability databases. For the remaining 75, the platform establishes what the application contains but cannot establish whether a published CVE exists. Vendor claims of CVE coverage across proprietary mobile SDKs should be evaluated against the actual contents of public vulnerability databases. A separate module tracks approximately 120 privacy trackers.
This area produces findings on legitimate applications more often than any other, which is why application security teams run the platform against their own builds rather than only against suspected malware.
6. Infrastructure intelligence
Endpoint extraction, C2 identification, and encrypted configuration extraction where the sample permits it.
Machine-learning classifier
A classifier runs alongside the pipeline. Measured performance is F1 macro 0.9873 on a 1,661-sample holdout, trained on 6,642 samples from CICMalDroid 2020. The holdout size is quoted deliberately: an accuracy figure without a stated evaluation set is not a measurement.
The classifier contributes a signal to the verdict. It does not determine the verdict, and no finding in a report rests on the classifier alone.
Analysis duration
Measurements taken against production reports on 19 September 2026:
| Package size | Analysis time |
|---|---|
| 48 MB | 157 s |
| 97 MB | 503 s |
| 111 MB | 611 s |
| 165 MB | 595 s |
A 50 MB APK completes in two to five minutes. Packages above 100 MB average eight to ten minutes. Jobs transition through four states: queued, running, done, failed.
Earlier documentation stated 30 to 90 seconds. That figure was inaccurate and has been withdrawn.
Report structure
metadata
run_id, app_name, package, version_name, version_code, sha256, file_size, min_sdk, target_sdk, analyzed_at.
This is the block most frequently cited downstream. The combination of sha256 and analyzed_at establishes reproducibility: it identifies which build was examined and when, which is what an audit or a dispute six months later requires.
min_sdk warrants attention. An application targeting an obsolete API level is frequently doing so to remain outside a permission model that current Android versions enforce.
overview
score, verdict, and a severities distribution across info, low, medium, high and critical.
Droidwatch scores risk from 0 to 100, where a higher score indicates greater risk. Verdict bands are fixed:
| Verdict | Score | Definition |
|---|---|---|
Malicious |
65 and above | Identified family, or a capability set with no legitimate interpretation |
High Risk |
40–64 | Dangerous capabilities combined with identity anomalies; family unconfirmed |
Suspicious |
20–39 | Anomalies without a coherent malicious pattern — adware, or a poorly constructed legitimate application |
Benign |
Below 20 | Nothing beyond the norm for the application category |
A single scale is used throughout. The Score column in the public threat feed carries the same value, so a score of 63 in the feed corresponds to a score of 63 in a private report.
For triage, the severities distribution is frequently more informative than the composite score, because it describes the shape of the problem. Two critical findings and nothing else indicates a specific, explicable application. Forty medium findings and no critical findings generally indicates a legitimate application carrying technical debt. The two reports route to different teams.
sections
An array of { id, title, findings } containing the body of the analysis: permissions, components, certificate details, network configuration, extracted indicators, code analysis and supply chain. The certificate chain, network indicators and YARA matches are located within their respective sections rather than at the top level of the document.
Each finding carries its own supporting reasoning. This is the substantive difference between a report and a scanner verdict: the report identifies which component requests a given permission and what that permission enables, rather than asserting that the permission is dangerous. Where a finding is disputed by a development team, the reasoning is what resolves the dispute in either direction.
Three elements within sections merit specific attention:
- Certificate details. Certificate reuse across ostensibly unrelated applications is the lowest-cost campaign-linkage signal available in mobile threat intelligence and is routinely overlooked. A debug certificate on an application presenting as a banking product resolves the investigation immediately.
- Network indicators. Domains, IP addresses, URLs and decrypted configuration where extraction succeeded. These have the longest operational life of any output: a verdict protects a single customer, whereas a C2 domain entered into a DNS blocklist protects every user behind it.
- YARA matches. Family attribution. An empty result is a valid outcome. Most samples do not belong to a known family, and a tool that consistently returns attribution is inferring rather than matching.
ttp_mapping
Findings mapped to MITRE ATT&CK Mobile techniques.
Mapping renders a mobile finding legible to stakeholders who do not work in mobile security. Technique identifiers can be fed into a detection coverage model, which removes the mobile estate as a gap in ATT&CK coverage reporting.
Findings are additionally mapped to the eight OWASP MASVS control categories — MASVS-STORAGE, MASVS-CRYPTO, MASVS-AUTH, MASVS-NETWORK, MASVS-PLATFORM, MASVS-CODE, MASVS-RESILIENCE and MASVS-PRIVACY. MASTG supplies the corresponding test procedure for each control where a result must be independently demonstrated.
One caution applies when both figures appear in the same report: they run in opposite directions. Risk is scored 0–100 where higher is worse. MASVS coverage is scored 0–100 where higher is better.
narrative and behavior_summary
Prose descriptions of the sample and its behaviour, assembled from the findings.
The generation method is stated explicitly because the prevailing assumption regarding prose in a security report is that a language model produced it. These fields are produced by a rules engine. A phase of the attack chain appears in the output only where findings support it, which means the summary cannot assert a step the evidence does not carry — the characteristic failure mode of generated text, and the reason generated text cannot be cited as evidence.
Both fields remain summaries rather than evidence. The evidence is sections, and sections is what belongs in an incident record.
coverage, analyzer_version and toolchain
These three blocks determine whether a report is defensible.
coverage records what the analysis was able to examine. A sample whose manifest failed to parse is not a clean sample, and a report that does not distinguish "examined, nothing found" from "could not examine" does not support a signed conclusion.
analyzer_version and toolchain record what produced the result. This is operationally significant because the analysis engine is versioned and changes over time. On 19 September 2026 the SDK fingerprint set expanded from 35 to 87 signatures and Log4j detection was introduced. A report generated after that date can legitimately contain findings absent from an earlier run against the same file. Where two analyses of one application are compared across dates, analyzer_version establishes that the difference is a change in the engine rather than an inconsistency in it.
Export formats
Six export formats are available:
| Format | Primary destination |
|---|---|
| STIX 2.1 | SIEM and SOAR ingestion |
| Incident records, review committees, client deliverables | |
| DOCX | Editable deliverables, including white-label MSSP reporting |
| JSON / JSONL | Internal tooling and data-store ingestion |
| CSV | Tabular analysis |
Programmatic access
Automated workflows use the API rather than the browser upload. The API mirrors the browser sequence:
POST /api/upload → returns upload_id
POST /api/analyze {"upload_id": "..."} → returns job_id and run_id
GET /api/jobs/{job_id} → poll until done or failed
GET /api/runs/{run_id}/artifact/report.json → retrieve the report
job_id and run_id are distinct UUIDs and are not interchangeable: the job represents the work, the run represents the result. Where a file has been analysed previously, /api/analyze returns cached: true with a null job_id; no polling is required, as the report already exists.
Authentication accepts either X-API-Key: dw_… or Authorization: Bearer dw_…. Where both are supplied, the API key header takes precedence.
Bulk processing uses the batch endpoints — POST /api/batch/upload, POST /api/batch/analyze, GET /api/batch/{batch_id} — which process a day's feed intake in a single pass. PDF and STIX exports are retrieved from their own artifact endpoints.
Two endpoint families require no authentication: the threat feed (GET /api/threat-feed, GET /api/threat-feed/lookup) and explore (GET /api/explore, GET /api/explore/search). Both serve only runs whose owner has opted in and whose verdict is Malicious, High Risk or Suspicious. The public feed is published under CC BY 4.0. The lookup endpoint permits hash checks without an account.
Build-time scanning is handled through CI/CD rather than the API. The GitHub Action scans build artefacts and fails builds on configurable verdict thresholds. Five further integrations are available: GitLab, Bitrise, Jenkins, CircleCI and Azure Pipelines. The quickstart documents the minimum working sequence; the API reference documents the schemas.
Scope and limitations
Everything described above is static analysis. Static analysis establishes capability rather than behaviour: what an application is able to do, not what it did during execution. This is sufficient for the majority of triage decisions and is available within minutes.
Where a decision depends on runtime behaviour, three constraints apply:
- Dynamic analysis is available for Android only. No iOS runtime instrumentation exists.
- Dynamic analysis executes against the customer's own device or emulator, connected through the Droidwatch agent. No sample executes on Droidwatch infrastructure. For organisations processing customer-supplied samples under data-residency obligations this is the intended design, though it requires configuration on the customer side. Dynamic analysis is available from the Pro plan; higher plans extend the execution window from 300 to 450 seconds and increase the monthly emulator allocation.
- The hosted cloud sandbox is not in production. Descriptions of Droidwatch dynamic analysis as a hosted sandbox are inaccurate.
iOS .ipa analysis runs seven static modules: Mach-O binary analysis, Info.plist, entitlements, App Transport Security configuration, class-dump, linked frameworks and declared privacy manifests. No runtime component exists for iOS on any plan.
Plans and limits
| Plan | Price | Analyses/day | Maximum size | Retention |
|---|---|---|---|---|
| No account | — | 3 | 150 MB | 7 days |
| Free | $0 | 5 | 200 MB | 7 days |
| Pro | $29/mo | 100 | 500 MB | 90 days |
| Team | $99/mo | 500 | 750 MB | 180 days |
| Enterprise | Custom | Unlimited | 1 GB | 365 days |
All plans run the identical analysis pipeline. Plan tiers govern throughput, file size and retention rather than analysis depth. Dynamic analysis and API access begin at Pro, with 30 emulator-minutes per month; Team provides 90 and Enterprise 150.
Frequently asked questions
Is APK analysis available at no cost? Yes. A free account provides five analyses per day with the complete static pipeline, MITRE ATT&CK Mobile mapping, MASVS coverage and all six export formats including STIX 2.1. Three analyses per day are available without an account.
Are submitted samples shared with third parties? Submissions are private by default. Indicators are published to the public threat feed only for runs whose owner has opted in. This differs from free multi-scanner services, where free-tier submissions are commonly made available to other customers — a constraint that prevents their use for customer-supplied samples containing personal data. Handling and disclosure practices are documented on the trust page.
How does this differ from VirusTotal? VirusTotal answers whether a hash has been observed and how participating engines classified it. It is the appropriate first lookup. It does not provide per-finding reasoning, certificate analysis, ATT&CK mapping, or a report suitable for submission to a review committee. A detailed comparison is available.
How does this differ from a self-operated MobSF instance? At the analysis level, the difference is limited; MobSF is a capable engine and a significant part of the mobile security discipline was established on it. The difference is operational: no container orchestration, no worker scaling, no dependency maintenance, plus multi-tenancy, role-based access control, audit logging, billing and threat intelligence. The full comparison documents the trade-off.
What is the expected analysis time? Two to five minutes for a 50 MB APK; eight to ten minutes on average for packages above 100 MB.
Submit an APK for analysis. No payment method required.