lingochamp/FileDownloader · critical · FileDownloadSecurityException
The filename [ ] from the response is not allowable…
Error message
The filename [%s] from the response is not allowable, because it contains '../', which can raise the directory traversal vulnerability
What it means
findFilename derives the target filename from the response's Content-Disposition header, the URL, or a generated hash. If a server-supplied filename contains '../', using it would let the download escape its intended directory (directory traversal), so the library throws FileDownloadSecurityException to block the attack.
Solutions
- Do not rely on server filenames: set an explicit safe path via task.setPath(...) so the response filename is ignored.
- Sanitize/validate the server-provided filename before initiating the download, rejecting any name containing path separators or '..'.
- Only download from trusted servers; treat this exception as evidence the remote is hostile and block it.
- If you need the server filename, strip directory components yourself (e.g. use only the substring after the last '/').
Example fix
// before
request.setPath(dir + File.separator + responseFilename); // responseFilename = "../../evil"
// after
String safe = new File(responseFilename).getName();
if (safe.contains("..") || safe.contains("/")) {
safe = FileDownloadUtils.generateFileName(url);
}
request.setPath(dir + File.separator + safe); Defensive patterns
Strategy: validation
Validate before calling
String name = headerFilename; // from Content-Disposition
if (name != null && (name.contains("../") || name.contains("/") || name.contains("\\"))) {
name = FileDownloadUtils.generateFileName(url); // reject hostile name
} Type guard
boolean isSafeFilename(String f) {
return f != null && !f.isEmpty() && !f.contains("../") && !f.contains("/") && !f.contains("\\")
&& !"..".equals(f);
} Try / catch
try {
downloader.create(url).setPath(safePath).start();
} catch (FileDownloadSecurityException e) {
// server supplied a traversal filename: block host and alert
blockHost(url);
} Prevention
- Always set an explicit local path so server filenames are never used directly.
- Treat this exception as a signal the remote server is hostile; log and block it.
- Sanitize any header-derived name to its basename before use.
When it happens
Trigger: A download response's Content-Disposition filename (or URL-derived filename) contains the substring '../', e.g. 'Content-Disposition: attachment; filename="../../data/file"'.
Common situations: Downloading from untrusted or compromised servers; malicious CDN/proxy injecting hostile filenames; security testing against apps using FileDownloader with server-driven filenames.
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
- fetched length[ ] != content length[ ], range[ , ) offset[…
- connection is null when findEtag
- can't know the size of the download file, and its…
- response code error: , request headers: response headers
- Connection failed with request
AI-assisted analysis of lingochamp/FileDownloader@6237a8cac1 (2026-09-08).
Data as JSON: /api/errors/5e8f01b55b18b354.
Report an issue: GitHub.
Appendix: source
Thrown at library/src/main/java/com/liulishuo/filedownloader/util/FileDownloadUtils.java:671
FileDownloadLog.e(FileDownloadUtils.class, e, "parse content length"
+ " from content range error");
}
return -1;
}
public static String findFilename(FileDownloadConnection connection, String url)
throws FileDownloadSecurityException {
String filename = FileDownloadUtils.parseContentDisposition(connection.
getResponseHeaderField("Content-Disposition"));
if (TextUtils.isEmpty(filename)) {
filename = findFileNameFromUrl(url);
}
if (TextUtils.isEmpty(filename)) {
filename = FileDownloadUtils.generateFileName(url);
} else if (filename.contains("../")) {
throw new FileDownloadSecurityException(FileDownloadUtils.formatString(
"The filename [%s] from the response is not allowable, because it contains "
+ "'../', which can raise the directory traversal vulnerability",
filename));
}
return filename;
}
public static FileDownloadOutputStream createOutputStream(final String path)
throws IOException {
if (TextUtils.isEmpty(path)) {
throw new RuntimeException("found invalid internal destination path, empty");
}
//noinspection ConstantConditions
if (!FileDownloadUtils.isFilenameValid(path)) {
throw new RuntimeException(View on GitHub (pinned to 6237a8cac1)