mirror of
https://github.com/tokio-rs/axum.git
synced 2026-09-07 00:00:12 +02:00
fix(axum-extra): escape filename in Content-Disposition header (#3664)
This commit is contained in:
@@ -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",
|
||||
);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user