зеркало из https://github.com/mozilla/pjs.git
Bug 693940: Restrict SVG-as-an-image to being able to load (local) URIs that have either the URI_INHERITS_SECURITY_CONTEXT or URI_LOADABLE_BY_SUBSUMERS flags. r=bz
This commit is contained in:
Родитель
c779bcb0fa
Коммит
80c639aa0a
|
@ -51,6 +51,17 @@
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS1(nsDataDocumentContentPolicy, nsIContentPolicy)
|
NS_IMPL_ISUPPORTS1(nsDataDocumentContentPolicy, nsIContentPolicy)
|
||||||
|
|
||||||
|
// Helper method for ShouldLoad()
|
||||||
|
// Checks a URI for the given flags. Returns true if the URI has the flags,
|
||||||
|
// and false if not (or if we weren't able to tell).
|
||||||
|
static bool
|
||||||
|
HasFlags(nsIURI* aURI, PRUint32 aURIFlags)
|
||||||
|
{
|
||||||
|
bool hasFlags;
|
||||||
|
nsresult rv = NS_URIChainHasFlags(aURI, aURIFlags, &hasFlags);
|
||||||
|
return NS_SUCCEEDED(rv) && hasFlags;
|
||||||
|
}
|
||||||
|
|
||||||
NS_IMETHODIMP
|
NS_IMETHODIMP
|
||||||
nsDataDocumentContentPolicy::ShouldLoad(PRUint32 aContentType,
|
nsDataDocumentContentPolicy::ShouldLoad(PRUint32 aContentType,
|
||||||
nsIURI *aContentLocation,
|
nsIURI *aContentLocation,
|
||||||
|
@ -87,21 +98,26 @@ nsDataDocumentContentPolicy::ShouldLoad(PRUint32 aContentType,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (doc->IsBeingUsedAsImage()) {
|
if (doc->IsBeingUsedAsImage()) {
|
||||||
// Allow local resources for SVG-as-an-image documents, but disallow
|
// We only allow SVG images to load content from URIs that are local and
|
||||||
// everything else, to prevent data leakage
|
// also satisfy one of the following conditions:
|
||||||
bool hasFlags;
|
// - URI inherits security context, e.g. data URIs
|
||||||
nsresult rv = NS_URIChainHasFlags(aContentLocation,
|
// OR
|
||||||
nsIProtocolHandler::URI_IS_LOCAL_RESOURCE,
|
// - URI loadable by subsumers, e.g. moz-filedata URIs
|
||||||
&hasFlags);
|
// Any URI that doesn't meet these requirements will be rejected below.
|
||||||
if (NS_FAILED(rv) || !hasFlags) {
|
if (!HasFlags(aContentLocation,
|
||||||
// resource is not local (or we couldn't tell) - reject!
|
nsIProtocolHandler::URI_IS_LOCAL_RESOURCE) ||
|
||||||
|
(!HasFlags(aContentLocation,
|
||||||
|
nsIProtocolHandler::URI_INHERITS_SECURITY_CONTEXT) &&
|
||||||
|
!HasFlags(aContentLocation,
|
||||||
|
nsIProtocolHandler::URI_LOADABLE_BY_SUBSUMERS))) {
|
||||||
*aDecision = nsIContentPolicy::REJECT_TYPE;
|
*aDecision = nsIContentPolicy::REJECT_TYPE;
|
||||||
|
|
||||||
// report error, if we can.
|
// Report error, if we can.
|
||||||
if (node) {
|
if (node) {
|
||||||
nsIPrincipal* requestingPrincipal = node->NodePrincipal();
|
nsIPrincipal* requestingPrincipal = node->NodePrincipal();
|
||||||
nsRefPtr<nsIURI> principalURI;
|
nsRefPtr<nsIURI> principalURI;
|
||||||
rv = requestingPrincipal->GetURI(getter_AddRefs(principalURI));
|
nsresult rv =
|
||||||
|
requestingPrincipal->GetURI(getter_AddRefs(principalURI));
|
||||||
if (NS_SUCCEEDED(rv) && principalURI) {
|
if (NS_SUCCEEDED(rv) && principalURI) {
|
||||||
nsScriptSecurityManager::ReportError(
|
nsScriptSecurityManager::ReportError(
|
||||||
nsnull, NS_LITERAL_STRING("CheckSameOriginError"), principalURI,
|
nsnull, NS_LITERAL_STRING("CheckSameOriginError"), principalURI,
|
||||||
|
@ -112,8 +128,8 @@ nsDataDocumentContentPolicy::ShouldLoad(PRUint32 aContentType,
|
||||||
doc->GetDocumentURI()) {
|
doc->GetDocumentURI()) {
|
||||||
// Check for (& disallow) recursive image-loads
|
// Check for (& disallow) recursive image-loads
|
||||||
bool isRecursiveLoad;
|
bool isRecursiveLoad;
|
||||||
rv = aContentLocation->EqualsExceptRef(doc->GetDocumentURI(),
|
nsresult rv = aContentLocation->EqualsExceptRef(doc->GetDocumentURI(),
|
||||||
&isRecursiveLoad);
|
&isRecursiveLoad);
|
||||||
if (NS_FAILED(rv) || isRecursiveLoad) {
|
if (NS_FAILED(rv) || isRecursiveLoad) {
|
||||||
NS_WARNING("Refusing to recursively load image");
|
NS_WARNING("Refusing to recursively load image");
|
||||||
*aDecision = nsIContentPolicy::REJECT_TYPE;
|
*aDecision = nsIContentPolicy::REJECT_TYPE;
|
||||||
|
|
|
@ -0,0 +1,37 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- This test checks to be sure we can render SVG-as-an-image
|
||||||
|
from a MozBlobBuilder-generated 'moz-filedata' URI. -->
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
function go() {
|
||||||
|
// Generate a moz-filedata URL encoding of an SVG document
|
||||||
|
var filedataURL = generateMozFiledataURL();
|
||||||
|
|
||||||
|
// Tell our img element to render the URL
|
||||||
|
var img = document.getElementsByTagName("img")[0]
|
||||||
|
img.src = filedataURL;
|
||||||
|
|
||||||
|
// Once our img loads, take reftest snapshot.
|
||||||
|
img.addEventListener("load", function() {
|
||||||
|
document.documentElement.removeAttribute("class");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function -- returns a moz-filedata URL representing a
|
||||||
|
// 100x100 fully-lime SVG document.
|
||||||
|
function generateMozFiledataURL() {
|
||||||
|
var blobBuilder = new self.MozBlobBuilder;
|
||||||
|
var svg =
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">' +
|
||||||
|
'<rect height="100%" width="100%" fill="lime"/>' +
|
||||||
|
'</svg>';
|
||||||
|
blobBuilder.append(svg);
|
||||||
|
return self.URL.createObjectURL(blobBuilder.getBlob("image/svg+xml"));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="go()">
|
||||||
|
<img src="">
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1,46 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<!-- This test checks to be sure we allow MozBlobBuilder-generated
|
||||||
|
'moz-filedata' URIs *inside of* SVG-as-an-image. -->
|
||||||
|
<html class="reftest-wait">
|
||||||
|
<head>
|
||||||
|
<script>
|
||||||
|
function go() {
|
||||||
|
// Generate a moz-filedata URL encoding of an SVG document
|
||||||
|
var filedataURL = generateMozFiledataURL();
|
||||||
|
|
||||||
|
// Now generate a data URI, containing our moz-filedata URI
|
||||||
|
var outerSVG =
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" ' +
|
||||||
|
'xmlns:xlink="http://www.w3.org/1999/xlink" ' +
|
||||||
|
'width="100" height="100">' +
|
||||||
|
'<image height="100" width="100" ' +
|
||||||
|
'xlink:href="' + filedataURL + '"/>' +
|
||||||
|
'</svg>';
|
||||||
|
|
||||||
|
// Tell our img element to render the URL
|
||||||
|
var img = document.getElementsByTagName("img")[0]
|
||||||
|
img.src = "data:image/svg+xml," + outerSVG;
|
||||||
|
|
||||||
|
// Once our img loads, take reftest snapshot.
|
||||||
|
img.addEventListener("load", function() {
|
||||||
|
document.documentElement.removeAttribute("class");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function -- returns a moz-filedata URL representing a
|
||||||
|
// 100x100 fully-lime SVG document.
|
||||||
|
function generateMozFiledataURL() {
|
||||||
|
var blobBuilder = new self.MozBlobBuilder;
|
||||||
|
var svg =
|
||||||
|
'<svg xmlns="http://www.w3.org/2000/svg" width="100" height="100">' +
|
||||||
|
'<rect height="100%" width="100%" fill="lime"/>' +
|
||||||
|
'</svg>';
|
||||||
|
blobBuilder.append(svg);
|
||||||
|
return self.URL.createObjectURL(blobBuilder.getBlob("image/svg+xml"));
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</head>
|
||||||
|
<body onload="go()">
|
||||||
|
<img src="">
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -55,6 +55,8 @@ fails == canvas-drawImage-slice-1b.html lime100x100-ref.html # XXX all edges fuz
|
||||||
random == img-and-image-1.html img-and-image-1-ref.svg # bug 645267
|
random == img-and-image-1.html img-and-image-1-ref.svg # bug 645267
|
||||||
|
|
||||||
# More complex <img> tests
|
# More complex <img> tests
|
||||||
|
== img-blobBuilder-1.html lime100x100-ref.html
|
||||||
|
== img-blobBuilder-2.html lime100x100-ref.html
|
||||||
== img-content-outside-viewBox-1.html img-content-outside-viewBox-1-ref.html
|
== img-content-outside-viewBox-1.html img-content-outside-viewBox-1-ref.html
|
||||||
== img-dyn-1.html img-dyn-1-ref.html
|
== img-dyn-1.html img-dyn-1-ref.html
|
||||||
== img-foreignObject-1.html lime100x100-ref.html
|
== img-foreignObject-1.html lime100x100-ref.html
|
||||||
|
@ -120,11 +122,11 @@ random == img-and-image-1.html img-and-image-1-ref.svg # bug 645267
|
||||||
# tests for external resources vs. data URIs in SVG as an image
|
# tests for external resources vs. data URIs in SVG as an image
|
||||||
== svg-image-datauri-1.html lime100x100.svg
|
== svg-image-datauri-1.html lime100x100.svg
|
||||||
HTTP == svg-image-datauri-1.html lime100x100.svg
|
HTTP == svg-image-datauri-1.html lime100x100.svg
|
||||||
fails-if(Android) == svg-image-external-1.html lime100x100.svg
|
== svg-image-external-1.html blue100x100.svg
|
||||||
HTTP == svg-image-external-1.html blue100x100.svg
|
HTTP == svg-image-external-1.html blue100x100.svg
|
||||||
== svg-stylesheet-datauri-1.html lime100x100.svg
|
== svg-stylesheet-datauri-1.html lime100x100.svg
|
||||||
HTTP == svg-stylesheet-datauri-1.html lime100x100.svg
|
HTTP == svg-stylesheet-datauri-1.html lime100x100.svg
|
||||||
random == svg-stylesheet-external-1.html lime100x100.svg # see bug 629885 comment 9
|
== svg-stylesheet-external-1.html blue100x100.svg
|
||||||
HTTP == svg-stylesheet-external-1.html blue100x100.svg
|
HTTP == svg-stylesheet-external-1.html blue100x100.svg
|
||||||
|
|
||||||
# test that :visited status is ignored in image documents
|
# test that :visited status is ignored in image documents
|
||||||
|
|
Загрузка…
Ссылка в новой задаче