@@ -395,7 +395,7 @@ describe('Body Parser Middleware', () => {
395395 const middleware = bodyParser ( )
396396 await middleware ( req , next )
397397
398- expect ( req . body ) . toEqual ( { } )
398+ expect ( req . body ) . toBeUndefined ( )
399399 expect ( next ) . toHaveBeenCalled ( )
400400 } )
401401
@@ -899,8 +899,8 @@ describe('Body Parser Middleware', () => {
899899 } )
900900
901901 it ( 'should handle non-string, non-number limit values' , ( ) => {
902- expect ( parseLimit ( null ) ) . toBe ( 1024 * 1024 ) // Default 1MB
903- expect ( parseLimit ( undefined ) ) . toBe ( 1024 * 1024 ) // Default 1MB
902+ expect ( ( ) => parseLimit ( null ) ) . toThrow ( TypeError )
903+ expect ( ( ) => parseLimit ( undefined ) ) . toThrow ( TypeError )
904904 } )
905905
906906 it ( 'should handle custom JSON parser in main body parser' , async ( ) => {
@@ -1261,9 +1261,9 @@ describe('Body Parser Middleware', () => {
12611261
12621262 const { createTextParser} = require ( '../../lib/middleware/body-parser' )
12631263 const middleware = createTextParser ( )
1264- await expect ( middleware ( mockReq , ( ) => { } ) ) . rejects . toThrow (
1265- 'Text parsing failed' ,
1266- )
1264+ const response = await middleware ( mockReq , ( ) => { } )
1265+ expect ( response . status ) . toBe ( 400 )
1266+ expect ( await response . text ( ) ) . toBe ( 'Failed to read request body' )
12671267 } )
12681268
12691269 test ( 'should handle invalid content-length in URL-encoded parser' , async ( ) => {
@@ -1322,9 +1322,9 @@ describe('Body Parser Middleware', () => {
13221322 createURLEncodedParser,
13231323 } = require ( '../../lib/middleware/body-parser' )
13241324 const middleware = createURLEncodedParser ( )
1325- await expect ( middleware ( mockReq , ( ) => { } ) ) . rejects . toThrow (
1326- 'URL-encoded parsing failed' ,
1327- )
1325+ const response = await middleware ( mockReq , ( ) => { } )
1326+ expect ( response . status ) . toBe ( 400 )
1327+ expect ( await response . text ( ) ) . toBe ( 'Failed to read request body' )
13281328 } )
13291329
13301330 test ( 'should handle invalid content-length in multipart parser' , async ( ) => {
@@ -1607,9 +1607,9 @@ describe('Body Parser Middleware', () => {
16071607
16081608 const { createTextParser} = require ( '../../lib/middleware/body-parser' )
16091609 const middleware = createTextParser ( )
1610- await expect ( middleware ( mockReq , ( ) => { } ) ) . rejects . toThrow (
1611- 'Text reading failed' ,
1612- )
1610+ const response = await middleware ( mockReq , ( ) => { } )
1611+ expect ( response . status ) . toBe ( 400 )
1612+ expect ( await response . text ( ) ) . toBe ( 'Failed to read request body' )
16131613 } )
16141614
16151615 test ( 'should handle URL-encoded early return for non-matching content type (lines 360-361)' , async ( ) => {
@@ -1701,10 +1701,7 @@ describe('Body Parser Middleware', () => {
17011701 // This might not be possible due to the restrictive regex
17021702 expect ( ( ) => parseLimit ( '0.b' ) ) . toThrow ( 'Invalid limit format' )
17031703 } catch ( e ) {
1704- // If this doesn't work, the line might be unreachable
1705- console . log (
1706- 'Line 40 may be mathematically unreachable due to regex constraints' ,
1707- )
1704+ // Line 40 may be mathematically unreachable due to regex constraints
17081705 }
17091706 } )
17101707
@@ -1720,7 +1717,6 @@ describe('Body Parser Middleware', () => {
17201717 [ 'content-type' , 'application/x-www-form-urlencoded' ] ,
17211718 ] ) ,
17221719 text : async ( ) => 'simpleKey=simpleValue' , // Simple key without brackets
1723- _rawBodyText : 'simpleKey=simpleValue' ,
17241720 }
17251721
17261722 const urlEncodedParser = createURLEncodedParser ( {
@@ -1741,7 +1737,6 @@ describe('Body Parser Middleware', () => {
17411737 method : 'POST' ,
17421738 headers : new Map ( [ [ 'content-type' , 'application/json' ] ] ) ,
17431739 text : async ( ) => '' , // Empty string should be handled
1744- _rawBodyText : '' ,
17451740 }
17461741
17471742 const jsonParser = createJSONParser ( )
@@ -1815,7 +1810,6 @@ describe('Body Parser Middleware', () => {
18151810 [ 'content-length' , bodyContent . length . toString ( ) ] ,
18161811 ] ) ,
18171812 text : async ( ) => bodyContent ,
1818- _rawBodyText : bodyContent ,
18191813 }
18201814
18211815 const urlEncodedParser = createURLEncodedParser ( { limit : 500 } ) // Small limit
@@ -1870,3 +1864,67 @@ describe('Body Parser Middleware', () => {
18701864 } )
18711865 } )
18721866} )
1867+
1868+ describe ( 'RAW_BODY_SYMBOL Security (L-3)' , ( ) => {
1869+ const {
1870+ createJSONParser,
1871+ createTextParser,
1872+ createURLEncodedParser,
1873+ RAW_BODY_SYMBOL ,
1874+ } = require ( '../../lib/middleware/body-parser' )
1875+ const { createTestRequest} = require ( '../helpers' )
1876+
1877+ it ( 'should export RAW_BODY_SYMBOL' , ( ) => {
1878+ expect ( RAW_BODY_SYMBOL ) . toBeDefined ( )
1879+ expect ( typeof RAW_BODY_SYMBOL ) . toBe ( 'symbol' )
1880+ expect ( RAW_BODY_SYMBOL . toString ( ) ) . toBe ( 'Symbol(0http.rawBody)' )
1881+ } )
1882+
1883+ it ( 'should store raw body via Symbol in JSON parser' , async ( ) => {
1884+ const req = createTestRequest ( 'POST' , '/api/data' , {
1885+ headers : { 'Content-Type' : 'application/json' } ,
1886+ body : '{"key": "value"}' ,
1887+ } )
1888+
1889+ const parser = createJSONParser ( )
1890+ const next = jest . fn ( )
1891+ await parser ( req , next )
1892+
1893+ // Raw body should be accessible via Symbol
1894+ expect ( req [ RAW_BODY_SYMBOL ] ) . toBe ( '{"key": "value"}' )
1895+ // Raw body should NOT be accessible as a regular string property
1896+ expect ( req . _rawBodyText ) . toBeUndefined ( )
1897+ } )
1898+
1899+ it ( 'should store raw body via Symbol in text parser' , async ( ) => {
1900+ const req = createTestRequest ( 'POST' , '/api/data' , {
1901+ headers : { 'Content-Type' : 'text/plain' } ,
1902+ body : 'hello world' ,
1903+ } )
1904+
1905+ const parser = createTextParser ( )
1906+ const next = jest . fn ( )
1907+ await parser ( req , next )
1908+
1909+ expect ( req [ RAW_BODY_SYMBOL ] ) . toBe ( 'hello world' )
1910+ expect ( req . _rawBodyText ) . toBeUndefined ( )
1911+ } )
1912+
1913+ it ( 'should not expose raw body as enumerable property' , async ( ) => {
1914+ const req = createTestRequest ( 'POST' , '/api/data' , {
1915+ headers : { 'Content-Type' : 'application/json' } ,
1916+ body : '{"secret": "password123"}' ,
1917+ } )
1918+
1919+ const parser = createJSONParser ( )
1920+ const next = jest . fn ( )
1921+ await parser ( req , next )
1922+
1923+ // Symbol-keyed properties should not appear in Object.keys
1924+ const keys = Object . keys ( req )
1925+ expect ( keys ) . not . toContain ( '_rawBodyText' )
1926+ // The raw body should only be accessible via Symbol
1927+ expect ( req . _rawBodyText ) . toBeUndefined ( )
1928+ expect ( req [ RAW_BODY_SYMBOL ] ) . toBe ( '{"secret": "password123"}' )
1929+ } )
1930+ } )
0 commit comments