Skip to content

VNX-930: Android app runs commands as root through su

CWE-930 is an OWASP Top Ten 2013 category (broken authentication and session management) with no code shape of its own; this rule reports the concrete device-level authorization signal it was generated for: Java or Kotlin code that launches the su binary to run commands as root, through Runtime.getRuntime().exec("su"), exec("su -c ..."), exec(new String[]{"su", ...}) or exec(arrayOf("su", ...)), new ProcessBuilder("su", ...), ProcessBuilder(listOf/Arrays.asList("su", ...)) or processBuilder.command("su", ...), with su named bare or by an absolute path (/system/xbin/su, /su/bin/su) and the argument list possibly starting on the next line; a command array whose first element is su assigned a few lines before the exec; and the libsuperuser Shell.SU.run(...) and early libsu Shell.su(...) root-shell helpers. Whatever the root shell runs bypasses the Android permission model. Not reported: root detection (which su, ls /system/xbin/su, File("/system/xbin/su").exists(), Shell.SU.available(), Superuser.apk checks), non-root shells (Shell.SH.run), other commands, comments and strings, and test code (src/test, src/androidTest, *Test.java).

Updated 02 Nov 2026Checked against cli@de9b52a
Field Value
Rule ID VNX-930
Severity Medium
SARIF level warning
Kind sast
Languages Java, Kotlin
CWE CWE-930
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 authorization-bypass-device android cwe-930
Source internal/sast/rules/vnx-930.rego

Overview

CWE-930 is an OWASP Top Ten 2013 category (broken authentication and session management) with no code shape of its own; this rule reports the concrete device-level authorization signal it was generated for: Java or Kotlin code that launches the su binary to run commands as root, through Runtime.getRuntime().exec(“su”), exec(“su -c …”), exec(new String[]{“su”, …}) or exec(arrayOf(“su”, …)), new ProcessBuilder(“su”, …) or ProcessBuilder(listOf/Arrays.asList(“su”, …)), and a command array whose first element is su assigned a few lines before the exec. Whatever the root shell runs bypasses the Android permission model. Not reported: root detection (which su, File(“/system/xbin/su”).exists(), Superuser.apk checks), other commands, comments and strings.

Why This Matters

A command run through su runs as root, outside the Android sandbox and permission model. Any part of it built from input becomes root code execution, and the app only works on rooted devices.

What Gets Flagged

Process p = Runtime.getRuntime().exec("su");
Runtime.getRuntime().exec(new String[] { "su", "-c", cmd });
ProcessBuilder pb = new ProcessBuilder("su", "-c", cmd);
Runtime.getRuntime().exec(arrayOf("su", "-c", cmd))

What Is Not Flagged

// root detection, not root use
boolean rooted = new File("/system/xbin/su").exists();
Runtime.getRuntime().exec(new String[] { "which", "su" });
Runtime.getRuntime().exec("ls -l /data/local/tmp");

Remediation

  1. Use a platform API or a privileged system service with a narrow interface instead of a root shell.
  2. If root is unavoidable, never build the command from input, and run a fixed command list.
  3. For a confirmed false positive, add a vulnetix-ignore: VNX-930 comment on the line.

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-930
// nosec vnx-930

Or record an ignore rule: vulnetix ignore add --rule vnx-930 --reason "...". See Suppressing findings.

Edit this pageSources: cli/internal/sast/rules/vnx-930.rego, cli/internal/sast/docs/vnx-930.md
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.