Skip to content

Commit

Permalink
Ignore mime type parameters in nosniff
Browse files Browse the repository at this point in the history
This patch implements the following changes:
- Only check for the toplevel/sublevel part of the mime type when
  deciding if it's a js or css resource, ignoring the mime parameters.
- Fix the wpt tests that did not escape url parameters properly and
  also used an invalid syntax for the mime parameter.
- Update the wpt manifest.
  • Loading branch information
fabricedesre authored and nox committed May 15, 2017
1 parent 34d0e59 commit 990b850
Show file tree
Hide file tree
Showing 6 changed files with 72 additions and 34 deletions.
8 changes: 4 additions & 4 deletions components/net/fetch/methods.rs
Expand Up @@ -559,10 +559,10 @@ pub fn should_be_blocked_due_to_nosniff(request_type: Type, response_headers: &H
mime!(Text / ("x-javascript")),
];

javascript_mime_types.contains(mime_type)
javascript_mime_types.iter()
.any(|mime| mime.0 == mime_type.0 && mime.1 == mime_type.1)
}

let text_css: Mime = mime!(Text / Css);
// Assumes str::starts_with is equivalent to mime::TopLevel
return match request_type {
// Step 6
Expand All @@ -575,8 +575,8 @@ pub fn should_be_blocked_due_to_nosniff(request_type: Type, response_headers: &H
// Step 7
Type::Style => {
match content_type_header {
Some(&ContentType(ref mime_type)) => mime_type != &text_css,
None => true
Some(&ContentType(Mime(TopLevel::Text, SubLevel::Css, _))) => false,
_ => true
}
}
// Step 8
Expand Down
8 changes: 4 additions & 4 deletions tests/wpt/metadata/MANIFEST.json
Expand Up @@ -558502,15 +558502,15 @@
"testharness"
],
"fetch/nosniff/image.html": [
"da847d5aa65fc5f52313b4434a84f1938061c7f6",
"2b31b5f05d843c55640943e68224cb36a1670a5e",
"testharness"
],
"fetch/nosniff/importscripts.html": [
"f48eb6fc81ba4d38a85f7908358fa62e29205b78",
"testharness"
],
"fetch/nosniff/importscripts.js": [
"90f5f826fcac39388c603e10b6b76d01a9238427",
"e7c02b40c457cc5347acb5a13d0ce14268b8187d",
"support"
],
"fetch/nosniff/parsing-nosniff.html": [
Expand Down Expand Up @@ -558558,11 +558558,11 @@
"support"
],
"fetch/nosniff/script.html": [
"7701124283e0714ef4229fbc6d63a26f8e5e86b1",
"762b6033a5b75465417f9921f7d06781ad036cbe",
"testharness"
],
"fetch/nosniff/stylesheet.html": [
"e2dda6ec5981c40dcad68c933336a0358639eec3",
"707b1031fc7594d49b6f1487c8ef71864791ea80",
"testharness"
],
"fetch/nosniff/worker.html": [
Expand Down
16 changes: 12 additions & 4 deletions tests/wpt/web-platform-tests/fetch/nosniff/image.html
Expand Up @@ -3,17 +3,25 @@
<div id=log></div>
<script>
// Note: images get always sniffed, nosniff doesn't do anything
var passes = ["", "?type=", "?type=x", "?type=x/x", "?type=image/gif", "?type=image/png", "?type=image/png;blah"]
var passes = [null, "", "x", "x/x", "image/gif", "image/png", "image/png;blah"]

passes.forEach(function(urlpart) {
const get_url = (mime) => {
let url = "resources/image.py"
if (mime != null) {
url += "?type=" + encodeURIComponent(mime)
}
return url
}

passes.forEach(function(mime) {
async_test(function(t) {
var img = document.createElement("img")
img.onerror = t.unreached_func("Unexpected error event")
img.onload = t.step_func_done(function(){
assert_equals(img.width, 96)
})
img.src = "resources/image.py" + urlpart
img.src = get_url(mime)
document.body.appendChild(img)
}, "URL query: " + urlpart)
}, "URL query: " + mime)
})
</script>
23 changes: 17 additions & 6 deletions tests/wpt/web-platform-tests/fetch/nosniff/importscripts.js
Expand Up @@ -3,15 +3,26 @@ function log(w) { this.postMessage(w) }
function f() { log("FAIL") }
function p() { log("PASS") }

["", "?type=", "?type=x", "?type=x/x"].forEach(function(urlpart) {
const get_url = (mime, outcome) => {
let url = "resources/js.py"
if (mime != null) {
url += "?type=" + encodeURIComponent(mime)
}
if (outcome) {
url += "&outcome=p"
}
return url
}

[null, "", "x", "x/x"].forEach(function(mime) {
try {
importScripts("resources/js.py" + urlpart)
importScripts(get_url(mime))
} catch(e) {
(e.name == "NetworkError") ? p() : log("FAIL (no NetworkError exception): " + urlpart)
(e.name == "NetworkError") ? p() : log("FAIL (no NetworkError exception): " + mime)
}

})
importScripts("resources/js.py?type=text/javascript&outcome=p")
importScripts("resources/js.py?type=text/ecmascript&outcome=p")
importScripts("resources/js.py?type=text/ecmascript;blah&outcome=p")
importScripts(get_url("text/javascript", true))
importScripts(get_url("text/ecmascript", true))
importScripts(get_url("text/ecmascript;blah", true))
log("END")
27 changes: 19 additions & 8 deletions tests/wpt/web-platform-tests/fetch/nosniff/script.html
Expand Up @@ -4,29 +4,40 @@
<script>
var log = function() {}, // see comment below
p = function() {}, // see comment below
fails = ["", "?type=", "?type=x", "?type=x/x"],
passes = ["?type=text/javascript", "?type=text/ecmascript", "?type=text/ecmascript;blah"]
fails = [null, "", "x", "x/x"],
passes = ["text/javascript", "text/ecmascript", "text/ecmascript;blah"]

// Ideally we'd also check whether the scripts in fact execute, but that would involve
// timers and might get a bit racy without cross-browser support for the execute events.

fails.forEach(function(urlpart) {
const get_url = (mime, outcome) => {
let url = "resources/js.py"
if (mime != null) {
url += "?type=" + encodeURIComponent(mime)
}
if (outcome) {
url += "&outcome=p"
}
return url
}

fails.forEach(function(mime) {
async_test(function(t) {
var script = document.createElement("script")
script.onerror = t.step_func_done(function(){})
script.onload = t.unreached_func("Unexpected load event")
script.src = "resources/js.py" + urlpart
script.src = get_url(mime)
document.body.appendChild(script)
}, "URL query: " + urlpart)
}, "URL query: " + mime)
})

passes.forEach(function(urlpart) {
passes.forEach(function(mime) {
async_test(function(t) {
var script = document.createElement("script")
script.onerror = t.unreached_func("Unexpected error event")
script.onload = t.step_func_done(function(){})
script.src = "resources/js.py" + urlpart + "&outcome=p"
script.src = get_url(mime, true)
document.body.appendChild(script)
}, "URL query: " + urlpart)
}, "URL query: " + mime)
})
</script>
24 changes: 16 additions & 8 deletions tests/wpt/web-platform-tests/fetch/nosniff/stylesheet.html
Expand Up @@ -3,28 +3,36 @@
<script src=/resources/testharnessreport.js></script>
<div id=log></div>
<script>
var fails = ["", "?type=", "?type=x", "?type=x/x"],
passes = ["?type=text/css", "?type=text/css;blah"]
var fails = [null, "", "x", "x/x"],
passes = ["text/css", "text/css;charset=utf-8", "text/css;blah"]

fails.forEach(function(urlpart) {
const get_url = (mime) => {
let url = "resources/css.py"
if (mime != null) {
url += "?type=" + encodeURIComponent(mime)
}
return url
}

fails.forEach(function(mime) {
async_test(function(t) {
var link = document.createElement("link")
link.rel = "stylesheet"
link.onerror = t.step_func_done(function(){})
link.onload = t.unreached_func("Unexpected load event")
link.href = "resources/css.py" + urlpart
link.href = get_url(mime)
document.body.appendChild(link)
}, "URL query: " + urlpart)
}, "URL query: " + mime)
})

passes.forEach(function(urlpart) {
passes.forEach(function(mime) {
async_test(function(t) {
var link = document.createElement("link")
link.rel = "stylesheet"
link.onerror = t.unreached_func("Unexpected error event")
link.onload = t.step_func_done(function(){})
link.href = "resources/css.py" + urlpart
link.href = get_url(mime)
document.body.appendChild(link)
}, "URL query: " + urlpart)
}, "URL query: " + mime)
})
</script>

0 comments on commit 990b850

Please sign in to comment.