Bug 641706: Make SpecialPowers able to create a XHR object with full system powers. r=smaug

This commit is contained in:
Jonas Sicking 2011-03-17 09:19:13 -07:00
Родитель ef31f6cfa2
Коммит 9a77da1530
5 изменённых файлов: 38 добавлений и 47 удалений

Просмотреть файл

@ -126,19 +126,16 @@
#define XML_HTTP_REQUEST_ABORTED (1 << 7) // Internal
#define XML_HTTP_REQUEST_ASYNC (1 << 8) // Internal
#define XML_HTTP_REQUEST_PARSEBODY (1 << 9) // Internal
#define XML_HTTP_REQUEST_XSITEENABLED (1 << 10) // Internal, Is any cross-site request allowed?
// Even if this is false the
// access-control spec is supported
#define XML_HTTP_REQUEST_SYNCLOOPING (1 << 11) // Internal
#define XML_HTTP_REQUEST_MULTIPART (1 << 12) // Internal
#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 13) // Internal
#define XML_HTTP_REQUEST_BACKGROUND (1 << 14) // Internal
#define XML_HTTP_REQUEST_SYNCLOOPING (1 << 10) // Internal
#define XML_HTTP_REQUEST_MULTIPART (1 << 11) // Internal
#define XML_HTTP_REQUEST_GOT_FINAL_STOP (1 << 12) // Internal
#define XML_HTTP_REQUEST_BACKGROUND (1 << 13) // Internal
// This is set when we've got the headers for a multipart XMLHttpRequest,
// but haven't yet started to process the first part.
#define XML_HTTP_REQUEST_MPART_HEADERS (1 << 15) // Internal
#define XML_HTTP_REQUEST_USE_XSITE_AC (1 << 16) // Internal
#define XML_HTTP_REQUEST_NEED_AC_PREFLIGHT (1 << 17) // Internal
#define XML_HTTP_REQUEST_AC_WITH_CREDENTIALS (1 << 18) // Internal
#define XML_HTTP_REQUEST_MPART_HEADERS (1 << 14) // Internal
#define XML_HTTP_REQUEST_USE_XSITE_AC (1 << 15) // Internal
#define XML_HTTP_REQUEST_NEED_AC_PREFLIGHT (1 << 16) // Internal
#define XML_HTTP_REQUEST_AC_WITH_CREDENTIALS (1 << 17) // Internal
#define XML_HTTP_REQUEST_LOADSTATES \
(XML_HTTP_REQUEST_UNINITIALIZED | \
@ -1639,14 +1636,12 @@ nsXMLHttpRequest::GetCurrentHttpChannel()
nsresult
nsXMLHttpRequest::CheckChannelForCrossSiteRequest(nsIChannel* aChannel)
{
// First check if cross-site requests are enabled
if ((mState & XML_HTTP_REQUEST_XSITEENABLED)) {
// First check if cross-site requests are enabled...
if (IsSystemXHR()) {
return NS_OK;
}
// or if this is a same-origin request.
NS_ASSERTION(!nsContentUtils::IsSystemPrincipal(mPrincipal),
"Shouldn't get here!");
// ...or if this is a same-origin request.
if (nsContentUtils::CheckMayLoad(mPrincipal, aChannel)) {
return NS_OK;
}
@ -1797,12 +1792,6 @@ nsXMLHttpRequest::OpenRequest(const nsACString& method,
channelPolicy);
if (NS_FAILED(rv)) return rv;
// Check if we're doing a cross-origin request.
if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
// Chrome callers are always allowed to read from different origins.
mState |= XML_HTTP_REQUEST_XSITEENABLED;
}
mState &= ~(XML_HTTP_REQUEST_USE_XSITE_AC |
XML_HTTP_REQUEST_NEED_AC_PREFLIGHT);
@ -1823,17 +1812,6 @@ nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url,
PRBool async, const nsAString& user,
const nsAString& password, PRUint8 optional_argc)
{
if (nsContentUtils::GetCurrentJSContext()) {
// We're (likely) called from JS
// Find out if UniversalBrowserRead privileges are enabled
if (nsContentUtils::IsCallerTrustedForRead()) {
mState |= XML_HTTP_REQUEST_XSITEENABLED;
} else {
mState &= ~XML_HTTP_REQUEST_XSITEENABLED;
}
}
if (!optional_argc) {
// No optional arguments were passed in. Default async to true.
async = PR_TRUE;
@ -1954,8 +1932,8 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
NS_ENSURE_TRUE(channel, NS_ERROR_UNEXPECTED);
nsCOMPtr<nsIPrincipal> documentPrincipal = mPrincipal;
if (nsContentUtils::IsSystemPrincipal(documentPrincipal)) {
nsCOMPtr<nsIPrincipal> documentPrincipal;
if (IsSystemXHR()) {
// Don't give this document the system principal. We need to keep track of
// mPrincipal being system because we use it for various security checks
// that should be passing, but the document data shouldn't get a system
@ -1963,6 +1941,8 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
nsresult rv;
documentPrincipal = do_CreateInstance("@mozilla.org/nullprincipal;1", &rv);
NS_ENSURE_SUCCESS(rv, rv);
} else {
documentPrincipal = mPrincipal;
}
channel->SetOwner(documentPrincipal);
@ -2040,7 +2020,7 @@ nsXMLHttpRequest::OnStartRequest(nsIRequest *request, nsISupports *ctxt)
nsCOMPtr<nsIDocument> responseDoc = do_QueryInterface(mResponseXML);
responseDoc->SetPrincipal(documentPrincipal);
if (nsContentUtils::IsSystemPrincipal(mPrincipal)) {
if (IsSystemXHR()) {
responseDoc->ForceEnableXULXBL();
}
@ -2420,7 +2400,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
if (httpChannel) {
httpChannel->GetRequestMethod(method); // If GET, method name will be uppercase
if (!nsContentUtils::IsSystemPrincipal(mPrincipal)) {
if (!IsSystemXHR()) {
// Get the referrer for the request.
//
// If it weren't for history.push/replaceState, we could just use the
@ -2656,7 +2636,7 @@ nsXMLHttpRequest::Send(nsIVariant *aBody)
}
}
if (!(mState & XML_HTTP_REQUEST_XSITEENABLED)) {
if (!IsSystemXHR()) {
// Always create a nsCrossSiteListenerProxy here even if it's
// a same-origin request right now, since it could be redirected.
listener = new nsCrossSiteListenerProxy(listener, mPrincipal, mChannel,
@ -2853,7 +2833,7 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
}
// Check for dangerous cross-site headers
PRBool safeHeader = !!(mState & XML_HTTP_REQUEST_XSITEENABLED);
bool safeHeader = IsSystemXHR();
if (!safeHeader) {
// Content-Type isn't always safe, but we'll deal with it in Send()
const char *kCrossOriginSafeHeaders[] = {
@ -2862,7 +2842,7 @@ nsXMLHttpRequest::SetRequestHeader(const nsACString& header,
};
for (i = 0; i < NS_ARRAY_LENGTH(kCrossOriginSafeHeaders); ++i) {
if (header.LowerCaseEqualsASCII(kCrossOriginSafeHeaders[i])) {
safeHeader = PR_TRUE;
safeHeader = true;
break;
}
}

Просмотреть файл

@ -69,6 +69,7 @@
#include "nsIPrivateDOMEvent.h"
#include "nsDOMProgressEvent.h"
#include "nsDOMEventTargetWrapperCache.h"
#include "nsContentUtils.h"
class nsILoadGroup;
class AsyncVerifyRedirectCallbackForwarder;
@ -333,6 +334,10 @@ protected:
already_AddRefed<nsIHttpChannel> GetCurrentHttpChannel();
bool IsSystemXHR() {
return !!nsContentUtils::IsSystemPrincipal(mPrincipal);
}
/**
* Check if aChannel is ok for a cross-site request by making sure no
* inappropriate headers are set, and no username/password is set.

Просмотреть файл

@ -22,9 +22,7 @@ https://bugzilla.mozilla.org/show_bug.cgi?id=426308
const SJS_URL = "http://example.org:80/tests/content/base/test/bug426308-redirect.sjs";
netscape.security.PrivilegeManager.enablePrivilege("UniversalBrowserRead");
var req = new XMLHttpRequest();
var req = SpecialPowers.createSystemXHR();
req.open("GET", SJS_URL + "?" + window.location.href, false);
req.send(null);

Просмотреть файл

@ -52,8 +52,7 @@ function createDoc() {
function xhrDoc(idx) {
return function() {
// Defy same-origin restrictions!
netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
var xhr = new XMLHttpRequest();
var xhr = SpecialPowers.createSystemXHR();
xhr.open("GET", docSources[idx], false);
xhr.send();
return xhr.responseXML;

Просмотреть файл

@ -37,13 +37,18 @@
/* This code is loaded in every child process that is started by mochitest in
* order to be used as a replacement for UniversalXPConnect
*/
var Ci = Components.interfaces;
var Cc = Components.classes;
function SpecialPowers(window) {
this.window = window;
bindDOMWindowUtils(this, window);
}
function bindDOMWindowUtils(sp, window) {
var util = window.QueryInterface(Components.interfaces.nsIInterfaceRequestor).getInterface(Components.interfaces.nsIDOMWindowUtils);
var util = window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIDOMWindowUtils);
// This bit of magic brought to you by the letters
// B Z, and E, S and the number 5.
//
@ -135,7 +140,6 @@ SpecialPowers.prototype = {
//XXX: these APIs really ought to be removed, they're not e10s-safe.
// (also they're pretty Firefox-specific)
_getTopChromeWindow: function(window) {
var Ci = Components.interfaces;
return window.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShellTreeItem)
@ -169,6 +173,11 @@ SpecialPowers.prototype = {
},
removeChromeEventListener: function(type, listener, capture) {
removeEventListener(type, listener, capture);
},
createSystemXHR: function() {
return Cc["@mozilla.org/xmlextras/xmlhttprequest;1"]
.createInstance(Ci.nsIXMLHttpRequest);
}
};