mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Merge pull request from GHSA-48w2-rm65-62xx
* Fix HTTP request smuggling vulnerability See GHSA-48w2-rm65-62xx or CVE-2021-41136 for more info. * 4.3.9 release note * 5.5.1 release note * 5.5.1
This commit is contained in:
parent
61dd7f4670
commit
acdc3ae571
6 changed files with 95 additions and 48 deletions
10
History.md
10
History.md
|
@ -1,3 +1,8 @@
|
|||
## 5.5.1 / 2021-10-12
|
||||
|
||||
* Security
|
||||
* Do not allow LF as a line ending in a header (CVE-2021-41136)
|
||||
|
||||
## 5.5.0 / 2021-09-19
|
||||
|
||||
* Features
|
||||
|
@ -251,6 +256,11 @@
|
|||
* Support parallel tests in verbose progress reporting ([#2223])
|
||||
* Refactor error handling in server accept loop ([#2239])
|
||||
|
||||
## 4.3.9 / 2021-10-12
|
||||
|
||||
* Security
|
||||
* Do not allow LF as a line ending in a header (CVE-2021-41136)
|
||||
|
||||
## 4.3.8 / 2021-05-11
|
||||
|
||||
* Security
|
||||
|
|
|
@ -426,10 +426,13 @@ st18:
|
|||
case 18:
|
||||
#line 428 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 9: goto tr25;
|
||||
case 13: goto tr26;
|
||||
case 32: goto tr27;
|
||||
}
|
||||
goto tr25;
|
||||
if ( 33 <= (*p) && (*p) <= 126 )
|
||||
goto tr25;
|
||||
goto st0;
|
||||
tr25:
|
||||
#line 46 "ext/puma_http11/http11_parser.rl"
|
||||
{ MARK(mark, p); }
|
||||
|
@ -438,10 +441,14 @@ st19:
|
|||
if ( ++p == pe )
|
||||
goto _test_eof19;
|
||||
case 19:
|
||||
#line 442 "ext/puma_http11/http11_parser.c"
|
||||
if ( (*p) == 13 )
|
||||
goto tr29;
|
||||
goto st19;
|
||||
#line 445 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 9: goto st19;
|
||||
case 13: goto tr29;
|
||||
}
|
||||
if ( 32 <= (*p) && (*p) <= 126 )
|
||||
goto st19;
|
||||
goto st0;
|
||||
tr9:
|
||||
#line 53 "ext/puma_http11/http11_parser.rl"
|
||||
{
|
||||
|
@ -484,7 +491,7 @@ st20:
|
|||
if ( ++p == pe )
|
||||
goto _test_eof20;
|
||||
case 20:
|
||||
#line 488 "ext/puma_http11/http11_parser.c"
|
||||
#line 495 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr31;
|
||||
case 60: goto st0;
|
||||
|
@ -505,7 +512,7 @@ st21:
|
|||
if ( ++p == pe )
|
||||
goto _test_eof21;
|
||||
case 21:
|
||||
#line 509 "ext/puma_http11/http11_parser.c"
|
||||
#line 516 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr33;
|
||||
case 60: goto st0;
|
||||
|
@ -526,7 +533,7 @@ st22:
|
|||
if ( ++p == pe )
|
||||
goto _test_eof22;
|
||||
case 22:
|
||||
#line 530 "ext/puma_http11/http11_parser.c"
|
||||
#line 537 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 43: goto st22;
|
||||
case 58: goto st23;
|
||||
|
@ -551,7 +558,7 @@ st23:
|
|||
if ( ++p == pe )
|
||||
goto _test_eof23;
|
||||
case 23:
|
||||
#line 555 "ext/puma_http11/http11_parser.c"
|
||||
#line 562 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr8;
|
||||
case 34: goto st0;
|
||||
|
@ -571,7 +578,7 @@ st24:
|
|||
if ( ++p == pe )
|
||||
goto _test_eof24;
|
||||
case 24:
|
||||
#line 575 "ext/puma_http11/http11_parser.c"
|
||||
#line 582 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr37;
|
||||
case 34: goto st0;
|
||||
|
@ -594,7 +601,7 @@ st25:
|
|||
if ( ++p == pe )
|
||||
goto _test_eof25;
|
||||
case 25:
|
||||
#line 598 "ext/puma_http11/http11_parser.c"
|
||||
#line 605 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr41;
|
||||
case 34: goto st0;
|
||||
|
@ -614,7 +621,7 @@ st26:
|
|||
if ( ++p == pe )
|
||||
goto _test_eof26;
|
||||
case 26:
|
||||
#line 618 "ext/puma_http11/http11_parser.c"
|
||||
#line 625 "ext/puma_http11/http11_parser.c"
|
||||
switch( (*p) ) {
|
||||
case 32: goto tr44;
|
||||
case 34: goto st0;
|
||||
|
|
|
@ -43,7 +43,7 @@
|
|||
|
||||
field_name = ( token -- ":" )+ >start_field $snake_upcase_field %write_field;
|
||||
|
||||
field_value = any* >start_value %write_value;
|
||||
field_value = ( print | "\t" )* >start_value %write_value;
|
||||
|
||||
message_header = field_name ":" " "* field_value :> CRLF;
|
||||
|
||||
|
|
|
@ -34,9 +34,9 @@ private static short[] init__puma_parser_key_offsets_0()
|
|||
{
|
||||
return new short [] {
|
||||
0, 0, 8, 17, 27, 29, 30, 31, 32, 33, 34, 36,
|
||||
39, 41, 44, 45, 61, 62, 78, 80, 81, 89, 97, 107,
|
||||
115, 124, 132, 140, 149, 158, 167, 176, 185, 194, 203, 212,
|
||||
221, 230, 239, 248, 257, 266, 275, 284, 293, 302, 303
|
||||
39, 41, 44, 45, 61, 62, 78, 83, 87, 95, 103, 113,
|
||||
121, 130, 138, 146, 155, 164, 173, 182, 191, 200, 209, 218,
|
||||
227, 236, 245, 254, 263, 272, 281, 290, 299, 308, 309
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -52,14 +52,13 @@ private static char[] init__puma_parser_trans_keys_0()
|
|||
46, 48, 57, 48, 57, 13, 48, 57, 10, 13, 33, 124,
|
||||
126, 35, 39, 42, 43, 45, 46, 48, 57, 65, 90, 94,
|
||||
122, 10, 33, 58, 124, 126, 35, 39, 42, 43, 45, 46,
|
||||
48, 57, 65, 90, 94, 122, 13, 32, 13, 32, 60, 62,
|
||||
127, 0, 31, 34, 35, 32, 60, 62, 127, 0, 31, 34,
|
||||
35, 43, 58, 45, 46, 48, 57, 65, 90, 97, 122, 32,
|
||||
34, 35, 60, 62, 127, 0, 31, 32, 34, 35, 60, 62,
|
||||
63, 127, 0, 31, 32, 34, 35, 60, 62, 127, 0, 31,
|
||||
32, 34, 35, 60, 62, 127, 0, 31, 32, 36, 95, 45,
|
||||
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
|
||||
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
|
||||
48, 57, 65, 90, 94, 122, 9, 13, 32, 33, 126, 9,
|
||||
13, 32, 126, 32, 60, 62, 127, 0, 31, 34, 35, 32,
|
||||
60, 62, 127, 0, 31, 34, 35, 43, 58, 45, 46, 48,
|
||||
57, 65, 90, 97, 122, 32, 34, 35, 60, 62, 127, 0,
|
||||
31, 32, 34, 35, 60, 62, 63, 127, 0, 31, 32, 34,
|
||||
35, 60, 62, 127, 0, 31, 32, 34, 35, 60, 62, 127,
|
||||
0, 31, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
|
||||
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
|
||||
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
|
||||
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
|
||||
|
@ -71,7 +70,8 @@ private static char[] init__puma_parser_trans_keys_0()
|
|||
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
|
||||
36, 95, 45, 46, 48, 57, 65, 90, 32, 36, 95, 45,
|
||||
46, 48, 57, 65, 90, 32, 36, 95, 45, 46, 48, 57,
|
||||
65, 90, 32, 0
|
||||
65, 90, 32, 36, 95, 45, 46, 48, 57, 65, 90, 32,
|
||||
36, 95, 45, 46, 48, 57, 65, 90, 32, 0
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -82,7 +82,7 @@ private static byte[] init__puma_parser_single_lengths_0()
|
|||
{
|
||||
return new byte [] {
|
||||
0, 2, 3, 4, 2, 1, 1, 1, 1, 1, 0, 1,
|
||||
0, 1, 1, 4, 1, 4, 2, 1, 4, 4, 2, 6,
|
||||
0, 1, 1, 4, 1, 4, 3, 2, 4, 4, 2, 6,
|
||||
7, 6, 6, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 0
|
||||
};
|
||||
|
@ -95,7 +95,7 @@ private static byte[] init__puma_parser_range_lengths_0()
|
|||
{
|
||||
return new byte [] {
|
||||
0, 3, 3, 3, 0, 0, 0, 0, 0, 0, 1, 1,
|
||||
1, 1, 0, 6, 0, 6, 0, 0, 2, 2, 4, 1,
|
||||
1, 1, 0, 6, 0, 6, 1, 1, 2, 2, 4, 1,
|
||||
1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3,
|
||||
3, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0
|
||||
};
|
||||
|
@ -108,9 +108,9 @@ private static short[] init__puma_parser_index_offsets_0()
|
|||
{
|
||||
return new short [] {
|
||||
0, 0, 6, 13, 21, 24, 26, 28, 30, 32, 34, 36,
|
||||
39, 41, 44, 46, 57, 59, 70, 73, 75, 82, 89, 96,
|
||||
104, 113, 121, 129, 136, 143, 150, 157, 164, 171, 178, 185,
|
||||
192, 199, 206, 213, 220, 227, 234, 241, 248, 255, 257
|
||||
39, 41, 44, 46, 57, 59, 70, 75, 79, 86, 93, 100,
|
||||
108, 117, 125, 133, 140, 147, 154, 161, 168, 175, 182, 189,
|
||||
196, 203, 210, 217, 224, 231, 238, 245, 252, 259, 261
|
||||
};
|
||||
}
|
||||
|
||||
|
@ -125,23 +125,23 @@ private static byte[] init__puma_parser_indicies_0()
|
|||
10, 1, 11, 1, 12, 1, 13, 1, 14, 1, 15, 1,
|
||||
16, 15, 1, 17, 1, 18, 17, 1, 19, 1, 20, 21,
|
||||
21, 21, 21, 21, 21, 21, 21, 21, 1, 22, 1, 23,
|
||||
24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 26, 27,
|
||||
25, 29, 28, 30, 1, 1, 1, 1, 1, 31, 32, 1,
|
||||
1, 1, 1, 1, 33, 34, 35, 34, 34, 34, 34, 1,
|
||||
8, 1, 9, 1, 1, 1, 1, 35, 36, 1, 38, 1,
|
||||
1, 39, 1, 1, 37, 40, 1, 42, 1, 1, 1, 1,
|
||||
41, 43, 1, 45, 1, 1, 1, 1, 44, 2, 46, 46,
|
||||
46, 46, 46, 1, 2, 47, 47, 47, 47, 47, 1, 2,
|
||||
48, 48, 48, 48, 48, 1, 2, 49, 49, 49, 49, 49,
|
||||
1, 2, 50, 50, 50, 50, 50, 1, 2, 51, 51, 51,
|
||||
51, 51, 1, 2, 52, 52, 52, 52, 52, 1, 2, 53,
|
||||
53, 53, 53, 53, 1, 2, 54, 54, 54, 54, 54, 1,
|
||||
2, 55, 55, 55, 55, 55, 1, 2, 56, 56, 56, 56,
|
||||
56, 1, 2, 57, 57, 57, 57, 57, 1, 2, 58, 58,
|
||||
58, 58, 58, 1, 2, 59, 59, 59, 59, 59, 1, 2,
|
||||
60, 60, 60, 60, 60, 1, 2, 61, 61, 61, 61, 61,
|
||||
1, 2, 62, 62, 62, 62, 62, 1, 2, 63, 63, 63,
|
||||
63, 63, 1, 2, 1, 1, 0
|
||||
24, 23, 23, 23, 23, 23, 23, 23, 23, 1, 25, 26,
|
||||
27, 25, 1, 28, 29, 28, 1, 30, 1, 1, 1, 1,
|
||||
1, 31, 32, 1, 1, 1, 1, 1, 33, 34, 35, 34,
|
||||
34, 34, 34, 1, 8, 1, 9, 1, 1, 1, 1, 35,
|
||||
36, 1, 38, 1, 1, 39, 1, 1, 37, 40, 1, 42,
|
||||
1, 1, 1, 1, 41, 43, 1, 45, 1, 1, 1, 1,
|
||||
44, 2, 46, 46, 46, 46, 46, 1, 2, 47, 47, 47,
|
||||
47, 47, 1, 2, 48, 48, 48, 48, 48, 1, 2, 49,
|
||||
49, 49, 49, 49, 1, 2, 50, 50, 50, 50, 50, 1,
|
||||
2, 51, 51, 51, 51, 51, 1, 2, 52, 52, 52, 52,
|
||||
52, 1, 2, 53, 53, 53, 53, 53, 1, 2, 54, 54,
|
||||
54, 54, 54, 1, 2, 55, 55, 55, 55, 55, 1, 2,
|
||||
56, 56, 56, 56, 56, 1, 2, 57, 57, 57, 57, 57,
|
||||
1, 2, 58, 58, 58, 58, 58, 1, 2, 59, 59, 59,
|
||||
59, 59, 1, 2, 60, 60, 60, 60, 60, 1, 2, 61,
|
||||
61, 61, 61, 61, 1, 2, 62, 62, 62, 62, 62, 1,
|
||||
2, 63, 63, 63, 63, 63, 1, 2, 1, 1, 0
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -100,7 +100,7 @@ module Puma
|
|||
# too taxing on performance.
|
||||
module Const
|
||||
|
||||
PUMA_VERSION = VERSION = "5.5.0".freeze
|
||||
PUMA_VERSION = VERSION = "5.5.1".freeze
|
||||
CODE_NAME = "Zawgyi".freeze
|
||||
|
||||
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
||||
|
|
|
@ -208,4 +208,34 @@ class Http11ParserTest < Minitest::Test
|
|||
|
||||
assert_equal "Strip This", req["HTTP_X_STRIP_ME"]
|
||||
end
|
||||
|
||||
def test_newline_smuggler
|
||||
parser = Puma::HttpParser.new
|
||||
req = {}
|
||||
http = "GET / HTTP/1.1\r\nHost: localhost:8080\r\nDummy: x\nDummy2: y\r\n\r\n"
|
||||
|
||||
parser.execute(req, http, 0) rescue nil # We test the raise elsewhere.
|
||||
|
||||
assert parser.error?, "Parser SHOULD have error"
|
||||
end
|
||||
|
||||
def test_newline_smuggler_two
|
||||
parser = Puma::HttpParser.new
|
||||
req = {}
|
||||
http = "GET / HTTP/1.1\r\nHost: localhost:8080\r\nDummy: x\r\nDummy: y\nDummy2: z\r\n\r\n"
|
||||
|
||||
parser.execute(req, http, 0) rescue nil
|
||||
|
||||
assert parser.error?, "Parser SHOULD have error"
|
||||
end
|
||||
|
||||
def test_htab_in_header_val
|
||||
parser = Puma::HttpParser.new
|
||||
req = {}
|
||||
http = "GET / HTTP/1.1\r\nHost: localhost:8080\r\nDummy: Valid\tValue\r\n\r\n"
|
||||
|
||||
parser.execute(req, http, 0)
|
||||
|
||||
assert_equal "Valid\tValue", req['HTTP_DUMMY']
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue