VNX-939: Improper Authorization in Handler for Custom URL Scheme
Reports an Android deep-link URI (or a query parameter or path segment read from it) passed to a WebView load, Intent.parseUri or a component selector without first checking its scheme, host or value.
| Field | Value |
|---|---|
| Rule ID | VNX-939 |
| Severity | Medium |
| SARIF level | warning |
| Kind | sast |
| Languages | Java, Kotlin |
| CWE | CWE-939 |
| CAPEC | CAPEC-66 |
| ATT&CK | T1190 |
| CWSS vector | CWSS:1.0/TI:M/AP:RU/AL:S/IC:N/FC:LT/RP:RU/RL:S/AV:L/AS:N/IN:A/SC:A/BI:M/DI:H/EX:M/EC:N/P:C |
| Tags | deeplink android cwe-939 |
| Source | internal/sast/rules/vnx-939.rego |
Overview
VNX-939 maps to CWE-939: Improper Authorization in Handler for Custom URL Scheme. Any installed app or any web page can open a custom-scheme (myapp://) or app link, so the URI an Activity receives is chosen by an attacker. A handler that loads it into a WebView, turns it into an Intent, or picks the component to launch from it lets that attacker drive the app.
What Gets Flagged
webView.loadUrl(getIntent().getDataString()); // flagged
Uri data = getIntent().getData();
String cls = data.getQueryParameter("screen");
i.setClassName(this, cls); // flagged
val next = intent?.data?.getQueryParameter("next")
val launch = Intent.parseUri(next, Intent.URI_INTENT_SCHEME) // flagged
Not flagged: a link whose scheme or host is checked first (getHost(), link.host != ..., startsWith, an allowlist or validator call), constant URLs and class names, intent string extras (VNX-ANDROID-002), test code, comments and string literals. Flows across methods or files are not followed, and the manifest’s intent-filter is not read.
Remediation
Check the scheme and host against an allowlist before acting on the link, and map path values to known screens rather than passing them to setClassName or Intent.parseUri:
Uri uri = getIntent().getData();
if (uri == null || !"https".equals(uri.getScheme()) || !ALLOWED_HOSTS.contains(uri.getHost())) {
finish();
return;
}
webView.loadUrl(uri.toString());
References
Suppressing this rule
Put a nosec comment on the line, or on line 1 to cover the whole file. Use the comment marker of the file’s language (#, //, -- or ;):
# nosec vnx-939
// nosec vnx-939
Or record an ignore rule: vulnetix ignore add --rule vnx-939 --reason "...". See Suppressing findings.