iBotPeaches/Apktool · error · InvalidPathException
Absolute paths are not allowed
Error message
Absolute paths are not allowed
What it means
Thrown by BrutIO.sanitizePath when the input path is absolute (e.g. '/etc/passwd' or 'C:\x'). The method only accepts paths relative to a base directory so that the resolved result stays inside it. It is a security guard used when extracting or writing zip entries to prevent writing outside the target directory.
Source
Thrown at brut.j.util/src/main/java/brut/util/BrutIO.java:108
public static CRC32 calculateCrc(InputStream in) throws IOException {
CRC32 crc = new CRC32();
int bytesRead;
byte[] buffer = new byte[8192];
while ((bytesRead = in.read(buffer)) != -1) {
crc.update(buffer, 0, bytesRead);
}
return crc;
}
public static String sanitizePath(File baseDir, String path) throws InvalidPathException, IOException {
if (path == null || path.isEmpty()) {
throw new InvalidPathException(path, "Path is null or empty");
}
Path origPath = Paths.get(path);
if (origPath.isAbsolute()) {
throw new InvalidPathException(path, "Absolute paths are not allowed");
}
Path basePath = Paths.get(baseDir.getCanonicalPath());
Path resolvedPath = basePath.resolve(origPath).normalize();
if (!resolvedPath.startsWith(basePath)) {
throw new InvalidPathException(path, "Path traverses outside the base directory");
}
return basePath.relativize(resolvedPath).toString();
}
}
View on GitHub (pinned to 79b63384d7)
Solutions
- Strip the leading separator or convert the input to a path relative to baseDir before calling sanitizePath (e.g. path.startsWith("/") ? path.substring(1) : path)
- If the absolute path is legitimate, compute the relative portion yourself: baseDir.toPath().relativize(Paths.get(path)) and pass that result
- Reject or skip absolute entries at the boundary where untrusted names enter (zip entry loop, config parser) instead of letting sanitizePath throw
Example fix
// before
String rel = BrutIO.sanitizePath(baseDir, entryName); // entryName = "/res/values.xml"
// after
String cleaned = entryName.startsWith("/") ? entryName.substring(1) : entryName;
String rel = BrutIO.sanitizePath(baseDir, cleaned); Defensive patterns
Strategy: validation
Validate before calling
boolean isSafeRelative(String p) {
if (p == null || p.isEmpty()) return false;
Path path = Paths.get(p);
return !path.isAbsolute() && !p.contains("..");
}
// use: if (isSafeRelative(entryName)) BrutIO.sanitizePath(baseDir, entryName); else skip(); Prevention
- Normalize untrusted names at ingestion: strip leading '/' or '\\' and reject '..' segments before any filesystem call
- Never build paths from raw config values or zip entry names without an isAbsolute() check
- In tests, feed portable relative paths (forward slashes, no drive letters) on every OS
When it happens
Trigger: Calling BrutIO.sanitizePath(baseDir, path) with any string for which Paths.get(path).isAbsolute() is true — a leading '/' on Unix, a drive letter or leading backslash on Windows, or a UNC path.
Common situations: Processing zip/apk entries that store absolute entry names; passing user-supplied or config-file paths that were written with leading separators; code ported from Windows to Unix or vice versa; tests feeding OS-native paths into the sanitizer.
Related errors
- Path is null or empty
- Path traverses outside the base directory
- Could not move file:
- Could not copy file:
- Could not delete tmp file:
AI-assisted analysis of iBotPeaches/Apktool@79b63384d7 (2026-08-14).
Data as JSON: /api/errors/f6eaa4cb5deb41c3.
Report an issue: GitHub.