on master help sign in
Limit the maximum header line length to 8190 chars.

This value was taken from an apache default setting: http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline

commit55d7cced89ac86b469793b1c001f63fae3b54b55 authorHans-Christian Esperer <hc@hcesperer.org> dateSat 2 Jul 2016, 21:26 (10 years ago) parent65cc932
2 files changed+24−5
wai-extra/Network/Wai/Parse.hs+10−5 wai-extra/test/Network/Wai/ParseSpec.hs+14
wai-extra/Network/Wai/Parse.hs+10−5
@@ -289,24 +289,29 @@ conduitRequestBodyEx o backend (Multipart bound) rbody add =
289289 parsePiecesEx o backend (S8.pack "--" `S.append` bound) rbody add
290290
291291
292+-- | Take one header or subheader line.
293+-- It makes sense to limit the maximum line length.
294+-- Apache's default is 8190 (http://httpd.apache.org/docs/2.2/mod/core.html#limitrequestline)
295+-- so we're using that here as well.
292296takeLine :: Source -> IO (Maybe S.ByteString)
293297takeLine src =
294− go id
298+ go ""
295299 where
296300 go front = do
297301 bs <- readSource src
302+ when (S.length front + S.length bs > 8190) $ error "Header line length exceeds allowed maximum."
298303 if S.null bs
299304 then close front
300305 else push front bs
301306
302− close front = leftover src (front S.empty) >> return Nothing
307+ close front = leftover src front >> return Nothing
303308 push front bs = do
304− let (x, y) = S.break (== 10) $ front bs -- LF
309+ let (x, y) = S.break (== 10) bs -- LF
305310 in if S.null y
306− then go $ S.append x
311+ then go $ front `S.append` x
307312 else do
308313 when (S.length y > 1) $ leftover src $ S.drop 1 y
309− return $ Just $ killCR x
314+ return $ Just $ killCR $ front `S.append` x
310315
311316takeLines :: Source -> IO [S.ByteString]
312317takeLines src = do
wai-extra/test/Network/Wai/ParseSpec.hs+14
@@ -131,6 +131,10 @@ caseParseRequestBody = do
131131 SRequest req4 bod4 <- toRequest'' ctype2 content2
132132 (parseRequestBodyEx (def { prboMaxHeaderLines = 1 } ) lbsBackEnd req4) `shouldThrow` anyErrorCall
133133
134+ it "exceeding header line size" $ do
135+ SRequest req4 bod4 <- toRequest'' ctype2 content4
136+ (parseRequestBodyEx def lbsBackEnd req4) `shouldThrow` anyErrorCall
137+
134138 where
135139 content2 =
136140 "--AaB03x\n"
@@ -154,6 +158,16 @@ caseParseRequestBody = do
154158 <> "Content-Type: application/octet-stream\r\n\r\n"
155159 <> "Photo blog using Hack.\n\r\n"
156160 <> "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh--\r\n"
161+ content4 =
162+ "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh\r\n"
163+ <> "Content-Disposition: form-data; name=\"yaml\"; filename=\"README\"\r\n"
164+ <> "Content-Type: application/octet-stream\r\n\r\n"
165+ <> "Photo blog using Hack.\n\r\n"
166+ <> "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh\r\n"
167+ <> "Content-Disposition: form-data; name=\"bla\"; filename=\"riedmie\"\r\n"
168+ <> "Content-Type: application/octet-stream=TOOLONG=" <> S8.replicate 8192 '=' <> "\r\n\r\n"
169+ <> "Photo blog using Hack.\n\r\n"
170+ <> "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh--\r\n"
157171
158172caseMultipartPlus :: Assertion
159173caseMultipartPlus = do