pSlip is an Android static analysis tool kit designed to find potentially vulnerable escalation paths by analyzing exported components, intent filters, provider permissions and cryptographic misuse
Manifest parsing, OAuth analysis, and AES/DES/IV detection all run on androguard reading the DEX directly. You no longer need apktool or jadx to scan an app. Those are only used if you opt into the deep AES pass with -aes-deep.
It now cross-references SecretKeySpec, IvParameterSpec, and Cipher, then backtraces the key/IV register to its constant source. A byte array key can never be a bare string literal, so a value is only reported if it actually reaches the constructor through getBytes() or an array literal. That provenance rule kills the usual false positives (algorithm names like AES, KDF names like PBKDF2WithHmacSHA1, stray exception strings). Every finding includes the recovered value, the key size, the cipher transform, and the const -> getBytes -> init chain, so it is ready to drop into a report.
The same app that used to time out now finishes in well under a minute with no Java involved. If you need keys that are assembled across branches or loaded from static fields, -aes-deep runs the old jadx/apktool source pass.
pSlip flags exported components that own an OAuth redirect (a custom scheme or an https app link) and reports the leaked client_id, the claimable redirect, and the runtime preconditions an attacker still has to confirm before claiming impact.
It also catches the Google “Web application” misconfiguration where an Android app ships a client_secret in the APK (the wrong OAuth client type), and it pulls cross-platform client_ids out of the DEX. Detection runs by default. Buildable PoC project generation is behind -oauth-poc.
.xapk, .apks, and .apkm bundles are expanded automatically. The base/code APK is analyzed and config/resource splits are skipped.
On a fresh Python install pSlip bootstraps its Python dependencies (tqdm, androguard) and re-runs itself. Set PSLIP_NO_AUTOINSTALL=1 to turn that off.
-all / -allsafe CLI.pSlip detects Android applications vulnerable to Permission-Slip / Confused-Deputy paths by analyzing:
pSlip is built for application-security testing, CI/CD pipelines, and bulk APK triage.
javascript: handlers-aes-deep, since it scans decompiled source and config)https app links)client_id plus claimable redirect, with the runtime preconditions spelled outgit clone https://github.com/actuator/pSlip.git
cd pSlip
pip install -r requirements.txt
That is everything for the default scan. The manifest, OAuth, and AES passes all run on androguard, so no Java or external tools are needed.
Only if you want the deep AES pass (-aes-deep), install jadx and/or apktool, which require Java 11 or later:
# Linux
sudo apt install apktool jadx
On Windows you can let pSlip install its Python dependencies on first run, or run pip install -r requirements.txt yourself. If jadx/apktool are not on PATH, pass -jadx <path> / -apktool <path>.
# Directory sweep, full scan, HTML + JSON
python pSlip.py . -all -html demo.html -json demo.json
# Fast sweep, skip the AES/crypto pass
python pSlip.py path/to/apks -allsafe -html report.html
# Deep AES pass using jadx/apktool source decompilation
python pSlip.py . -all -aes-deep -html report.html
# jadx installed somewhere off PATH
python pSlip.py . -all -jadx C:\tools\jadx\bin\jadx.bat
A single APK, a directory of APKs, or split bundles (.xapk, .apks, .apkm) are all valid targets.
-all Full analysis: manifest + OAuth + AES (androguard)
-allsafe Full analysis without the AES/crypto pass
-html <file> Write HTML report
-json <file> Write JSON report
-aes-timeout <minutes> Per-APK time limit for the AES pass (default: 5)
-aes-deep Use the jadx/apktool source-decompile AES pass
instead of the default androguard DEX scan
-oauth-poc Also generate buildable OAuth PoC projects
-oauth-poc-dir <dir> Output directory for OAuth PoC projects
-jadx <path> Path to a jadx launcher not on PATH (for -aes-deep)
-apktool <path> Path to an apktool launcher not on PATH
PSLIP_AES_PARALLEL Number of APKs to analyze at once in the AES pass
PSLIP_AES_DEEP=1 Same as -aes-deep
PSLIP_JADX Path override for jadx (same as -jadx)
PSLIP_APKTOOL Path override for apktool (same as -apktool)
PSLIP_JADX_TIMEOUT jadx subprocess timeout in seconds (deep pass)
PSLIP_APKTOOL_TIMEOUT apktool subprocess timeout in seconds (deep pass)
PSLIP_NO_AUTOINSTALL=1 Do not auto-install Python dependencies
PSLIP_FORCE_COLOR=1 Force ANSI color in the banner/output
The default crypto pass reads the DEX directly. It finds every call site of javax.crypto.spec.SecretKeySpec and javax.crypto.spec.IvParameterSpec, then walks the method backward to find what feeds the key or IV register.
The rule that keeps the output clean: a key or IV argument is a byte array, so a real one cannot be a bare string constant. pSlip only reports a value when it reaches the constructor through String.getBytes() or an array literal. Algorithm names, KDF names, and unrelated string constants near the call site are ignored.
Each finding records the recovered value, the key length and size class, the cipher transform from the nearby Cipher.getInstance, and the bytecode chain that proves the flow. Example:
Issue Type: Hardcoded AES Key
Details: Hardcoded AES key (32 bytes, AES-256) recovered from DEX bytecode.
value='...' (hex ...). algorithm=AES; cipher=AES/ECB/PKCS5Padding.
provenance: const '...' -> String.getBytes() -> SecretKeySpec.<init>.
sink=<class>-><method>
-aes-deep switches to the jadx/apktool path, which decompiles to Java/smali and runs the source-level scanner. It is slower and needs Java, but it can resolve keys the linear bytecode model does not, such as keys built across branches or read from a static field.
The linear bytecode backtrace is intraprocedural by design. Keys assembled across basic blocks or read from a static field are left to -aes-deep.
pSlip looks for exported components that handle an OAuth redirect, either a custom scheme or an https app link. When it finds one it reports the provider, the leaked client_id, the redirect a rogue app could claim, and the set of preconditions that are not provable from the APK and must be confirmed at runtime before claiming impact.
It also detects the Google “Web application” mistake, where an app is registered with the confidential client type and ships the client_secret inside the APK. In that case the secret is reported (redacted in the report, full value only in a generated PoC), and the token exchange recipe is described for the right client type.
[See https://actuator.sh/blog/2026-08-the-wrong-dropdown.html]
Detection runs by default as part of -all. Add -oauth-poc (optionally with -oauth-poc-dir <dir>) to also write buildable PoC projects.
pSlip detects hardcoded Segment write keys in Java, Kotlin, JSON, XML, JavaScript, TypeScript, properties, text, and smali. This scanner reads decompiled source and config, so it currently runs as part of the deep AES pass (-aes-deep).
Examples detected:
private static final String SEGMENT_WRITE_KEY = "pHYN1qhsRsz...";
{
"segmentWriteKey": "CaVz3hRhBJKCNlParpK4kvWJLNUf164N"
}
Reported as:
Issue Type: Hardcoded Segment Write Key
Severity: High
Confidence: 95