mirror of
https://github.com/jquery/jquery.git
synced 2024-11-23 02:54:22 +00:00
Attributes: Don't stringify attributes in the setter
Stringifying attributes in the setter was needed for IE <=9 but it breaks trusted types enforcement when setting a script `src` attribute. Note that this doesn't mean script execution works. Since jQuery disables all scripts by changing their type and then executes them by creating fresh script tags with proper `src` & possibly other attributes, this unwraps any trusted `src` wrappers, making the script not execute under strict CSP settings. We might try to fix it in the future in a separate change. Fixes gh-4948 Closes gh-4949
This commit is contained in:
parent
4fd6912bfd
commit
4250b62878
@ -50,7 +50,7 @@ jQuery.extend( {
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
elem.setAttribute( name, value + "" );
|
elem.setAttribute( name, value );
|
||||||
return value;
|
return value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -247,6 +247,12 @@ QUnit.assert.ok( true, "mock executed");';
|
|||||||
echo file_get_contents( __DIR__ . '/trusted-html.html' );
|
echo file_get_contents( __DIR__ . '/trusted-html.html' );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected function trustedTypesAttributes( $req ) {
|
||||||
|
header( "Content-Security-Policy: require-trusted-types-for 'script'; report-uri ./mock.php?action=cspLog" );
|
||||||
|
header( 'Content-type: text/html' );
|
||||||
|
echo file_get_contents( __DIR__ . '/trusted-types-attributes.html' );
|
||||||
|
}
|
||||||
|
|
||||||
protected function errorWithScript( $req ) {
|
protected function errorWithScript( $req ) {
|
||||||
header( 'HTTP/1.0 404 Not Found' );
|
header( 'HTTP/1.0 404 Not Found' );
|
||||||
if ( isset( $req->query['withScriptContentType'] ) ) {
|
if ( isset( $req->query['withScriptContentType'] ) ) {
|
||||||
|
61
test/data/trusted-types-attributes.html
Normal file
61
test/data/trusted-types-attributes.html
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta charset=utf-8 />
|
||||||
|
<title>Trusted HTML attribute tests</title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<div id="qunit-fixture"></div>
|
||||||
|
<script src="../../dist/jquery.js"></script>
|
||||||
|
<script src="iframeTest.js"></script>
|
||||||
|
<script>
|
||||||
|
var i, input, elem, policy,
|
||||||
|
results = [];
|
||||||
|
|
||||||
|
function runTests( messagePrefix, getTrustedScriptUrlWrapper ) {
|
||||||
|
try {
|
||||||
|
elem = jQuery( "<script><\/script>" )
|
||||||
|
.attr( "src", getTrustedScriptUrlWrapper( "trusted-types-attributes.js" ) );
|
||||||
|
elem.appendTo( document.body );
|
||||||
|
|
||||||
|
results.push( {
|
||||||
|
actual: elem.attr( "src" ),
|
||||||
|
expected: "trusted-types-attributes.js",
|
||||||
|
message: messagePrefix + ": script URL properly set"
|
||||||
|
} );
|
||||||
|
} catch ( e ) {
|
||||||
|
results.push( {
|
||||||
|
actual: "error thrown",
|
||||||
|
expected: "",
|
||||||
|
message: messagePrefix + ": error has been thrown"
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( typeof trustedTypes !== "undefined" ) {
|
||||||
|
policy = trustedTypes.createPolicy( "jquery-test-policy", {
|
||||||
|
createScriptURL: function( html ) {
|
||||||
|
return html;
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
|
runTests( "TrustedScriptURL", function wrapInTrustedScriptUrl( input ) {
|
||||||
|
return policy.createScriptURL( input );
|
||||||
|
} );
|
||||||
|
} else {
|
||||||
|
|
||||||
|
// No TrustedScriptURL support so let's at least run tests with object wrappers
|
||||||
|
// with a proper `toString` function. See trusted-html.html for more context.
|
||||||
|
runTests( "Object wrapper", function( input ) {
|
||||||
|
return {
|
||||||
|
toString: function toString() {
|
||||||
|
return input;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
|
||||||
|
startIframeTest( results );
|
||||||
|
</script>
|
||||||
|
</body>
|
||||||
|
</html>
|
1
test/data/trusted-types-attributes.js
Normal file
1
test/data/trusted-types-attributes.js
Normal file
@ -0,0 +1 @@
|
|||||||
|
window.testMessage = "script run";
|
@ -264,6 +264,14 @@ var mocks = {
|
|||||||
var body = fs.readFileSync( __dirname + "/data/trusted-html.html" ).toString();
|
var body = fs.readFileSync( __dirname + "/data/trusted-html.html" ).toString();
|
||||||
resp.end( body );
|
resp.end( body );
|
||||||
},
|
},
|
||||||
|
trustedTypesAttributes: function( req, resp ) {
|
||||||
|
resp.writeHead( 200, {
|
||||||
|
"Content-Type": "text/html",
|
||||||
|
"Content-Security-Policy": "require-trusted-types-for 'script'; report-uri /base/test/data/mock.php?action=cspLog"
|
||||||
|
} );
|
||||||
|
var body = fs.readFileSync( __dirname + "/data/trusted-types-attributes.html" ).toString();
|
||||||
|
resp.end( body );
|
||||||
|
},
|
||||||
errorWithScript: function( req, resp ) {
|
errorWithScript: function( req, resp ) {
|
||||||
if ( req.query.withScriptContentType ) {
|
if ( req.query.withScriptContentType ) {
|
||||||
resp.writeHead( 404, { "Content-Type": "application/javascript" } );
|
resp.writeHead( 404, { "Content-Type": "application/javascript" } );
|
||||||
|
@ -1764,3 +1764,23 @@ QUnit.test( "non-lowercase boolean attribute getters should not crash", function
|
|||||||
}
|
}
|
||||||
} );
|
} );
|
||||||
} );
|
} );
|
||||||
|
|
||||||
|
|
||||||
|
// Test trustedTypes support in browsers where they're supported (currently Chrome 83+).
|
||||||
|
// Browsers with no TrustedScriptURL support still run tests on object wrappers with
|
||||||
|
// a proper `toString` function.
|
||||||
|
testIframe(
|
||||||
|
"Basic TrustedScriptURL support (gh-4948)",
|
||||||
|
"mock.php?action=trustedTypesAttributes",
|
||||||
|
function( assert, jQuery, window, document, test ) {
|
||||||
|
var done = assert.async();
|
||||||
|
|
||||||
|
assert.expect( 1 );
|
||||||
|
|
||||||
|
test.forEach( function( result ) {
|
||||||
|
assert.deepEqual( result.actual, result.expected, result.message );
|
||||||
|
} );
|
||||||
|
|
||||||
|
supportjQuery.get( baseURL + "mock.php?action=cspClean" ).then( done );
|
||||||
|
}
|
||||||
|
);
|
||||||
|
Loading…
Reference in New Issue
Block a user