From 6b57540b508d1dfc505db720b2e99b0923664ca3 Mon Sep 17 00:00:00 2001 From: Anurag Soni Date: Fri, 14 May 2021 12:10:33 -0400 Subject: [PATCH] Validate header key's character set (#15) * Validate header key's character set --- src/Tiny_httpd.ml | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/src/Tiny_httpd.ml b/src/Tiny_httpd.ml index 007abce9..0f18b7c8 100644 --- a/src/Tiny_httpd.ml +++ b/src/Tiny_httpd.ml @@ -321,6 +321,20 @@ module Headers = struct let pp_pair out (k,v) = Format.fprintf out "@[%s: %s@]" k v in Format.fprintf out "@[%a@]" (Format.pp_print_list pp_pair) l + (* token = 1*tchar + tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" / "+" / "-" / "." / "^" / "_" + / "`" / "|" / "~" / DIGIT / ALPHA ; any VCHAR, except delimiters + Reference: https://datatracker.ietf.org/doc/html/rfc7230#section-3.2 *) + let is_tchar = function + | '0' .. '9' | 'a' .. 'z' | 'A' .. 'Z' + | '!' | '#' | '$' | '%' | '&' | '\'' | '*' | '+' | '-' | '.' | '^' + | '_' | '`' | '|' | '~' -> true + | _ -> false + + let for_all pred s = + try String.iter (fun c->if not (pred c) then raise Exit) s; true + with Exit -> false + let parse_ ~buf (bs:byte_stream) : t = let rec loop acc = let line = Byte_stream.read_line ~buf bs in @@ -332,6 +346,8 @@ module Headers = struct try let i = String.index line ':' in let k = String.sub line 0 i in + if not (for_all is_tchar k) then ( + invalid_arg (Printf.sprintf "Invalid header key: %S" k)); let v = String.sub line (i+1) (String.length line-i-1) |> String.trim in k,v with _ -> bad_reqf 400 "invalid header line: %S" line