Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
108 changes: 87 additions & 21 deletions src/components/requestpolicyService.js
Original file line number Diff line number Diff line change
Expand Up @@ -1910,6 +1910,48 @@ RequestPolicyService.prototype = {
this._lastShouldLoadCheck.origin = originUri;
this._lastShouldLoadCheck.result = result;
},

/**
* unwrap URIs implementing nsINestedURI and view-source URIs
* to get at the underlying transport protocol
*
* @param nsIURI uri
* @return {nsIURI} The unwrapped URI
*/
_unWrapURI : function(uri) {
while(true) {
var oldSpec = requestpolicy.mod.DomainUtil.stripFragment(uri.spec);

// unwrap any sort of nested URI (jar uris, etc)
if(uri instanceof Components.interfaces.nsINestedURI) {
uri = uri.QueryInterface(Components.interfaces.nsINestedURI).innermostURI;
}
// view-source URIs are handled here as well, since they don't
// implement nsINestedURI even though they can be infinitely nested???
else if (uri.scheme == "view-source") {
//get everything after the initial scheme
var newSpec = oldSpec.split(":").slice(1).join(":");
uri = requestpolicy.mod.DomainUtil.getUriObject(newSpec);
}
// A meaningful, non-nestable uri, stop unwrapping.
else {
break;
}
}
return uri;
},

/**
* Check if a URI points to a local jar file
* @param nsIURI uri
* @return {Boolean} true if the URI points to a local jar file
*/
_isLocalJarURI: function(uri) {
if(uri.scheme == "jar") {
return (this._unWrapURI(uri).scheme == "file");
}
return false;
},

/**
* Determines if a request is only related to internal resources.
Expand Down Expand Up @@ -1944,6 +1986,23 @@ RequestPolicyService.prototype = {
if (aRequestOrigin == undefined || aRequestOrigin == null) {
return true;
}

// Special-case access to local jars by chrome and resource URIs
// This is necessary for resource:/// and probably some addons.

// TODO: Check if it's possible or necessary to lock this down more.
if (aRequestOrigin.scheme == "chrome"
|| aRequestOrigin.scheme == "resource"
|| this._isLocalJarURI(aRequestOrigin)) {
if(this._isLocalJarURI(aContentLocation)) {
return true;
}
}

// Done with special-casing jar URIs, unwrap jar URIs if we're dealing
// with any.
aContentLocation = this._unWrapURI(aContentLocation);
aRequestOrigin = this._unWrapURI(aRequestOrigin);

try {
// The asciiHost values will exist but be empty strings for the "file"
Expand Down Expand Up @@ -2023,7 +2082,7 @@ RequestPolicyService.prototype = {
}
return false;
},

// the content policy that does something useful
mainContentPolicy : {

Expand All @@ -2035,6 +2094,13 @@ RequestPolicyService.prototype = {
if (this._isInternalRequest(aContentLocation, aRequestOrigin)) {
return CP_OK;
}

// Remove useless jar and view-source schemes.
var aOldContentLocation = aContentLocation;
var aOldRequestOrigin = aRequestOrigin;

aContentLocation = this._unWrapURI(aContentLocation);
aRequestOrigin = this._unWrapURI(aRequestOrigin);

// We don't need to worry about ACE formatted IDNs because it seems
// that they'll automatically be converted to UTF8 format before we
Expand All @@ -2045,6 +2111,26 @@ RequestPolicyService.prototype = {
var dest = requestpolicy.mod.DomainUtil
.stripFragment(aContentLocation.spec);

// Log view-source and jar uris being unwrapped
if(aOldRequestOrigin != aRequestOrigin) {
var oldOrigin = requestpolicy.mod.DomainUtil
.stripFragment(aOldRequestOrigin.spec);

requestpolicy.mod.Logger.info(
requestpolicy.mod.Logger.TYPE_CONTENT,
"Considering origin <"
+ oldOrigin + "> to be origin <" + origin + ">");
}
if(aOldContentLocation != aContentLocation) {
var oldDest = requestpolicy.mod.DomainUtil
.stripFragment(aOldContentLocation.spec);

requestpolicy.mod.Logger.info(
requestpolicy.mod.Logger.TYPE_CONTENT,
"Considering destination <"
+ oldDest + "> to be destination <" + dest + ">");
}

// Fx 16 changed the following: 1) we should be able to count on the
// referrer (aRequestOrigin) being set to something besides
// moz-nullprincipal when there is a referrer, and 2) the new argument
Expand Down Expand Up @@ -2075,26 +2161,6 @@ RequestPolicyService.prototype = {
aRequestOrigin = requestpolicy.mod.DomainUtil.getUriObject(origin);
}

if (aRequestOrigin.scheme == "view-source") {
var newOrigin = origin.split(":").slice(1).join(":");
requestpolicy.mod.Logger.info(
requestpolicy.mod.Logger.TYPE_CONTENT,
"Considering view-source origin <"
+ origin + "> to be origin <" + newOrigin + ">");
origin = newOrigin;
aRequestOrigin = requestpolicy.mod.DomainUtil.getUriObject(origin);
}

if (aContentLocation.scheme == "view-source") {
var newDest = dest.split(":").slice(1).join(":");
requestpolicy.mod.Logger.info(
requestpolicy.mod.Logger.TYPE_CONTENT,
"Considering view-source destination <"
+ dest + "> to be destination <" + newDest + ">");
dest = newDest;
aContentLocation = requestpolicy.mod.DomainUtil.getUriObject(dest);
}

if (origin == "about:blank" && aContext) {
var newOrigin;
if (aContext.documentURI && aContext.documentURI != "about:blank") {
Expand Down
23 changes: 23 additions & 0 deletions tests/uri_unwrapping_1.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<html>
<head>
</head>
<body>

<!-- The images will always fail to load due to security precautions in firefox,
instead, check the webserver logs to verify the GET was not made. -->
<p><img src="jar:http://127.0.0.1/cross-site-image.png!/foo" /></p>

<!-- Make sure regular view-source links are unwrapped -->
<p><img src="view-source:http://127.0.0.1/cross-site-image.png" /></p>

<!-- Make sure nested jar URIs get unwrapped (These may not work anyways) -->
<p><img src="jar:jar:http://127.0.0.1/cross-site-image.png!/foo!/bar" /></p>

<!-- Host should be fully unwrapped for view-source as well -->
<p><img src="jar:view-source:view-source:http://127.0.0.1/cross-site-image.png!/foo" /></p>

<!-- Make sure this doesn't break the resource:/// uri -->
<p><img src="resource:///chrome/browser/skin/classic/browser/Geolocation-16.png" /></p>

</body>
</html>
23 changes: 23 additions & 0 deletions tests/uri_unwrapping_2.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv='Content-Type' content='text/html; charset=utf-8'>
<title>RequestPolicy jar: URI Test</title>
</head>
<body>
<style>
/* RequestPolicy messes with the style attr when it blocks an image, detect it. */
#detectRP[style*="oL2nkwAAAAlwSFlzAAALEwAACxMBAJqcGAAAAAd0SU1FB"] {
height:100px;
width:100px;
display:block;
background:blue;
}
</style>
<img id="detectRP" src="http://garbage.domain/foo" />
<img style="height:100px !important; width:100px !important; display:block; background:green;" src="jar:http://garbage.domain/foo!/s" />
<p>If you only see a blue square above, congrats! RequestPolicy is blocking jar URIs properly.</p>
<p>If you see two squares, one green and one blue, cross-domain requests can be pushed through using the jar scheme.</p>
<p>If you see anything else... are you even using RequestPolicy?</p>
</body>
</html>