Skip to content

Commit

Permalink
Tests: Strip untypical callback parameter characters from mock.php
Browse files Browse the repository at this point in the history
Only allow alphanumeric characters & underscores for callback parameters.
The change is done both for the PHP server as well as the Node.js-based version.
This is only test code so we're not fixing any security issue but it happens
often enough that the whole jQuery repository directory structure is deployed
onto the server with PHP enabled that it makes is easy to introduce security
issues if this cleanup is not done.

Ref gh-4764
Closes gh-4871
  • Loading branch information
mgol authored Apr 13, 2021
1 parent 50e8e84 commit a702746
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 13 deletions.
22 changes: 14 additions & 8 deletions test/data/mock.php
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
<?php

/**
* Keep in sync with /test/middleware-mockserver.js
*/
function cleanCallback( $callback ) {
return preg_replace( '/[^a-z0-9_]/i', '', $callback );
}

class MockServer {
protected function contentType( $req ) {
$type = $req->query['contentType'];
Expand Down Expand Up @@ -65,7 +70,8 @@ protected function script( $req ) {
array_values( $req->headers )
);

echo $req->query['callback'] . "(" . json_encode( [ 'headers' => $headers ] ) . ")";
echo cleanCallback( $req->query['callback'] ) .
"(" . json_encode( [ 'headers' => $headers ] ) . ")";
} else {
echo 'QUnit.assert.ok( true, "mock executed" );';
}
Expand Down Expand Up @@ -105,17 +111,17 @@ protected function jsonp( $req ) {
} else {
$callback = $_POST['callback'];
}
if ( isset( $req->query['array'] ) ) {
echo $callback . '([ {"name": "John", "age": 21}, {"name": "Peter", "age": 25 } ])';
} else {
echo $callback . '({ "data": {"lang": "en", "length": 25} })';
}
$json = isset( $req->query['array'] ) ?
'[ { "name": "John", "age": 21 }, { "name": "Peter", "age": 25 } ]' :
'{ "data": { "lang": "en", "length": 25 } }';
echo cleanCallback( $callback ) . '(' . $json . ')';
}

protected function xmlOverJsonp( $req ) {
$callback = $_REQUEST['callback'];
$cleanCallback = cleanCallback( $callback );
$text = json_encode( file_get_contents( __DIR__ . '/with_fries.xml' ) );
echo "$callback($text)\n";
echo "$cleanCallback($text)\n";
}

protected function error( $req ) {
Expand Down Expand Up @@ -243,7 +249,7 @@ protected function errorWithScript( $req ) {
}
if ( isset( $req->query['callback'] ) ) {
$callback = $req->query['callback'];
echo $callback . '( {"status": 404, "msg": "Not Found"} )';
echo cleanCallback( $callback ) . '( {"status": 404, "msg": "Not Found"} )';
} else {
echo 'QUnit.assert.ok( false, "Mock return erroneously executed" );';
}
Expand Down
15 changes: 10 additions & 5 deletions test/middleware-mockserver.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ var cspLog = "";
/**
* Keep in sync with /test/mock.php
*/
function cleanCallback( callback ) {
return callback.replace( /[^a-z0-9_]/gi, "" );
}

var mocks = {
contentType: function( req, resp ) {
resp.writeHead( 200, {
Expand Down Expand Up @@ -73,7 +77,7 @@ var mocks = {
}

if ( req.query.callback ) {
resp.end( req.query.callback + "(" + JSON.stringify( {
resp.end( cleanCallback( req.query.callback ) + "(" + JSON.stringify( {
headers: req.headers
} ) + ")" );
} else {
Expand Down Expand Up @@ -126,14 +130,14 @@ var mocks = {
{ data: { lang: "en", length: 25 } }
);
callback.then( function( cb ) {
resp.end( cb + "(" + json + ")" );
resp.end( cleanCallback( cb ) + "(" + json + ")" );
}, next );
},
xmlOverJsonp: function( req, resp ) {
var callback = req.query.callback;
var body = fs.readFileSync( __dirname + "/data/with_fries.xml" ).toString();
resp.writeHead( 200 );
resp.end( callback + "(" + JSON.stringify( body ) + ")\n" );
resp.end( cleanCallback( callback ) + "(" + JSON.stringify( body ) + ")\n" );
},
error: function( req, resp ) {
if ( req.query.json ) {
Expand Down Expand Up @@ -256,10 +260,11 @@ var mocks = {
if ( req.query.withScriptContentType ) {
resp.writeHead( 404, { "Content-Type": "application/javascript" } );
} else {
resp.writeHead( 404 );
resp.writeHead( 404, { "Content-Type": "text/html; charset=UTF-8" } );
}
if ( req.query.callback ) {
resp.end( req.query.callback + "( {\"status\": 404, \"msg\": \"Not Found\"} )" );
resp.end( cleanCallback( req.query.callback ) +
"( {\"status\": 404, \"msg\": \"Not Found\"} )" );
} else {
resp.end( "QUnit.assert.ok( false, \"Mock return erroneously executed\" );" );
}
Expand Down

0 comments on commit a702746

Please sign in to comment.