@@ -41,6 +41,36 @@ const { outHeadersKey, ondrain } = require('internal/http');
41
41
const { nextTick } = require ( 'internal/process/next_tick' ) ;
42
42
const is_reused_symbol = require ( 'internal/freelist' ) . symbols . is_reused_symbol ;
43
43
44
+ const REVERT_CVE_2018_12116 = process . REVERT_CVE_2018_12116 ;
45
+
46
+ // DO NOT USE: this is insecure. See CVE-2018-12116.
47
+ // The actual list of disallowed characters in regexp form is more like:
48
+ // /[^A-Za-z0-9\-._~!$&'()*+,;=/:@]/
49
+ // with an additional rule for ignoring percentage-escaped characters, but
50
+ // that's a) hard to capture in a regular expression that performs well, and
51
+ // b) possibly too restrictive for real-world usage. So instead we restrict the
52
+ // filter to just control characters and spaces.
53
+ //
54
+ // This function is used in the case of small paths, where manual character code
55
+ // checks can greatly outperform the equivalent regexp (tested in V8 5.4).
56
+ function isInvalidPath ( s ) {
57
+ var i = 0 ;
58
+ if ( s . charCodeAt ( 0 ) <= 32 ) return true ;
59
+ if ( ++ i >= s . length ) return false ;
60
+ if ( s . charCodeAt ( 1 ) <= 32 ) return true ;
61
+ if ( ++ i >= s . length ) return false ;
62
+ if ( s . charCodeAt ( 2 ) <= 32 ) return true ;
63
+ if ( ++ i >= s . length ) return false ;
64
+ if ( s . charCodeAt ( 3 ) <= 32 ) return true ;
65
+ if ( ++ i >= s . length ) return false ;
66
+ if ( s . charCodeAt ( 4 ) <= 32 ) return true ;
67
+ if ( ++ i >= s . length ) return false ;
68
+ if ( s . charCodeAt ( 5 ) <= 32 ) return true ;
69
+ ++ i ;
70
+ for ( ; i < s . length ; ++ i )
71
+ if ( s . charCodeAt ( i ) <= 32 ) return true ;
72
+ return false ;
73
+ }
44
74
const INVALID_PATH_REGEX = / [ ^ \u0021 - \u00ff ] / ;
45
75
46
76
function validateHost ( host , name ) {
@@ -92,7 +122,18 @@ function ClientRequest(options, cb) {
92
122
var path ;
93
123
if ( options . path ) {
94
124
path = String ( options . path ) ;
95
- if ( INVALID_PATH_REGEX . test ( path ) )
125
+ var invalidPath ;
126
+ if ( REVERT_CVE_2018_12116 ) {
Has a conversation. Original line has a conversation.
127
+ if ( path . length <= 39 ) { // Determined experimentally in V8 5.4
128
+ invalidPath = isInvalidPath ( path ) ;
129
+ } else {
130
+ invalidPath = / [ \u0000 - \u0020 ] / . test ( path ) ;
131
+ }
132
+ } else {
133
+ invalidPath = INVALID_PATH_REGEX . test ( path ) ;
134
+ }
135
+
136
+ if ( invalidPath )
96
137
throw new TypeError ( 'Request path contains unescaped characters' ) ;
97
138
}
98
139