mirror of
				https://github.com/puma/puma.git
				synced 2022-11-09 13:48:40 -05:00 
			
		
		
		
	4.3.9 (#2721)
* Fix HTTP request smuggling vulnerability See GHSA-48w2-rm65-62xx or CVE-2021-41136 for more info. * 4.3.9 release note * 4.3.9
This commit is contained in:
		
							parent
							
								
									b911c13f87
								
							
						
					
					
						commit
						fb6ad8f801
					
				
					 6 changed files with 90 additions and 48 deletions
				
			
		| 
						 | 
				
			
			@ -1,3 +1,8 @@
 | 
			
		|||
## 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
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -428,10 +428,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 44 "ext/puma_http11/http11_parser.rl"
 | 
			
		||||
	{ MARK(mark, p); }
 | 
			
		||||
| 
						 | 
				
			
			@ -440,10 +443,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 51 "ext/puma_http11/http11_parser.rl"
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			@ -486,7 +493,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -507,7 +514,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -528,7 +535,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -553,7 +560,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -573,7 +580,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -596,7 +603,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;
 | 
			
		||||
| 
						 | 
				
			
			@ -616,7 +623,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 = "4.3.8".freeze
 | 
			
		||||
    PUMA_VERSION = VERSION = "4.3.9".freeze
 | 
			
		||||
    CODE_NAME = "Mysterious Traveller".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…
	
	Add table
		Add a link
		
	
		Reference in a new issue