symfony/http-foundation · error · InvalidArgumentException
The filename and the fallback cannot contain the "/" and…
Error message
The filename and the fallback cannot contain the "/" and "\" characters.
What it means
Path separators '/' and '\' are forbidden in both $filename and $filenameFallback to prevent Content-Disposition header values from carrying path components, which would enable header injection / path-traversal style attacks against clients that honor directory parts in the filename. makeDisposition() throws this InvalidArgumentException if either string contains either separator.
Solutions
- Pass only the basename: HeaderUtils::makeDisposition($d, basename($path))
- Strip separators from user input: str_replace(['/', '\\'], '', $filename) or preg_replace('#[/\\\\]#', '_', $name)
- Reject requests containing path separators before building the header (defense against traversal)
- Wrap in try/catch InvalidArgumentException, sanitize, and retry with the cleaned name
Example fix
// before
HeaderUtils::makeDisposition('attachment', '/var/www/uploads/report.pdf'); // throws
// after
HeaderUtils::makeDisposition('attachment', basename('/var/www/uploads/report.pdf')); // 'report.pdf' Defensive patterns
Strategy: validation
Validate before calling
$name = basename(str_replace('\\', '/', $filename));
if ($name !== $filename) {
throw new \InvalidArgumentException('Filename must not contain path separators.');
} Type guard
function hasNoPathSeparators(string $s): bool {
return !str_contains($s, '/') && !str_contains($s, '\\');
} Try / catch
try {
$header = HeaderUtils::makeDisposition($disposition, $filename);
} catch (\InvalidArgumentException $e) {
$header = HeaderUtils::makeDisposition($disposition, basename(str_replace('\\', '/', $filename)));
} Prevention
- Always pass basename($path), never a full server path
- Treat user-supplied filenames as untrusted: reject or strip '/' and '\\' (path-traversal defense)
- Log/reject traversal attempts rather than silently sanitizing when input is malicious
When it happens
Trigger: Calling makeDisposition($disposition, $filename) or with a fallback where $filename or $filenameFallback contains '/' or '\' — e.g. 'uploads/report.pdf', 'C:\\temp\\a.pdf', or a user-supplied '../../etc/passwd' filename.
Common situations: Passing a full server-side file path instead of just the basename; echoing unsanitized user upload names (path traversal attempt) into the Content-Disposition header; Windows paths with backslashes.
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
- The disposition must be either
- The filename fallback must only contain ASCII characters.
- The filename fallback cannot contain the "%" character.
- Invalid Host " ".
- Untrusted Host " ".
AI-assisted analysis of symfony/http-foundation@5aea19cd67 (2026-09-13).
Data as JSON: /api/errors/1b97ae319024685d.
Report an issue: GitHub.
Appendix: source
Thrown at HeaderUtils.php:187
}
if ('' === $filenameFallback) {
$filenameFallback = $filename;
}
// filenameFallback is not ASCII.
if (!preg_match('/^[\x20-\x7e]*$/', $filenameFallback)) {
throw new \InvalidArgumentException('The filename fallback must only contain ASCII characters.');
}
// percent characters aren't safe in fallback.
if (str_contains($filenameFallback, '%')) {
throw new \InvalidArgumentException('The filename fallback cannot contain the "%" character.');
}
// path separators aren't allowed in either.
if (str_contains($filename, '/') || str_contains($filename, '\\') || str_contains($filenameFallback, '/') || str_contains($filenameFallback, '\\')) {
throw new \InvalidArgumentException('The filename and the fallback cannot contain the "/" and "\\" characters.');
}
$params = ['filename' => $filenameFallback];
if ($filename !== $filenameFallback) {
$params['filename*'] = "utf-8''".rawurlencode($filename);
}
return $disposition.'; '.self::toString($params, ';');
}
/**
* Like parse_str(), but preserves dots in variable names.
*/
public static function parseQuery(string $query, bool $ignoreBrackets = false, string $separator = '&'): array
{
$q = [];
foreach (explode($separator, $query) as $v) {View on GitHub (pinned to 5aea19cd67)