fix(users/Profpatsch/read-http): actually parse ascii

There might be exploits since we parsed the headers as utf8 even
though we actually want to interpret them as ASCII.

This fixes it, by using the ascii crate.

Thanks to @sterni for noticing.

Change-Id: I50b6a588d99b34e677cb22968cf0dfd8b331d11c
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2457
Reviewed-by: Profpatsch <mail@profpatsch.de>
Tested-by: BuildkiteCI
This commit is contained in:
Profpatsch 2021-01-29 16:35:02 +01:00
parent cf3aab3b78
commit f0579313d3
3 changed files with 12 additions and 3 deletions

View file

@ -6,6 +6,7 @@ let
read-http = depot.users.Profpatsch.writers.rustSimple { read-http = depot.users.Profpatsch.writers.rustSimple {
name = "read-http"; name = "read-http";
dependencies = [ dependencies = [
depot.users.Profpatsch.rust-crates.ascii
depot.users.Profpatsch.rust-crates.httparse depot.users.Profpatsch.rust-crates.httparse
depot.users.Profpatsch.netencode.netencode-rs depot.users.Profpatsch.netencode.netencode-rs
depot.users.Profpatsch.arglib.netencode.rust depot.users.Profpatsch.arglib.netencode.rust

View file

@ -1,6 +1,7 @@
extern crate httparse; extern crate httparse;
extern crate netencode; extern crate netencode;
extern crate arglib_netencode; extern crate arglib_netencode;
extern crate ascii;
use std::os::unix::io::FromRawFd; use std::os::unix::io::FromRawFd;
use std::io::Read; use std::io::Read;
@ -63,11 +64,11 @@ fn main() -> std::io::Result<()> {
fn normalize_headers<'a>(headers: &'a [httparse::Header]) -> Vec<(String, &'a str)> { fn normalize_headers<'a>(headers: &'a [httparse::Header]) -> Vec<(String, &'a str)> {
let mut res = vec![]; let mut res = vec![];
for httparse::Header { name, value } in headers { for httparse::Header { name, value } in headers {
let val = std::str::from_utf8(*value) let val = ascii::AsciiStr::from_ascii(*value)
.expect(&format!("read-http: we require header values to be UTF-8 (they should be ASCII), but the header {} was {:?}", name, value)); .expect(&format!("read-http: we require header values to be ASCII, but the header {} was {:?}", name, value));
// lowercase the headers, since the standard doesnt care // lowercase the headers, since the standard doesnt care
// and we want unique strings to match agains // and we want unique strings to match agains
res.push((name.to_lowercase(), val)) res.push((name.to_lowercase(), val.as_str()))
} }
res res
} }

View file

@ -14,6 +14,13 @@ rec {
sha256 = "12q71z6ck8wlqrwgi25x3lrryyks9djymswn9b1c6qq0i01jpc1p"; sha256 = "12q71z6ck8wlqrwgi25x3lrryyks9djymswn9b1c6qq0i01jpc1p";
}; };
ascii = pkgs.buildRustCrate {
pname = "ascii";
crateName = "ascii";
version = "1.0.0";
sha256 = "0gam8xsn981wfa40srsniivffjsfz1pg0xnigmczk9k7azb1ks1m";
};
regex-syntax = pkgs.buildRustCrate { regex-syntax = pkgs.buildRustCrate {
pname = "regex-syntax"; pname = "regex-syntax";
crateName = "regex-syntax"; crateName = "regex-syntax";