Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commita6b9e90

Browse files
committed
Ajax: Avoid CSP errors in the script transport for async requests
Until now, the AJAX script transport only used a script tag to load scriptsfor cross-domain requests or ones with `scriptAttrs` set. This commit makesit also used for all async requests to avoid CSP errors arising from usageof inline scripts. This also makes `jQuery.getScript` not trigger CSP errorsas it uses the AJAX script transport under the hood.For sync requests such a change is impossible and that's what `jQuery._evalUrl`uses. Fixing that is tracked ingh-1895.The commit also makes other type of requests using the script tag version of thescript transport set its type to "GET", namely async scripts & ones with`scriptAttrs` set in addition to the existing cross-domain ones.Fixesgh-3969
1 parenta22b43b commita6b9e90

File tree

7 files changed

+81
-9
lines changed

7 files changed

+81
-9
lines changed

‎src/ajax/script.js

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,16 +32,20 @@ jQuery.ajaxPrefilter( "script", function( s ) {
3232
if(s.cache===undefined){
3333
s.cache=false;
3434
}
35-
if(s.crossDomain){
35+
36+
// These types of requests are handled via a script tag
37+
// so force their methods to GET.
38+
if(s.async||s.crossDomain||s.scriptAttrs){
3639
s.type="GET";
3740
}
3841
});
3942

4043
// Bind script tag hack transport
4144
jQuery.ajaxTransport("script",function(s){
4245

43-
// This transport only deals with cross domain or forced-by-attrs requests
44-
if(s.crossDomain||s.scriptAttrs){
46+
// This transport only deals with async, cross domain or forced-by-attrs requests.
47+
// Sync requests remain handled differently to preserve strict script ordering.
48+
if(s.async||s.crossDomain||s.scriptAttrs){
4549
varscript,callback;
4650
return{
4751
send:function(_,complete){
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
window.downloadedScriptCalled=true;

‎test/data/csp-ajax-script.html

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<metahttp-equiv="Content-Type"content="text/html; charset=utf-8"/>
5+
<title>jQuery.ajax() - script, CSP script-src compat (gh-3969)</title>
6+
<scriptsrc="../jquery.js"></script>
7+
<scriptsrc="iframeTest.js"></script>
8+
<scriptsrc="csp-ajax-script.js"></script>
9+
</head>
10+
<body>
11+
<p>CSP Test Page</p>
12+
</body>
13+
</html>

‎test/data/csp-ajax-script.js

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
/* global startIframeTest */
2+
3+
vartimeoutId,type;
4+
5+
functionfinalize(){
6+
startIframeTest(type,window.downloadedScriptCalled);
7+
}
8+
9+
timeoutId=setTimeout(function(){
10+
finalize();
11+
},1000);
12+
13+
jQuery
14+
.ajax({
15+
url:"csp-ajax-script-downloaded.js",
16+
dataType:"script",
17+
method:"POST",
18+
beforeSend:function(_jqXhr,settings){
19+
type=settings.type;
20+
}
21+
})
22+
.then(function(){
23+
clearTimeout(timeoutId);
24+
finalize();
25+
});

‎test/data/mock.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -195,22 +195,24 @@ protected function testHTML( $req ) {
195195
}
196196

197197
protectedfunctioncspFrame($req ) {
198-
// This is CSP only for browsers with "Content-Security-Policy" header support
199-
// i.e. no old WebKit or old Firefox
200198
header("Content-Security-Policy: default-src 'self'; report-uri ./mock.php?action=cspLog" );
201199
header('Content-type: text/html' );
202200
echofile_get_contents(__DIR__ .'/csp.include.html' );
203201
}
204202

205203
protectedfunctioncspNonce($req ) {
206-
// This is CSP only for browsers with "Content-Security-Policy" header support
207-
// i.e. no old WebKit or old Firefox
208204
$test =$req->query['test'] ?'-' .$req->query['test'] :'';
209205
header("Content-Security-Policy: script-src 'nonce-jquery+hardcoded+nonce'; report-uri ./mock.php?action=cspLog" );
210206
header('Content-type: text/html' );
211207
echofile_get_contents(__DIR__ .'/csp-nonce' .$test .'.html' );
212208
}
213209

210+
protectedfunctioncspAjaxScript($req ) {
211+
header("Content-Security-Policy: script-src 'self'; report-uri /base/test/data/mock.php?action=cspLog" );
212+
header('Content-type: text/html' );
213+
echofile_get_contents(__DIR__ .'/csp-ajax-script.html' );
214+
}
215+
214216
protectedfunctioncspLog($req ) {
215217
file_put_contents($this->cspFile,'error' );
216218
}

‎test/middleware-mockserver.js

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -222,6 +222,15 @@ var mocks = {
222222
__dirname+"/data/csp-nonce"+testParam+".html").toString();
223223
resp.end(body);
224224
},
225+
cspAjaxScript:function(req,resp){
226+
resp.writeHead(200,{
227+
"Content-Type":"text/html",
228+
"Content-Security-Policy":"script-src 'self'; report-uri /base/test/data/mock.php?action=cspLog"
229+
});
230+
varbody=fs.readFileSync(
231+
__dirname+"/data/csp-ajax-script.html").toString();
232+
resp.end(body);
233+
},
225234
cspLog:function(req,resp){
226235
cspLog="error";
227236
resp.writeHead(200);

‎test/unit/ajax.js

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -89,17 +89,21 @@ QUnit.module( "ajax", {
8989
}
9090
);
9191

92-
ajaxTest("jQuery.ajax() - custom attributes for script tag",4,
92+
ajaxTest("jQuery.ajax() - custom attributes for script tag",5,
9393
function(assert){
9494
return{
9595
create:function(options){
9696
varxhr;
97+
options.method="POST";
9798
options.dataType="script";
9899
options.scriptAttrs={id:"jquery-ajax-test",async:"async"};
99100
xhr=jQuery.ajax(url("mock.php?action=script"),options);
100101
assert.equal(jQuery("#jquery-ajax-test").attr("async"),"async","attr value");
101102
returnxhr;
102103
},
104+
beforeSend:function(_jqXhr,settings){
105+
assert.strictEqual(settings.type,"GET","Type changed to GET");
106+
},
103107
success:function(){
104108
assert.ok(true,"success");
105109
},
@@ -1356,6 +1360,17 @@ QUnit.module( "ajax", {
13561360

13571361
});
13581362

1363+
testIframe(
1364+
"jQuery.ajax() - script, CSP script-src compat (gh-3969)",
1365+
"mock.php?action=cspAjaxScript",
1366+
function(assert,jQuery,window,document,type,downloadedScriptCalled){
1367+
assert.expect(2);
1368+
1369+
assert.strictEqual(type,"GET","Type changed to GET");
1370+
assert.strictEqual(downloadedScriptCalled,true,"External script called");
1371+
}
1372+
);
1373+
13591374
ajaxTest("jQuery.ajax() - script, Remote",2,function(assert){
13601375
return{
13611376
setup:function(){
@@ -1369,12 +1384,15 @@ QUnit.module( "ajax", {
13691384
};
13701385
});
13711386

1372-
ajaxTest("jQuery.ajax() - script, Remote with POST",3,function(assert){
1387+
ajaxTest("jQuery.ajax() - script, Remote with POST",4,function(assert){
13731388
return{
13741389
setup:function(){
13751390
Globals.register("testBar");
13761391
},
13771392
url:url("mock.php?action=testbar"),
1393+
beforeSend:function(_jqXhr,settings){
1394+
assert.strictEqual(settings.type,"GET","Type changed to GET");
1395+
},
13781396
type:"POST",
13791397
dataType:"script",
13801398
success:function(data,status){

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp