fix(axum-extra): escape filename in Content-Disposition header (#3664)

This commit is contained in:
Mathieu
2026-04-03 08:49:48 +02:00
committed by Alice Ryhl
parent 880cc38174
commit 4fa5d80ab7
5 changed files with 165 additions and 6 deletions
@@ -0,0 +1,46 @@
use std::fmt::{self, Write};
/// A wrapper type that escapes backslashes and double quotes when formatted,
/// for safe inclusion in Content-Disposition header quoted-strings.
///
/// This prevents Content-Disposition header parameter injection
/// (similar to CVE-2023-29401).
pub(crate) struct EscapedFilename<'a>(pub &'a str);
impl fmt::Display for EscapedFilename<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
for c in self.0.chars() {
if c == '\\' || c == '"' {
f.write_char('\\')?;
}
f.write_char(c)?;
}
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn no_special_characters() {
assert_eq!(EscapedFilename("report.pdf").to_string(), "report.pdf");
}
#[test]
fn escapes_double_quotes() {
assert_eq!(
EscapedFilename("evil\"; filename*=UTF-8''pwned.txt; x=\"").to_string(),
"evil\\\"; filename*=UTF-8''pwned.txt; x=\\\"",
);
}
#[test]
fn escapes_backslashes() {
assert_eq!(
EscapedFilename("file\\name.txt").to_string(),
"file\\\\name.txt",
);
}
}