diff options
| author | Oskar <oskar@mullvad.net> | 2025-09-11 15:50:06 +0200 |
|---|---|---|
| committer | David Lönnhager <david.l@mullvad.net> | 2025-09-25 13:53:34 +0200 |
| commit | fed13c26db8754e0c1686adf621658d918cc43d8 (patch) | |
| tree | 902e58bdd95f508dbcbe4a0883e88ecb7a1962ea | |
| parent | 85464023623c11144d5c79f6c5ca0d198320fa0c (diff) | |
| download | mullvadvpn-fed13c26db8754e0c1686adf621658d918cc43d8.tar.xz mullvadvpn-fed13c26db8754e0c1686adf621658d918cc43d8.zip | |
Add sanitation of header values
| -rw-r--r-- | mullvad-api/src/version.rs | 40 |
1 files changed, 38 insertions, 2 deletions
diff --git a/mullvad-api/src/version.rs b/mullvad-api/src/version.rs index 2593836aea..3f3c4a4e7e 100644 --- a/mullvad-api/src/version.rs +++ b/mullvad-api/src/version.rs @@ -78,8 +78,14 @@ impl AppVersionProxy { async move { let request = request? .expected_status(&[StatusCode::OK]) - .header("M-App-Version", mullvad_version::VERSION)? - .header("M-Platform-Version", &platform_version)?; + .header( + "M-App-Version", + &sanitize_header_value(mullvad_version::VERSION), + )? + .header( + "M-Platform-Version", + &sanitize_header_value(&platform_version), + )?; let response = service.request(request).await?; let bytes = response.body_with_max_size(Self::SIZE_LIMIT).await?; @@ -112,3 +118,33 @@ impl AppVersionProxy { } } } + +// This function makes a string conform to the allowed characters and length of header values. +// Here's the rule it needs to implement: [A-Za-z0-9_.-]{1,64} +fn sanitize_header_value(value: &str) -> String { + value + .chars() + .map(|c| if c.is_whitespace() { '_' } else { c }) + .filter(|&c| c.is_ascii_alphanumeric() || "_.-".contains(c)) + .take(64) + .collect() +} + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_sanitize_header_value() { + assert_eq!(sanitize_header_value("2025.5"), "2025.5"); + assert_eq!(sanitize_header_value("Fedora Linux"), "Fedora_Linux"); + assert_eq!(sanitize_header_value("macOS 26.1"), "macOS_26.1"); + assert_eq!(sanitize_header_value("Déjà vu OS"), "Dj_vu_OS"); + + let long_value = + "abcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyzabcdefghijklmnopqrstuvxyz"; + let mut truncated_long_value = long_value.to_owned(); + truncated_long_value.truncate(64); + assert_eq!(sanitize_header_value(long_value), truncated_long_value); + } +} |
