on master help sign in
Merge pull request #564 from hce/fix-headerlength-check

Fix the way the header length is determined

commit72f3066d1352ec60e00b22afc8eacdc4d6243614 authorMichael Snoyman <michael@snoyman.com> dateWed 6 Jul 2016, 12:53 (10 years ago) parent194b267a851ef6
4 files changed+28−18
wai-extra/ChangeLog.md+4 wai-extra/Network/Wai/Parse.hs+8−3 wai-extra/test/Network/Wai/ParseSpec.hs+15−14 wai-extra/wai-extra.cabal+1−1
wai-extra/ChangeLog.md+4
@@ -1,3 +1,7 @@
1+## 3.0.16.1
2+
3+* Fix the way the header length is checked (for limiting the max header length)
4+
15## 3.0.16.0
26
37* Add a new function "parseRequestBodyEx" that allows various size limits to be set.
wai-extra/Network/Wai/Parse.hs+8−3
@@ -425,7 +425,7 @@ takeLine maxlen src =
425425 go front = do
426426 bs <- readSource src
427427 case maxlen of
428− Just maxlen' -> when (S.length front + S.length bs > maxlen') $
428+ Just maxlen' -> when (S.length front > maxlen') $
429429 error "Header line length exceeds allowed maximum."
430430 Nothing -> return ()
431431 if S.null bs
@@ -439,7 +439,12 @@ takeLine maxlen src =
439439 then go $ front `S.append` x
440440 else do
441441 when (S.length y > 1) $ leftover src $ S.drop 1 y
442− return $ Just $ killCR $ front `S.append` x
442+ let res = front `S.append` x
443+ case maxlen of
444+ Just maxlen' -> when (S.length res > maxlen') $
445+ error "Header line length exceeds allowed maximum."
446+ Nothing -> return ()
447+ return $ Just $ killCR $ res
443448
444449takeLines' :: Maybe Int -> Maybe Int -> Source -> IO [S.ByteString]
445450takeLines' lineLength maxLines source =
@@ -634,7 +639,7 @@ wrapTillBound bound src max' = do
634639 return $ front bs
635640 else push $ front bs
636641 where
637− push bs =
642+ push bs = do
638643 case findBound bound bs of
639644 FoundBound before after -> do
640645 let before' = killCRLF before
wai-extra/test/Network/Wai/ParseSpec.hs+15−14
@@ -104,38 +104,38 @@ caseParseRequestBody = do
104104 result3' `shouldBe` expected3
105105
106106 it "parsing with memory limit" $ do
107− SRequest req4 bod4 <- toRequest'' ctype3 content3
107+ SRequest req4 _bod4 <- toRequest'' ctype3 content3
108108 result4' <- parseRequestBodyEx ( setMaxRequestNumFiles 1 $ setMaxRequestKeyLength 14 def ) lbsBackEnd req4
109109 result4' `shouldBe` expected3
110110
111111 it "exceeding number of files" $ do
112− SRequest req4 bod4 <- toRequest'' ctype3 content3
112+ SRequest req4 _bod4 <- toRequest'' ctype3 content3
113113 (parseRequestBodyEx ( setMaxRequestNumFiles 0 def ) lbsBackEnd req4) `shouldThrow` anyErrorCall
114114
115115 it "exceeding parameter length" $ do
116− SRequest req4 bod4 <- toRequest'' ctype3 content3
116+ SRequest req4 _bod4 <- toRequest'' ctype3 content3
117117 (parseRequestBodyEx ( setMaxRequestKeyLength 2 def ) lbsBackEnd req4) `shouldThrow` anyErrorCall
118118
119119 it "exceeding file size" $ do
120− SRequest req4 bod4 <- toRequest'' ctype3 content3
120+ SRequest req4 _bod4 <- toRequest'' ctype3 content3
121121 (parseRequestBodyEx ( setMaxRequestFileSize 2 def ) lbsBackEnd req4) `shouldThrow` anyErrorCall
122122
123123 it "exceeding total file size" $ do
124− SRequest req4 bod4 <- toRequest'' ctype3 content3
124+ SRequest req4 _bod4 <- toRequest'' ctype3 content3
125125 (parseRequestBodyEx ( setMaxRequestFilesSize 20 def ) lbsBackEnd req4) `shouldThrow` anyErrorCall
126− SRequest req5 bod5 <- toRequest'' ctype3 content5
126+ SRequest req5 _bod5 <- toRequest'' ctype3 content5
127127 (parseRequestBodyEx ( setMaxRequestFilesSize 20 def ) lbsBackEnd req5) `shouldThrow` anyErrorCall
128128
129129 it "exceeding max parm value size" $ do
130− SRequest req4 bod4 <- toRequest'' ctype2 content2
130+ SRequest req4 _bod4 <- toRequest'' ctype2 content2
131131 (parseRequestBodyEx ( setMaxRequestParmsSize 10 def ) lbsBackEnd req4) `shouldThrow` anyErrorCall
132132
133133 it "exceeding max header lines" $ do
134− SRequest req4 bod4 <- toRequest'' ctype2 content2
134+ SRequest req4 _bod4 <- toRequest'' ctype2 content2
135135 (parseRequestBodyEx ( setMaxHeaderLines 1 def ) lbsBackEnd req4) `shouldThrow` anyErrorCall
136136
137137 it "exceeding header line size" $ do
138− SRequest req4 bod4 <- toRequest'' ctype2 content4
138+ SRequest req4 _bod4 <- toRequest'' ctype3 content4
139139 (parseRequestBodyEx ( setMaxHeaderLineLength 8190 def ) lbsBackEnd req4) `shouldThrow` anyErrorCall
140140
141141 it "Testing parseRequestBodyEx with application/x-www-form-urlencoded" $ do
@@ -177,13 +177,14 @@ caseParseRequestBody = do
177177 <> "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh--\r\n"
178178 content4 =
179179 "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh\r\n"
180− <> "Content-Disposition: form-data; name=\"yaml\"; filename=\"README\"\r\n"
180+ <> "Content-Disposition: form-data; name=\"alb\"; filename=\"README\"\r\n"
181181 <> "Content-Type: application/octet-stream\r\n\r\n"
182− <> "Photo blog using Hack.\n\r\n"
182+ <> "Photo blog using Hack.\r\n\r\n"
183183 <> "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh\r\n"
184− <> "Content-Disposition: form-data; name=\"bla\"; filename=\"riedmie\"\r\n"
185− <> "Content-Type: application/octet-stream=TOOLONG=" <> S8.replicate 8192 '=' <> "\r\n\r\n"
186− <> "Photo blog using Hack.\n\r\n"
184+ <> "Content-Disposition: form-data; name=\"bla\"; filename=\"riedmi"
185+ <> S8.replicate 8190 'e' <> "\"\r\n"
186+ <> "Content-Type: application/octet-stream\r\n\r\n"
187+ <> "Photo blog using Hack.\r\n\r\n"
187188 <> "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh--\r\n"
188189 content5 =
189190 "------WebKitFormBoundaryB1pWXPZ6lNr8RiLh\r\n"
wai-extra/wai-extra.cabal+1−1
@@ -1,5 +1,5 @@
11Name: wai-extra
2−Version: 3.0.16.0
2+Version: 3.0.16.1
33Synopsis: Provides some basic WAI handlers and middleware.
44description:
55 Provides basic WAI handler and middleware functionality: