MuntashirAkon/AppManager · critical · IOException
Zip slip vulnerability detected!\nExpected dest: " + new Fil
Error message
Zip slip vulnerability detected!\nExpected dest: " + new File(realDestPath, entry.getName()) + "\nActual path: " + realFilePath
What it means
A second, post-resolution zip-slip check in AndroidBackupExtractor: even when the entry name looked safe, the real filesystem path of the target (following symlinks) is compared against realDestPath. If the resolved path escapes the destination, extraction is aborted with an IOException.
Source
Thrown at app/src/main/java/io/github/muntashirakon/AppManager/backup/adb/AndroidBackupExtractor.java:98
if (!filename.startsWith(relativeDirInAb)) {
throw new IOException("Unsupported file in AB: " + filename);
}
// Remove apps/{packageName}/ part
filename = filename.substring(relDirSize);
Path file;
if (entry.isDirectory()) {
file = dest.createDirectoriesIfRequired(filename);
} else file = dest.createNewArbitraryFile(filename, null);
// Check if the given entry is a link.
if (entry.isSymbolicLink() && file.getFilePath() != null) {
String linkName = entry.getLinkName();
file.delete();
file.createNewSymbolicLink(linkName);
} else {
// Zip slip vulnerability might still be present
String realFilePath = file.getRealFilePath();
if (realDestPath != null && realFilePath != null && !realFilePath.startsWith(realDestPath)) {
throw new IOException("Zip slip vulnerability detected!" +
"\nExpected dest: " + new File(realDestPath, entry.getName()) +
"\nActual path: " + realFilePath);
}
if (!entry.isDirectory()) {
try (OutputStream os = file.openOutputStream()) {
IoUtils.copy(tis, os);
}
}
}
// Categorize and build TarArchiveEntry
int category = getCategory(filename);
if (category == CAT_UNK && filename.equals(Constants.BACKUP_MANIFEST_FILENAME)) {
// Ignore manifest file
continue;
}
TarArchiveEntry targetEntry = getTargetArchiveEntry(entry, filename);
List<TargetTarEntry> targetTarEntries = mCategoryTargetEntriesMap.get(category);View on GitHub (pinned to 0152f468fc)
Solutions
- Refuse the archive — it likely contains a malicious symlink chain
- Extract into a fresh, empty destination directory with no pre-existing symlinks
- Remove suspicious symlinks from the destination before re-running the restore
- Regenerate the backup from a trusted source
Example fix
// before (destination reused across restores)
Path dest = new Path("/data/local/tmp/restore");
extractor.extract();
// after (clean destination each run)
Path dest = new Path("/data/local/tmp/restore-" + System.nanoTime());
dest.mkdirsIfNotExists();
extractor.extract(); Defensive patterns
Strategy: validation
Validate before calling
// Ensure destination contains no symlinks before extraction
Files.walk(destDir)
.filter(p -> Files.isSymbolicLink(p))
.forEach(p -> { throw new RuntimeException("Symlink in dest: " + p); }); Try / catch
try {
extractor.extract();
} catch (IOException e) {
if (e.getMessage().contains("Zip slip")) {
Log.e(TAG, "Symlink-based traversal attempt blocked", e);
wipeAndRecreate(destDir);
} else throw e;
} Prevention
- Extract into empty directories with no pre-existing symlinks
- Never reuse a destination across untrusted restores
- Treat any zip-slip exception as evidence of a malicious archive
- Audit destinations in shared/multi-user storage
When it happens
Trigger: A TAR entry containing a symbolic link (or hard-to-spot path) whose resolved target lies outside the extraction directory — e.g. a symlink previously created pointing to /data, followed by an entry writing through it.
Common situations: Maliciously crafted backups using symlink chains to escape the destination; archives restored into directories that already contain attacker-influenced symlinks.
Understand the failure class
Background: Path traversal blocked: "path escapes the workspace" and "outside site root" errors when a path will not stay inside its allowed directory — this error's family across 26 libraries.
Related errors
- Zip slip vulnerability detected! Expected dest: ${new File(r
- Zip slip vulnerability detected!\nExpected dest: " + new Fil
- Zip slip vulnerability detected! Expected dest: ${new File(r
- Error! Invalid characters in arguments.\n
- Signing info verification failed.\nInstalled: ${certChecksum
AI-assisted analysis of MuntashirAkon/AppManager@0152f468fc (2026-09-12).
Data as JSON: /api/errors/9e0ac7411e2c3d01.
Report an issue: GitHub.