@@ -61,7 +61,7 @@ import type { TraceModel } from '@isomorphic/trace/traceModel';
6161import type { Entry } from '@trace/har' ;
6262
6363// The following function is derived from Chromium's source code
64- // https://github.com/ChromeDevTools/devtools-frontend/blob/83cbe41b4107e188a1f66fdf6ea3a9cca42587c6 /front_end/panels/network/NetworkLogView.ts#L2363
64+ // https://github.com/ChromeDevTools/devtools-frontend/blob/5d4c12362e84535371d8b966b0c7e421c236b720 /front_end/panels/network/NetworkLogView.ts#L2441
6565export async function generateCurlCommand ( model : TraceModel | undefined , resource : Entry ) : Promise < string > {
6666 const platform = navigator . platform . includes ( 'Win' ) ? 'win' : 'unix' ;
6767 let command : string [ ] = [ ] ;
@@ -96,14 +96,19 @@ export async function generateCurlCommand(model: TraceModel | undefined, resourc
9696 Lastly we replace new lines with ^ and TWO new lines because the first
9797 new line is there to enact the escape command the second is the character
9898 to escape (in this case new line).
99+
100+ All other whitespace characters are replaced with a single space, as there
101+ is no way to enter their literal values in a command line, and they do break
102+ the command allowing for injection.
99103 */
100104 const encapsChars = '^"' ;
101105 return encapsChars +
102106 str . replace ( / \\ / g, '\\\\' )
103107 . replace ( / " / g, '\\"' )
104108 . replace ( / [ ^ a - z A - Z 0 - 9 \s _ \- : = + ~ ' \/ . ' , ? ; ( ) * ` ] / g, '^$&' )
105109 . replace ( / % (? = [ a - z A - Z 0 - 9 _ ] ) / g, '%^' )
106- . replace ( / \r ? \n / g, '^\n\n' ) +
110+ . replace ( / [ ^ - ~ \r \n ] / g, ' ' )
111+ . replace ( / \r ? \n | \r / g, '^\n\n' ) +
107112 encapsChars ;
108113 }
109114
@@ -162,13 +167,16 @@ export async function generateCurlCommand(model: TraceModel | undefined, resourc
162167 if ( ignoredHeaders . has ( name . toLowerCase ( ) ) )
163168 continue ;
164169
165- if ( header . value . trim ( ) ) {
166- command . push ( '-H ' + escapeString ( name + ': ' + header . value ) ) ;
167- } else {
170+ const value = header . value ;
171+ if ( ! value . trim ( ) ) {
168172 // A header passed with -H with no value or only whitespace as its
169173 // value tells curl to not set the header at all. To post an empty
170174 // header, you have to terminate it with a semicolon.
171175 command . push ( '-H ' + escapeString ( name + ';' ) ) ;
176+ } else if ( name . toLowerCase ( ) === 'cookie' ) {
177+ command . push ( '-b ' + escapeString ( value ) ) ;
178+ } else {
179+ command . push ( '-H ' + escapeString ( name + ': ' + value ) ) ;
172180 }
173181 }
174182 command = command . concat ( data ) ;
0 commit comments