backing out fix for bug 416534 as potential cause of mochitest failure
authormyk@mozilla.org
Tue, 26 Feb 2008 19:23:36 -0800
changeset 12320 75f5ccc83d49111ac53327007aa38d71241744b9
parent 12319 e54420db9809cd611e8870f4aaaf24e9d94c6b23
child 12321 34618990870afed07830b2845885ba4924c410fd
push idunknown
push userunknown
push dateunknown
bugs416534
milestone1.9b4pre
backing out fix for bug 416534 as potential cause of mochitest failure
caps/idl/nsIPrincipal.idl
caps/include/nsScriptSecurityManager.h
caps/src/nsNullPrincipal.cpp
caps/src/nsPrincipal.cpp
caps/src/nsScriptSecurityManager.cpp
caps/src/nsSystemPrincipal.cpp
content/base/public/nsISyncLoadDOMService.idl
content/base/src/nsContentSink.cpp
content/base/src/nsContentUtils.cpp
content/base/src/nsCrossSiteListenerProxy.cpp
content/base/src/nsCrossSiteListenerProxy.h
content/base/src/nsSyncLoadService.cpp
content/base/src/nsSyncLoadService.h
content/base/src/nsXMLHttpRequest.cpp
content/xml/document/src/nsXMLContentSink.cpp
content/xml/document/src/nsXMLDocument.cpp
content/xslt/src/xml/txXMLParser.cpp
content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
content/xul/document/src/nsXULDocument.cpp
extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp
--- a/caps/idl/nsIPrincipal.idl
+++ b/caps/idl/nsIPrincipal.idl
@@ -46,17 +46,17 @@ struct JSContext;
 struct JSPrincipals;
 %}
 
 interface nsIURI;
 
 [ptr] native JSContext(JSContext);
 [ptr] native JSPrincipals(JSPrincipals);
 
-[scriptable, uuid(7292475e-2821-4602-9d00-228476696428)]
+[scriptable, uuid(635c413b-47c3-4ee1-87c8-e7919cc65f5a)]
 interface nsIPrincipal : nsISerializable
 {
     /**
      * Values of capabilities for each principal. Order is
      * significant: if an operation is performed on a set
      * of capabilities, the minimum is computed.
      */
     const short ENABLE_DENIED                = 1;
@@ -199,39 +199,16 @@ interface nsIPrincipal : nsISerializable
      * Note for the future: Perhaps we should consider a certificate principal
      * for a given URI subsuming a codebase principal for the same URI?  Not
      * sure what the immediate benefit would be, but I think the setup could
      * make some code (e.g. MaybeDowngradeToCodebase) clearer.
      */
     [noscript] boolean subsumes(in nsIPrincipal other);
 
     /**
-     * Checks whether this principal is allowed to load the network resource
-     * located at the given URI under the same-origin policy. This means that
-     * codebase principals are only allowed to load resources from the same
-     * domain, the system principal is allowed to load anything, and null
-     * principals are not allowed to load anything.
-     *
-     * If the load is allowed this function does nothing. If the load is not
-     * allowed the function throws NS_ERROR_DOM_BAD_URI.
-     *
-     * NOTE: Other policies might override this, such as the Access-Control
-     *       specification.
-     * NOTE: The 'domain' attribute has no effect on the behaviour of this
-     *       function.
-     *
-     *
-     * @param uri    The URI about to be loaded.
-     * @param report If true, will report a warning to the console service
-     *               if the load is not allowed.
-     * @throws NS_ERROR_DOM_BAD_URI if the load is not allowed.
-     */
-    [noscript] void checkMayLoad(in nsIUri uri, in boolean report);
-
-    /**
      * The subject name for the certificate.  This actually identifies the
      * subject of the certificate.  This may well not be a string that would
      * mean much to a typical user on its own (e.g. it may have a number of
      * different names all concatenated together with some information on what
      * they mean in between).
      *
      * Throws if there is no certificate associated with this principal.
      */
--- a/caps/include/nsScriptSecurityManager.h
+++ b/caps/include/nsScriptSecurityManager.h
@@ -390,28 +390,16 @@ public:
 
     static nsSystemPrincipal*
     SystemPrincipalSingletonConstructor();
 
     JSContext* GetCurrentJSContext();
 
     JSContext* GetSafeJSContext();
 
-    /**
-     * Utility method for comparing two URIs.  For security purposes, two URIs
-     * are equivalent if their schemes, hosts, and ports (if any) match.  This
-     * method returns true if aSubjectURI and aObjectURI have the same origin,
-     * false otherwise.
-     */
-    static PRBool SecurityCompareURIs(nsIURI* aSourceURI, nsIURI* aTargetURI);
-
-    static nsresult 
-    ReportError(JSContext* cx, const nsAString& messageTag,
-                nsIURI* aSource, nsIURI* aTarget);
-
 private:
 
     // GetScriptSecurityManager is the only call that can make one
     nsScriptSecurityManager();
     virtual ~nsScriptSecurityManager();
 
     static JSBool JS_DLL_CALLBACK
     CheckObjectAccess(JSContext *cx, JSObject *obj,
@@ -427,16 +415,20 @@ private:
 #endif
                          );
 
     // Returns null if a principal cannot be found.  Note that rv can be NS_OK
     // when this happens -- this means that there was no JS running.
     nsIPrincipal*
     doGetSubjectPrincipal(nsresult* rv);
     
+    static nsresult 
+    ReportError(JSContext* cx, const nsAString& messageTag,
+                nsIURI* aSource, nsIURI* aTarget);
+
     nsresult
     CheckPropertyAccessImpl(PRUint32 aAction,
                             nsAXPCNativeCallContext* aCallContext,
                             JSContext* cx, JSObject* aJSObject,
                             nsISupports* aObj, nsIURI* aTargetURI,
                             nsIClassInfo* aClassInfo,
                             const char* aClassName, jsval aProperty,
                             void** aCachedClassPolicy);
@@ -543,19 +535,26 @@ private:
     InitDomainPolicy(JSContext* cx, const char* aPolicyName,
                      DomainPolicy* aDomainPolicy);
 
     nsresult
     InitPrincipals(PRUint32 prefCount, const char** prefNames,
                    nsISecurityPref* securityPref);
 
 
+    /**
+     * Utility method for comparing two URIs.  For security purposes, two URIs
+     * are equivalent if their schemes, hosts, and ports (if any) match.  This
+     * method returns true if aSubjectURI and aObjectURI have the same origin,
+     * false otherwise.
+     */
+    PRBool SecurityCompareURIs(nsIURI* aSourceURI, nsIURI* aTargetURI);
+
     /* encapsulate the file comparison rules */
-    static PRBool SecurityCompareFileURIs(nsIURI* aSourceURI,
-                                          nsIURI* aTargetURI);
+    PRBool SecurityCompareFileURIs(nsIURI* aSourceURI, nsIURI* aTargetURI);
 
 #ifdef XPC_IDISPATCH_SUPPORT
     // While this header is included outside of caps, this class isn't 
     // referenced so this should be fine.
     nsresult
     CheckComponentPermissions(JSContext *cx, const nsCID &aCID);
 #endif
 #ifdef DEBUG_CAPS_HACKER
@@ -586,18 +585,17 @@ private:
     PRPackedBool mIsJavaScriptEnabled;
     PRPackedBool mIsMailJavaScriptEnabled;
     PRPackedBool mIsWritingPrefs;
     PRPackedBool mPolicyPrefsChanged;
 #ifdef XPC_IDISPATCH_SUPPORT    
     PRPackedBool mXPCDefaultGrantAll;
     static const char sXPCDefaultGrantAllName[];
 #endif
-
-    static PRInt32 sFileURIOriginPolicy;
+    PRInt32 mFileURIOriginPolicy;
 
     static nsIIOService    *sIOService;
     static nsIXPConnect    *sXPConnect;
     static nsIStringBundle *sStrBundle;
     static JSRuntime       *sRuntime;
 };
 
 // Levels for file: URI same-origin policy:
--- a/caps/src/nsNullPrincipal.cpp
+++ b/caps/src/nsNullPrincipal.cpp
@@ -44,18 +44,16 @@
 
 #include "nsNullPrincipal.h"
 #include "nsMemory.h"
 #include "nsIUUIDGenerator.h"
 #include "nsID.h"
 #include "nsNetUtil.h"
 #include "nsIClassInfoImpl.h"
 #include "nsNetCID.h"
-#include "nsDOMError.h"
-#include "nsScriptSecurityManager.h"
 
 static NS_DEFINE_CID(kSimpleURICID, NS_SIMPLEURI_CID);
 
 NS_IMPL_QUERY_INTERFACE2_CI(nsNullPrincipal,
                             nsIPrincipal,
                             nsISerializable)
 NS_IMPL_CI_INTERFACE_GETTER2(nsNullPrincipal,
                              nsIPrincipal,
@@ -313,27 +311,16 @@ nsNullPrincipal::Subsumes(nsIPrincipal *
 {
   // We don't subsume anything except ourselves.  Note that nsPrincipal::Equals
   // will return false for us, since we're not about:blank and not Equals to
   // reasonable nsPrincipals.
   *aResult = (aOther == this);
   return NS_OK;
 }
 
-NS_IMETHODIMP
-nsNullPrincipal::CheckMayLoad(nsIURI* aURI, PRBool aReport)
-{
-  if (aReport) {
-    nsScriptSecurityManager::ReportError(
-      nsnull, NS_LITERAL_STRING("CheckSameOriginError"), mURI, aURI);
-  }
-
-  return NS_ERROR_DOM_BAD_URI;
-}
-
 NS_IMETHODIMP 
 nsNullPrincipal::GetSubjectName(nsACString& aName)
 {
     return NS_ERROR_NOT_AVAILABLE;
 }
 
 NS_IMETHODIMP
 nsNullPrincipal::GetCertificate(nsISupports** aCertificate)
--- a/caps/src/nsPrincipal.cpp
+++ b/caps/src/nsPrincipal.cpp
@@ -49,17 +49,16 @@
 #include "nsJSPrincipals.h"
 #include "nsVoidArray.h"
 #include "nsHashtable.h"
 #include "nsIObjectInputStream.h"
 #include "nsIObjectOutputStream.h"
 #include "nsIPrefBranch.h"
 #include "nsIPrefService.h"
 #include "nsIClassInfoImpl.h"
-#include "nsDOMError.h"
 
 #include "nsPrincipal.h"
 
 static PRBool URIIsImmutable(nsIURI* aURI)
 {
   nsCOMPtr<nsIMutable> mutableObj(do_QueryInterface(aURI));
   PRBool isMutable;
   return
@@ -303,31 +302,16 @@ nsPrincipal::Equals(nsIPrincipal *aOther
 
 NS_IMETHODIMP
 nsPrincipal::Subsumes(nsIPrincipal *aOther, PRBool *aResult)
 {
   return Equals(aOther, aResult);
 }
 
 NS_IMETHODIMP
-nsPrincipal::CheckMayLoad(nsIURI* aURI, PRBool aReport)
-{
-  if (!nsScriptSecurityManager::SecurityCompareURIs(mCodebase, aURI)) {
-    if (aReport) {
-      nsScriptSecurityManager::ReportError(
-        nsnull, NS_LITERAL_STRING("CheckSameOriginError"), mCodebase, aURI);
-    }
-    
-    return NS_ERROR_DOM_BAD_URI;
-  }
-
-  return NS_OK;
-}
-
-NS_IMETHODIMP
 nsPrincipal::CanEnableCapability(const char *capability, PRInt16 *result)
 {
   // If this principal is marked invalid, can't enable any capabilities
   if (mCapabilities) {
     nsCStringKey invalidKey(sInvalid);
     if (mCapabilities->Exists(&invalidKey)) {
       *result = nsIPrincipal::ENABLE_DENIED;
 
--- a/caps/src/nsScriptSecurityManager.cpp
+++ b/caps/src/nsScriptSecurityManager.cpp
@@ -93,17 +93,16 @@
 #include "nsCDefaultURIFixup.h"
 
 static NS_DEFINE_CID(kZipReaderCID, NS_ZIPREADER_CID);
 
 nsIIOService    *nsScriptSecurityManager::sIOService = nsnull;
 nsIXPConnect    *nsScriptSecurityManager::sXPConnect = nsnull;
 nsIStringBundle *nsScriptSecurityManager::sStrBundle = nsnull;
 JSRuntime       *nsScriptSecurityManager::sRuntime   = 0;
-PRInt32 nsScriptSecurityManager::sFileURIOriginPolicy = FILEURI_SOP_SELF;
 
 // Info we need about the JSClasses used by XPConnects wrapped
 // natives, to avoid having to QI to nsIXPConnectWrappedNative all the
 // time when doing security checks.
 static const JSClass *sXPCWrappedNativeJSClass;
 static JSGetObjectOps sXPCWrappedNativeGetObjOps1;
 static JSGetObjectOps sXPCWrappedNativeGetObjOps2;
 
@@ -273,17 +272,16 @@ nsScriptSecurityManager::GetSafeJSContex
     }
 
     JSContext *cx;
     if (NS_FAILED(mJSContextStack->GetSafeJSContext(&cx)))
         return nsnull;
     return cx;
 }
 
-/* static */
 PRBool
 nsScriptSecurityManager::SecurityCompareURIs(nsIURI* aSourceURI,
                                              nsIURI* aTargetURI)
 {
     // Note that this is not an Equals() test on purpose -- for URIs that don't
     // support host/port, we want equality to basically be object identity, for
     // security purposes.  Otherwise, for example, two javascript: URIs that
     // are otherwise unrelated could end up "same origin", which would be
@@ -375,26 +373,26 @@ nsScriptSecurityManager::SecurityCompare
 }
 
 // helper function for SecurityCompareURIs
 PRBool
 nsScriptSecurityManager::SecurityCompareFileURIs(nsIURI* aSourceURI,
                                                  nsIURI* aTargetURI)
 {
     // in traditional unsafe behavior all files are the same origin
-    if (sFileURIOriginPolicy == FILEURI_SOP_TRADITIONAL)
+    if (mFileURIOriginPolicy == FILEURI_SOP_TRADITIONAL)
         return PR_TRUE;
 
 
     // Check simplest and default FILEURI_SOP_SELF case first:
     // If they're equal or if the policy says they must be, we're done
     PRBool filesAreEqual = PR_FALSE;
     if (NS_FAILED( aSourceURI->Equals(aTargetURI, &filesAreEqual) ))
         return PR_FALSE;
-    if (filesAreEqual || sFileURIOriginPolicy == FILEURI_SOP_SELF)
+    if (filesAreEqual || mFileURIOriginPolicy == FILEURI_SOP_SELF)
         return filesAreEqual;
 
 
     // disallow access to directory listings (bug 209234)
     PRBool targetIsDir = PR_TRUE;
     nsCOMPtr<nsIFile> targetFile;
     nsCOMPtr<nsIFileURL> targetFileURL( do_QueryInterface(aTargetURI) );
 
@@ -403,17 +401,17 @@ nsScriptSecurityManager::SecurityCompare
         NS_FAILED( targetFile->IsDirectory(&targetIsDir) ) ||
         targetIsDir)
     {
         return PR_FALSE;
     }
 
 
     // For policy ANYFILE we're done
-    if (sFileURIOriginPolicy == FILEURI_SOP_ANYFILE)
+    if (mFileURIOriginPolicy == FILEURI_SOP_ANYFILE)
         return PR_TRUE;
 
 
     // source parent directory is needed for remaining policies
     nsCOMPtr<nsIFile> sourceFile;
     nsCOMPtr<nsIFile> sourceParent;
     nsCOMPtr<nsIFileURL> sourceFileURL( do_QueryInterface(aSourceURI) );
 
@@ -422,28 +420,28 @@ nsScriptSecurityManager::SecurityCompare
         NS_FAILED( sourceFile->GetParent(getter_AddRefs(sourceParent)) ) ||
         !sourceParent)
     {
         // unexpected error
         return PR_FALSE;
     }
 
     // check remaining policies
-    if (sFileURIOriginPolicy == FILEURI_SOP_SAMEDIR)
+    if (mFileURIOriginPolicy == FILEURI_SOP_SAMEDIR)
     {
         // file: URIs in the same directory have the same origin
         PRBool sameParent = PR_FALSE;
         nsCOMPtr<nsIFile> targetParent;
         if (NS_FAILED( targetFile->GetParent(getter_AddRefs(targetParent)) ) ||
             NS_FAILED( sourceParent->Equals(targetParent, &sameParent) ))
             return PR_FALSE;
         return sameParent;
     }
 
-    if (sFileURIOriginPolicy == FILEURI_SOP_SUBDIR)
+    if (mFileURIOriginPolicy == FILEURI_SOP_SUBDIR)
     {
         // file: URIs can access files in the same or lower directories
         PRBool isChild = PR_FALSE;
         if (NS_FAILED( sourceParent->Contains(targetFile, PR_TRUE, &isChild) ))
             return PR_FALSE;
         return isChild;
     }
 
@@ -3256,20 +3254,21 @@ nsScriptSecurityManager::Observe(nsISupp
 /////////////////////////////////////////////
 nsScriptSecurityManager::nsScriptSecurityManager(void)
     : mOriginToPolicyMap(nsnull),
       mDefaultPolicy(nsnull),
       mCapabilities(nsnull),
       mIsJavaScriptEnabled(PR_FALSE),
       mIsMailJavaScriptEnabled(PR_FALSE),
       mIsWritingPrefs(PR_FALSE),
-      mPolicyPrefsChanged(PR_TRUE)
+      mPolicyPrefsChanged(PR_TRUE),
 #ifdef XPC_IDISPATCH_SUPPORT
-      , mXPCDefaultGrantAll(PR_FALSE)
+      mXPCDefaultGrantAll(PR_FALSE),
 #endif
+      mFileURIOriginPolicy(FILEURI_SOP_SELF)
 {
     NS_ASSERTION(sizeof(long) == sizeof(void*), "long and void* have different lengths on this platform. This may cause a security failure.");
     mPrincipals.Init(31);
 }
 
 
 nsresult nsScriptSecurityManager::Init()
 {
@@ -3873,17 +3872,17 @@ nsScriptSecurityManager::ScriptSecurityP
     mIsJavaScriptEnabled = NS_FAILED(rv) || temp;
 
     rv = mSecurityPref->SecurityGetBoolPref(sJSMailEnabledPrefName, &temp);
     // JavaScript in Mail defaults to disabled in failure cases.
     mIsMailJavaScriptEnabled = NS_SUCCEEDED(rv) && temp;
 
     PRInt32 policy;
     rv = mSecurityPref->SecurityGetIntPref(sFileOriginPolicyPrefName, &policy);
-    sFileURIOriginPolicy = NS_SUCCEEDED(rv) ? policy : FILEURI_SOP_SELF;
+    mFileURIOriginPolicy = NS_SUCCEEDED(rv) ? policy : FILEURI_SOP_SELF;
 
 #ifdef XPC_IDISPATCH_SUPPORT
     rv = mSecurityPref->SecurityGetBoolPref(sXPCDefaultGrantAllName, &temp);
     // Granting XPC Priveleges defaults to disabled in failure cases.
     mXPCDefaultGrantAll = NS_SUCCEEDED(rv) && temp;
 #endif
 }
 
--- a/caps/src/nsSystemPrincipal.cpp
+++ b/caps/src/nsSystemPrincipal.cpp
@@ -111,22 +111,16 @@ nsSystemPrincipal::Equals(nsIPrincipal *
 NS_IMETHODIMP
 nsSystemPrincipal::Subsumes(nsIPrincipal *other, PRBool *result)
 {
     *result = PR_TRUE;
     return NS_OK;
 }
 
 NS_IMETHODIMP
-nsSystemPrincipal::CheckMayLoad(nsIURI* uri, PRBool aReport)
-{
-    return NS_OK;
-}
-
-NS_IMETHODIMP
 nsSystemPrincipal::GetHashValue(PRUint32 *result)
 {
     *result = NS_PTR_TO_INT32(this);
     return NS_OK;
 }
 
 NS_IMETHODIMP 
 nsSystemPrincipal::CanEnableCapability(const char *capability, 
--- a/content/base/public/nsISyncLoadDOMService.idl
+++ b/content/base/public/nsISyncLoadDOMService.idl
@@ -34,66 +34,60 @@
  * the provisions above, a recipient may use your version of this file under
  * the terms of any one of the MPL, the GPL or the LGPL.
  *
  * ***** END LICENSE BLOCK ***** */
 
 #include "nsISupports.idl"
 
 interface nsIURI;
-interface nsIPrincipal;
 interface nsIDOMDocument;
 interface nsIChannel;
 
 /*************************************************************************
  *                                                                       *
  *                          **** NOTICE ****                             *
  *                                                                       *
- *                                                                       *
- *    This interface is DEPRECATED!                                      *
- *    You should instead use XMLHttpRequest which now works both from    *
- *    Javascript and C++.                                                *
- *                                                                       *
- *    Additionally, synchronous network loads are evil.  Any delays      *
- *    from the server will appear as a hang in the mozilla UI.           *
- *    Therefore, they should be avoided as much as possible.             *
+ *    nsISyncLoadDOMService defines synchronous methods to download      *
+ *    data from the network.  Any delays from the server will            *
+ *    appear as a hang in the mozilla UI.  Therefore, this interface     *
+ *    should be avoided as much as possible.                             *
  *                                                                       *
  *    Don't make me come over there!!                                    *
  *                                                                       *
  *                                                                       *
  ************************************************************************/
 
 /**
  * The nsISyncDOMLoadService interface can be used to synchronously load
  * a document.
  */
 
-[scriptable, uuid(8095998d-ae1c-4cfa-9b43-0973e5d77eb0)]
+[scriptable, uuid(2ae03836-0704-45c9-a545-4169548c0669)]
 interface nsISyncLoadDOMService : nsISupports
 {
     /**
      * Synchronously load the document from the specified channel.
      *
      * @param aChannel   The channel to load the document from.
-     * @param aLoaderPrincipal Principal of loading document. For security
-     *                         checks null if no securitychecks should be done
+     * @param aLoaderURI URI of loading document. For security checks
+     *                   null if no securitychecks should be done
      *
      * @returns The document loaded from the URI.
      */
-    nsIDOMDocument loadDocument(in nsIChannel aChannel,
-                                in nsIPrincipal aLoaderPrincipal);
+    nsIDOMDocument loadDocument(in nsIChannel aChannel, in nsIURI aLoaderURI);
 
     nsIDOMDocument loadDocumentAsXML(in nsIChannel aChannel,
-                                     in nsIPrincipal aLoaderPrincipal);
+                                     in nsIURI aLoaderURI);
 
     /**
      * Synchronously load an XML document from the specified
      * channel. The channel must be possible to open synchronously.
      *
      * @param aChannel   The channel to load the document from.
-     * @param aLoaderPrincipal Principal of loading document. For security
-     *                         checks null if no securitychecks should be done
+     * @param aLoaderURI URI of loading document. For security checks
+     *                   null if no securitychecks should be done
      *
      * @returns The document loaded from the URI.
      */
     nsIDOMDocument loadLocalDocument(in nsIChannel aChannel,
-                                     in nsIPrincipal aLoaderPrincipal);
+                                     in nsIURI aLoaderURI);
 };
--- a/content/base/src/nsContentSink.cpp
+++ b/content/base/src/nsContentSink.cpp
@@ -861,17 +861,18 @@ nsContentSink::ProcessOfflineManifest(ns
   nsContentUtils::NewURIWithDocumentCharset(getter_AddRefs(manifestURI),
                                             manifestSpec, mDocument,
                                             mDocumentURI);
   if (!manifestURI) {
     return;
   }
 
   // Documents must list a manifest from the same origin
-  nsresult rv = mDocument->NodePrincipal()->CheckMayLoad(manifestURI, PR_TRUE);
+  nsresult rv = nsContentUtils::GetSecurityManager()->
+                   CheckSameOriginURI(manifestURI, mDocumentURI, PR_TRUE);
   if (NS_FAILED(rv)) {
     return;
   }
 
   // Start the update
   nsCOMPtr<nsIDOMDocument> domdoc = do_QueryInterface(mDocument);
   nsCOMPtr<nsIOfflineCacheUpdateService> updateService =
     do_GetService(NS_OFFLINECACHEUPDATESERVICE_CONTRACTID);
--- a/content/base/src/nsContentUtils.cpp
+++ b/content/base/src/nsContentUtils.cpp
@@ -3829,17 +3829,20 @@ nsContentUtils::CheckSecurityBeforeLoad(
 
   // Same Origin
   if ((aAllowData && SchemeIs(aURIToLoad, "data")) ||
       ((aCheckLoadFlags & nsIScriptSecurityManager::ALLOW_CHROME) &&
        SchemeIs(aURIToLoad, "chrome"))) {
     return NS_OK;
   }
 
-  return aLoadingPrincipal->CheckMayLoad(aURIToLoad, PR_TRUE);
+  nsCOMPtr<nsIURI> loadingURI;
+  rv = aLoadingPrincipal->GetURI(getter_AddRefs(loadingURI));
+  NS_ENSURE_SUCCESS(rv, rv);
+  return sSecurityManager->CheckSameOriginURI(loadingURI, aURIToLoad, PR_TRUE);
 }
 
 /* static */
 void
 nsContentUtils::TriggerLink(nsIContent *aContent, nsPresContext *aPresContext,
                             nsIURI *aLinkURI, const nsString &aTargetSpec,
                             PRBool aClick, PRBool aIsUserTriggered)
 {
--- a/content/base/src/nsCrossSiteListenerProxy.cpp
+++ b/content/base/src/nsCrossSiteListenerProxy.cpp
@@ -46,39 +46,28 @@
 #include "nsParserCIID.h"
 #include "nsICharsetAlias.h"
 #include "nsMimeTypes.h"
 #include "nsIStreamConverterService.h"
 #include "nsStringStream.h"
 #include "nsParserUtils.h"
 #include "nsGkAtoms.h"
 #include "nsWhitespaceTokenizer.h"
-#include "nsIChannelEventSink.h"
 
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
-NS_IMPL_ISUPPORTS7(nsCrossSiteListenerProxy, nsIStreamListener,
+NS_IMPL_ISUPPORTS5(nsCrossSiteListenerProxy, nsIStreamListener,
                    nsIRequestObserver, nsIContentSink, nsIXMLContentSink,
-                   nsIExpatSink, nsIChannelEventSink, nsIInterfaceRequestor)
+                   nsIExpatSink)
 
 nsCrossSiteListenerProxy::nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
-                                                   nsIPrincipal* aRequestingPrincipal,
-                                                   nsIChannel* aChannel,
-                                                   nsresult* aResult)
-  : mOuterListener(aOuter),
-    mRequestingPrincipal(aRequestingPrincipal),
-    mAcceptState(eNotSet),
-    mHasForwardedRequest(PR_FALSE),
-    mHasBeenCrossSite(PR_FALSE)
+                                                   nsIPrincipal* aRequestingPrincipal)
+  : mOuter(aOuter), mAcceptState(eNotSet), mHasForwardedRequest(PR_FALSE)
 {
   aRequestingPrincipal->GetURI(getter_AddRefs(mRequestingURI));
-  aChannel->GetNotificationCallbacks(getter_AddRefs(mOuterNotificationCallbacks));
-  aChannel->SetNotificationCallbacks(this);
-
-  *aResult = UpdateChannel(aChannel);
 }
 
 nsresult
 nsCrossSiteListenerProxy::ForwardRequest(PRBool aFromStop)
 {
   if (mHasForwardedRequest) {
     return NS_OK;
   }
@@ -89,42 +78,41 @@ nsCrossSiteListenerProxy::ForwardRequest
     mParser->Terminate();
     mParser = nsnull;
     mParserListener = nsnull;
   }
 
   if (mAcceptState != eAccept) {
     mAcceptState = eDeny;
     mOuterRequest->Cancel(NS_ERROR_DOM_BAD_URI);
-    mOuterListener->OnStartRequest(mOuterRequest, mOuterContext);
+    mOuter->OnStartRequest(mOuterRequest, mOuterContext);
 
     // Only call OnStopRequest here if we were called from OnStopRequest.
     // Otherwise the call to Cancel will make us get an OnStopRequest later
     // so we'll forward OnStopRequest then.
     if (aFromStop) {
-      mOuterListener->OnStopRequest(mOuterRequest, mOuterContext,
-                                    NS_ERROR_DOM_BAD_URI);
+      mOuter->OnStopRequest(mOuterRequest, mOuterContext, NS_ERROR_DOM_BAD_URI);
     }
 
     // Clear this data just in case since it should never be forwarded.
     mStoredData.Truncate();
 
     return NS_ERROR_DOM_BAD_URI;
   }
 
-  nsresult rv = mOuterListener->OnStartRequest(mOuterRequest, mOuterContext);
+  nsresult rv = mOuter->OnStartRequest(mOuterRequest, mOuterContext);
   NS_ENSURE_SUCCESS(rv, rv);
 
   if (!mStoredData.IsEmpty()) {
     nsCOMPtr<nsIInputStream> stream;
     rv = NS_NewCStringInputStream(getter_AddRefs(stream), mStoredData);
     NS_ENSURE_SUCCESS(rv, rv);
 
-    rv = mOuterListener->OnDataAvailable(mOuterRequest, mOuterContext, stream,
-                                         0, mStoredData.Length());
+    rv = mOuter->OnDataAvailable(mOuterRequest, mOuterContext, stream, 0,
+                                 mStoredData.Length());
     NS_ENSURE_SUCCESS(rv, rv);
   }
 
   return NS_OK;
 }
 
 NS_IMETHODIMP
 nsCrossSiteListenerProxy::OnStartRequest(nsIRequest* aRequest,
@@ -144,18 +132,19 @@ nsCrossSiteListenerProxy::OnStartRequest
 
   // Check if this was actually a cross domain request
   nsCOMPtr<nsIChannel> channel = do_QueryInterface(aRequest);
   if (!channel) {
     return NS_ERROR_DOM_BAD_URI;
   }
   nsCOMPtr<nsIURI> finalURI;
   channel->GetURI(getter_AddRefs(finalURI));
-
-  if (!mHasBeenCrossSite) {
+  rv = nsContentUtils::GetSecurityManager()->
+    CheckSameOriginURI(mRequestingURI, finalURI, PR_FALSE);
+  if (NS_SUCCEEDED(rv)) {
     mAcceptState = eAccept;
     return ForwardRequest(PR_FALSE);
   }
 
   nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(channel);
   if (http) {
     PRBool succeeded;
     rv = http->GetRequestSucceeded(&succeeded);
@@ -253,17 +242,17 @@ nsCrossSiteListenerProxy::OnStartRequest
 }
 
 NS_IMETHODIMP
 nsCrossSiteListenerProxy::OnStopRequest(nsIRequest* aRequest,
                                         nsISupports* aContext,
                                         nsresult aStatusCode)
 {
   if (mHasForwardedRequest) {
-    return mOuterListener->OnStopRequest(aRequest, aContext, aStatusCode);
+    return mOuter->OnStopRequest(aRequest, aContext, aStatusCode);
   }
 
   mAcceptState = eDeny;
   return ForwardRequest(PR_TRUE);
 }
 
 NS_METHOD
 StringSegmentWriter(nsIInputStream *aInStream,
@@ -287,18 +276,18 @@ nsCrossSiteListenerProxy::OnDataAvailabl
                                           nsIInputStream* aInputStream,
                                           PRUint32 aOffset,
                                           PRUint32 aCount)
 {
   if (mHasForwardedRequest) {
     if (mAcceptState != eAccept) {
       return NS_ERROR_DOM_BAD_URI;
     }
-    return mOuterListener->OnDataAvailable(aRequest, aContext, aInputStream,
-                                           aOffset, aCount);
+    return mOuter->OnDataAvailable(aRequest, aContext, aInputStream, aOffset,
+                                   aCount);
   }
 
   NS_ASSERTION(mStoredData.Length() == aOffset,
                "Stored wrong amount of data");
 
   PRUint32 read;
   nsresult rv = aInputStream->ReadSegments(StringSegmentWriter, &mStoredData,
                                            aCount, &read);
@@ -872,98 +861,47 @@ nsCrossSiteListenerProxy::VerifyAndMatch
 
   // Only matches if we've matched all of pattern and, if there is a wildcard, there
   // is at least one more entry in mReqSubdomains.
   
   return patternPos == 0 &&
          (!patternHasWild || reqPos >= 1);
 }
 
-NS_IMETHODIMP
-nsCrossSiteListenerProxy::GetInterface(const nsIID & aIID, void **aResult)
+/* static */
+nsresult
+nsCrossSiteListenerProxy::AddRequestHeaders(nsIChannel* aChannel,
+                                            nsIPrincipal* aRequestingPrincipal)
 {
-  if (aIID.Equals(NS_GET_IID(nsIChannelEventSink))) {
-    *aResult = static_cast<nsIChannelEventSink*>(this);
-    NS_ADDREF_THIS();
-
-    return NS_OK;
-  }
-
-  return mOuterNotificationCallbacks ?
-    mOuterNotificationCallbacks->GetInterface(aIID, aResult) :
-    NS_ERROR_NO_INTERFACE;
-}
+  // Once bug 386823 is fixed this could just be an assertion.
+  NS_ENSURE_TRUE(aRequestingPrincipal, NS_ERROR_FAILURE);
 
-NS_IMETHODIMP
-nsCrossSiteListenerProxy::OnChannelRedirect(nsIChannel *aOldChannel,
-                                            nsIChannel *aNewChannel,
-                                            PRUint32    aFlags)
-{
-  nsresult rv;
-  nsCOMPtr<nsIChannelEventSink> outer =
-    do_GetInterface(mOuterNotificationCallbacks);
-  if (outer) {
-    rv = outer->OnChannelRedirect(aOldChannel, aNewChannel, aFlags);
-    NS_ENSURE_SUCCESS(rv, rv);
-  }
-
-  return UpdateChannel(aNewChannel);
-}
-
-nsresult
-nsCrossSiteListenerProxy::UpdateChannel(nsIChannel* aChannel)
-{
+  // Work out the requesting URI
   nsCOMPtr<nsIURI> uri;
-  nsresult rv = aChannel->GetURI(getter_AddRefs(uri));
+  nsresult rv = aRequestingPrincipal->GetURI(getter_AddRefs(uri));
   NS_ENSURE_SUCCESS(rv, rv);
 
-  // Check that the uri is ok to load
-  rv = nsContentUtils::GetSecurityManager()->
-    CheckLoadURIWithPrincipal(mRequestingPrincipal, uri,
-                              nsIScriptSecurityManager::STANDARD);
+  nsCString scheme, host;
+  rv = uri->GetScheme(scheme);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  rv = uri->GetAsciiHost(host);
   NS_ENSURE_SUCCESS(rv, rv);
 
-  if (!mHasBeenCrossSite &&
-      NS_SUCCEEDED(mRequestingPrincipal->CheckMayLoad(uri, PR_FALSE))) {
-    return NS_OK;
-  }
-
-  nsCString userpass;
-  uri->GetUserPass(userpass);
-  NS_ENSURE_TRUE(userpass.IsEmpty(), NS_ERROR_DOM_BAD_URI);
-
-  // It's a cross site load
-  mHasBeenCrossSite = PR_TRUE;
-
-  // Work out the Referer-Root header
-  nsCString root, host;
-  rv = mRequestingURI->GetAsciiHost(host);
-  NS_ENSURE_SUCCESS(rv, rv);
-
-  if (!host.IsEmpty()) {
-    nsCString scheme;
-    rv = mRequestingURI->GetScheme(scheme);
-    NS_ENSURE_SUCCESS(rv, rv);
-
-    root = scheme + NS_LITERAL_CSTRING("://") + host;
-
-    // If needed, append the port
-    PRInt32 port;
-    mRequestingURI->GetPort(&port);
-    if (port != -1) {
-      PRInt32 defaultPort = NS_GetDefaultPort(scheme.get());
-      if (port != defaultPort) {
-        root.Append(":");
-        root.AppendInt(port);
-      }
+  nsCString root = scheme + NS_LITERAL_CSTRING("://") + host;
+  // Append the port
+  PRInt32 port;
+  uri->GetPort(&port);
+  if (port != -1) {
+    PRInt32 defaultPort = NS_GetDefaultPort(scheme.get());
+    if (port != defaultPort) {
+      root.Append(":");
+      root.AppendInt(port);
     }
   }
-  else {
-    root.AssignLiteral("null");
-  }
 
   // Now add the access-control-origin header
   nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(aChannel);
   NS_ENSURE_TRUE(http, NS_ERROR_FAILURE);
 
   return http->SetRequestHeader(NS_LITERAL_CSTRING("Access-Control-Origin"),
     root, PR_FALSE);
 }
--- a/content/base/src/nsCrossSiteListenerProxy.h
+++ b/content/base/src/nsCrossSiteListenerProxy.h
@@ -39,71 +39,62 @@
 #include "nsIInterfaceRequestor.h"
 #include "nsCOMPtr.h"
 #include "nsString.h"
 #include "nsIURI.h"
 #include "nsTArray.h"
 #include "nsIContentSink.h"
 #include "nsIXMLContentSink.h"
 #include "nsIExpatSink.h"
-#include "nsIInterfaceRequestor.h"
-#include "nsIChannelEventSink.h"
 
 class nsIURI;
 class nsIParser;
 class nsIPrincipal;
 
 class nsCrossSiteListenerProxy : public nsIStreamListener,
                                  public nsIXMLContentSink,
-                                 public nsIExpatSink,
-                                 public nsIInterfaceRequestor,
-                                 public nsIChannelEventSink
+                                 public nsIExpatSink
 {
 public:
   nsCrossSiteListenerProxy(nsIStreamListener* aOuter,
-                           nsIPrincipal* aRequestingPrincipal,
-                           nsIChannel* aChannel,
-                           nsresult* aResult);
-
+                           nsIPrincipal* aRequestingPrincipal);
+  
   NS_DECL_ISUPPORTS
   NS_DECL_NSIREQUESTOBSERVER
   NS_DECL_NSISTREAMLISTENER
   NS_DECL_NSIEXPATSINK
-  NS_DECL_NSIINTERFACEREQUESTOR
-  NS_DECL_NSICHANNELEVENTSINK
+
+  static nsresult AddRequestHeaders(nsIChannel* aChannel,
+                                    nsIPrincipal* aRequestingPrincipal);
 
   // nsIContentSink
   NS_IMETHOD WillTokenize(void) { return NS_OK; }
   NS_IMETHOD WillBuildModel(void);
   NS_IMETHOD DidBuildModel()  { return NS_OK; }
   NS_IMETHOD WillInterrupt(void) { return NS_OK; }
   NS_IMETHOD WillResume(void) { return NS_OK; }
   NS_IMETHOD SetParser(nsIParser* aParser) { return NS_OK; }
   virtual void FlushPendingNotifications(mozFlushType aType) { }
   NS_IMETHOD SetDocumentCharset(nsACString& aCharset) { return NS_OK; }
   virtual nsISupports *GetTarget() { return nsnull; }
 
 private:
-  nsresult UpdateChannel(nsIChannel* aChannel);
 
   nsresult ForwardRequest(PRBool aCallStop);
   PRBool MatchPatternList(const char*& aIter, const char* aEnd);
   void CheckHeader(const nsCString& aHeader);
   PRBool VerifyAndMatchDomainPattern(const nsACString& aDomainPattern);
 
-  nsCOMPtr<nsIStreamListener> mOuterListener;
+  nsCOMPtr<nsIStreamListener> mOuter;
   nsCOMPtr<nsIRequest> mOuterRequest;
   nsCOMPtr<nsISupports> mOuterContext;
   nsCOMPtr<nsIStreamListener> mParserListener;
   nsCOMPtr<nsIParser> mParser;
   nsCOMPtr<nsIURI> mRequestingURI;
-  nsCOMPtr<nsIPrincipal> mRequestingPrincipal;
-  nsCOMPtr<nsIInterfaceRequestor> mOuterNotificationCallbacks;
   nsTArray<nsCString> mReqSubdomains;
   nsCString mStoredData;
   enum {
     eAccept,
     eDeny,
     eNotSet
   } mAcceptState;
   PRBool mHasForwardedRequest;
-  PRBool mHasBeenCrossSite;
 };
--- a/content/base/src/nsSyncLoadService.cpp
+++ b/content/base/src/nsSyncLoadService.cpp
@@ -54,33 +54,32 @@
 #include "nsIPrivateDOMImplementation.h"
 #include "nsIScriptSecurityManager.h"
 #include "nsContentUtils.h"
 #include "nsThreadUtils.h"
 #include "nsNetUtil.h"
 #include "nsAutoPtr.h"
 #include "nsLoadListenerProxy.h"
 #include "nsStreamUtils.h"
-#include "nsCrossSiteListenerProxy.h"
 
 /**
  * This class manages loading a single XML document
  */
 
 class nsSyncLoader : public nsIDOMLoadListener,
                      public nsIChannelEventSink,
                      public nsIInterfaceRequestor,
                      public nsSupportsWeakReference
 {
 public:
     virtual ~nsSyncLoader();
 
     NS_DECL_ISUPPORTS
 
-    nsresult LoadDocument(nsIChannel* aChannel, nsIPrincipal *aLoaderPrincipal,
+    nsresult LoadDocument(nsIChannel* aChannel, nsIURI *aLoaderURI,
                           PRBool aChannelIsSync, PRBool aForceToXML,
                           nsIDOMDocument** aResult);
 
     NS_DECL_NSIDOMEVENTLISTENER
 
     // nsIDOMLoadListener
     NS_IMETHOD Load(nsIDOMEvent* aEvent);
     NS_IMETHOD BeforeUnload(nsIDOMEvent* aEvent);
@@ -158,45 +157,51 @@ nsSyncLoader::~nsSyncLoader()
 NS_IMPL_ISUPPORTS4(nsSyncLoader,
                    nsIDOMLoadListener,
                    nsIChannelEventSink,
                    nsIInterfaceRequestor,
                    nsISupportsWeakReference)
 
 nsresult
 nsSyncLoader::LoadDocument(nsIChannel* aChannel,
-                           nsIPrincipal *aLoaderPrincipal,
+                           nsIURI *aLoaderURI,
                            PRBool aChannelIsSync,
                            PRBool aForceToXML,
                            nsIDOMDocument **aResult)
 {
     NS_ENSURE_ARG_POINTER(aResult);
     *aResult = nsnull;
     nsresult rv = NS_OK;
 
-    nsCOMPtr<nsIURI> loaderUri;
-    if (aLoaderPrincipal) {
-        aLoaderPrincipal->GetURI(getter_AddRefs(loaderUri));
-    }
-
     mChannel = aChannel;
     nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(mChannel);
     if (http) {
         http->SetRequestHeader(NS_LITERAL_CSTRING("Accept"),     
                                NS_LITERAL_CSTRING("text/xml,application/xml,application/xhtml+xml,*/*;q=0.1"),
                                PR_FALSE);
-        if (loaderUri) {
-            http->SetReferrer(loaderUri);
+        if (aLoaderURI) {
+            http->SetReferrer(aLoaderURI);
         }
     }
 
-    // Hook us up to listen to redirects and the like.
-    // Do this before setting up the cross-site proxy since
-    // that installs its own proxies.
-    mChannel->SetNotificationCallbacks(this);
+    if (aLoaderURI) {
+        nsCOMPtr<nsIURI> docURI;
+        rv = aChannel->GetOriginalURI(getter_AddRefs(docURI));
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        nsIScriptSecurityManager *securityManager =
+            nsContentUtils::GetSecurityManager();
+
+        rv = securityManager->CheckLoadURI(aLoaderURI, docURI,
+                                           nsIScriptSecurityManager::STANDARD);
+        NS_ENSURE_SUCCESS(rv, rv);
+
+        rv = securityManager->CheckSameOriginURI(aLoaderURI, docURI, PR_TRUE);
+        NS_ENSURE_SUCCESS(rv, rv);
+    }
 
     // Get the loadgroup of the channel
     nsCOMPtr<nsILoadGroup> loadGroup;
     rv = aChannel->GetLoadGroup(getter_AddRefs(loadGroup));
     NS_ENSURE_SUCCESS(rv, rv);
 
     // Create document
     nsCOMPtr<nsIDocument> document;
@@ -213,23 +218,16 @@ nsSyncLoader::LoadDocument(nsIChannel* a
     NS_ENSURE_SUCCESS(rv, rv);
 
     if (aForceToXML) {
         nsCOMPtr<nsIStreamListener> forceListener =
             new nsForceXMLListener(listener);
         listener.swap(forceListener);
     }
 
-    if (aLoaderPrincipal) {
-        listener = new nsCrossSiteListenerProxy(listener, aLoaderPrincipal,
-                                                mChannel, &rv);
-        NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
-        NS_ENSURE_SUCCESS(rv, rv);
-    }
-
     // Register as a load listener on the document
     nsCOMPtr<nsPIDOMEventTarget> target = do_QueryInterface(document);
     NS_ENSURE_TRUE(target, NS_ERROR_FAILURE);
 
     nsWeakPtr requestWeak = do_GetWeakReference(static_cast<nsIDOMLoadListener*>(this));
     nsLoadListenerProxy* proxy = new nsLoadListenerProxy(requestWeak);
     NS_ENSURE_TRUE(proxy, NS_ERROR_OUT_OF_MEMORY);
 
@@ -267,16 +265,19 @@ nsSyncLoader::LoadDocument(nsIChannel* a
     NS_ENSURE_TRUE(document->GetRootContent(), NS_ERROR_FAILURE);
 
     return CallQueryInterface(document, aResult);
 }
 
 nsresult
 nsSyncLoader::PushAsyncStream(nsIStreamListener* aListener)
 {
+    // Hook us up to listen to redirects and the like
+    mChannel->SetNotificationCallbacks(this);
+
     // Start reading from the channel
     nsresult rv = mChannel->AsyncOpen(aListener, nsnull);
 
     if (NS_SUCCEEDED(rv)) {
         // process events until we're finished.
         mLoading = PR_TRUE;
         nsIThread *thread = NS_GetCurrentThread();
         while (mLoading && NS_SUCCEEDED(rv)) {
@@ -361,75 +362,82 @@ nsSyncLoader::Error(nsIDOMEvent* aEvent)
 
 NS_IMETHODIMP
 nsSyncLoader::OnChannelRedirect(nsIChannel *aOldChannel,
                                 nsIChannel *aNewChannel,
                                 PRUint32    aFlags)
 {
     NS_PRECONDITION(aNewChannel, "Redirecting to null channel?");
 
+    nsCOMPtr<nsIURI> oldURI;
+    nsresult rv = aOldChannel->GetURI(getter_AddRefs(oldURI)); // The original URI
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIURI> newURI;
+    rv = aNewChannel->GetURI(getter_AddRefs(newURI)); // The new URI
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsIScriptSecurityManager *securityManager =
+        nsContentUtils::GetSecurityManager();
+
+    rv = securityManager->CheckSameOriginURI(oldURI, newURI, PR_TRUE);
+    NS_ENSURE_SUCCESS(rv, rv);
+
     mChannel = aNewChannel;
 
     return NS_OK;
 }
 
 NS_IMETHODIMP
 nsSyncLoader::GetInterface(const nsIID & aIID,
                            void **aResult)
 {
     return QueryInterface(aIID, aResult);
 }
 
 NS_IMPL_ISUPPORTS1(nsSyncLoadService,
                    nsISyncLoadDOMService)
 
 static nsresult
-LoadFromChannel(nsIChannel* aChannel, nsIPrincipal *aLoaderPrincipal,
-                PRBool aChannelIsSync, PRBool aForceToXML,
-                nsIDOMDocument** aResult)
+LoadFromChannel(nsIChannel* aChannel, nsIURI *aLoaderURI, PRBool aChannelIsSync,
+                PRBool aForceToXML, nsIDOMDocument** aResult)
 {
     nsRefPtr<nsSyncLoader> loader = new nsSyncLoader();
     if (!loader) {
         return NS_ERROR_OUT_OF_MEMORY;
     }
 
-    return loader->LoadDocument(aChannel, aLoaderPrincipal, aChannelIsSync,
+    return loader->LoadDocument(aChannel, aLoaderURI, aChannelIsSync,
                                 aForceToXML, aResult);
 }
 
 NS_IMETHODIMP
-nsSyncLoadService::LoadDocument(nsIChannel* aChannel,
-                                nsIPrincipal* aLoaderPrincipal,
+nsSyncLoadService::LoadDocument(nsIChannel* aChannel, nsIURI* aLoaderURI,
                                 nsIDOMDocument** aResult)
 {
-    return LoadFromChannel(aChannel, aLoaderPrincipal, PR_FALSE, PR_FALSE,
-                           aResult);
+    return LoadFromChannel(aChannel, aLoaderURI, PR_FALSE, PR_FALSE, aResult);
 }
 
 NS_IMETHODIMP
-nsSyncLoadService::LoadDocumentAsXML(nsIChannel* aChannel,
-                                     nsIPrincipal* aLoaderPrincipal,
+nsSyncLoadService::LoadDocumentAsXML(nsIChannel* aChannel, nsIURI* aLoaderURI,
                                      nsIDOMDocument** aResult)
 {
-    return LoadFromChannel(aChannel, aLoaderPrincipal, PR_FALSE, PR_TRUE,
-                           aResult);
+    return LoadFromChannel(aChannel, aLoaderURI, PR_FALSE, PR_TRUE, aResult);
 }
 
 NS_IMETHODIMP
-nsSyncLoadService::LoadLocalDocument(nsIChannel* aChannel,
-                                     nsIPrincipal* aLoaderPrincipal,
+nsSyncLoadService::LoadLocalDocument(nsIChannel* aChannel, nsIURI* aLoaderURI,
                                      nsIDOMDocument** aResult)
 {
-    return LoadFromChannel(aChannel, aLoaderPrincipal, PR_TRUE, PR_TRUE,
-                           aResult);
+    return LoadFromChannel(aChannel, aLoaderURI, PR_TRUE, PR_TRUE, aResult);
 }
 
 /* static */
 nsresult
-nsSyncLoadService::LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
+nsSyncLoadService::LoadDocument(nsIURI *aURI, nsIURI *aLoaderURI,
                                 nsILoadGroup *aLoadGroup, PRBool aForceToXML,
                                 nsIDOMDocument** aResult)
 {
     nsCOMPtr<nsIChannel> channel;
     nsresult rv = NS_NewChannel(getter_AddRefs(channel), aURI, nsnull,
                                 aLoadGroup);
     NS_ENSURE_SUCCESS(rv, rv);
 
@@ -438,18 +446,17 @@ nsSyncLoadService::LoadDocument(nsIURI *
     }
 
     PRBool isChrome = PR_FALSE, isResource = PR_FALSE;
     PRBool isSync = (NS_SUCCEEDED(aURI->SchemeIs("chrome", &isChrome)) &&
                      isChrome) ||
                     (NS_SUCCEEDED(aURI->SchemeIs("resource", &isResource)) &&
                      isResource);
 
-    return LoadFromChannel(channel, aLoaderPrincipal, isSync, aForceToXML,
-                           aResult);
+    return LoadFromChannel(channel, aLoaderURI, isSync, aForceToXML, aResult);
 }
 
 /* static */
 nsresult
 nsSyncLoadService::PushSyncStreamToListener(nsIInputStream* aIn,
                                             nsIStreamListener* aListener,
                                             nsIChannel* aChannel)
 {
--- a/content/base/src/nsSyncLoadService.h
+++ b/content/base/src/nsSyncLoadService.h
@@ -55,25 +55,25 @@ class nsSyncLoadService : public nsISync
 public:
     NS_DECL_ISUPPORTS
     NS_DECL_NSISYNCLOADDOMSERVICE
 
     /**
      * Synchronously load the document from the specified URI.
      *
      * @param aURI URI to load the document from.
-     * @param aLoaderPrincipal Principal of loading document. For security
-     *                         checks and referrer header. May be null if no
-     *                         security checks should be done.
+     * @param aLoaderURI URI of loading document. For security checks and
+     *                   referrer header. May be null if no security checks
+     *                   should be done.
      * @param aLoadGroup The loadgroup to use for loading the document.
      * @param aForceToXML Whether to parse the document as XML, regardless of
      *                    content type.
      * @param aResult [out] The document loaded from the URI.
      */
-    static nsresult LoadDocument(nsIURI *aURI, nsIPrincipal *aLoaderPrincipal,
+    static nsresult LoadDocument(nsIURI *aURI, nsIURI *aLoaderURI,
                                  nsILoadGroup *aLoadGroup, PRBool aForceToXML,
                                  nsIDOMDocument** aResult);
 
     /**
      * Read input stream aIn in chunks and deliver synchronously to aListener.
      *
      * @param aIn The stream to be read.
      * @param aListener The listener that will receive
--- a/content/base/src/nsXMLHttpRequest.cpp
+++ b/content/base/src/nsXMLHttpRequest.cpp
@@ -1411,27 +1411,37 @@ nsXMLHttpRequest::CheckChannelForCrossSi
     return NS_OK;
   }
 
   // This is a cross-site request
 
   // The request is now cross-site, so update flag.
   mState |= XML_HTTP_REQUEST_USE_XSITE_AC;
 
-  // Remove dangerous headers
+  // Remove dangerous headers and set XMLHttpRequest-Security-Check
   nsCOMPtr<nsIHttpChannel> http = do_QueryInterface(mChannel);
   if (http) {
     PRUint32 i;
     for (i = 0; i < mExtraRequestHeaders.Length(); ++i) {
       http->SetRequestHeader(mExtraRequestHeaders[i], EmptyCString(), PR_FALSE);
     }
     mExtraRequestHeaders.Clear();
   }
 
-  return NS_OK;
+  // Cancel if username/password is supplied to avoid brute-force password
+  // hacking
+  nsCOMPtr<nsIURI> channelURI;
+  nsresult rv = mChannel->GetURI(getter_AddRefs(channelURI));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCString userpass;
+  channelURI->GetUserPass(userpass);
+  NS_ENSURE_TRUE(userpass.IsEmpty(), NS_ERROR_DOM_BAD_URI);
+  
+  return nsCrossSiteListenerProxy::AddRequestHeaders(mChannel, mPrincipal);
 }
 
 /* noscript void openRequest (in AUTF8String method, in AUTF8String url, in boolean async, in AString user, in AString password); */
 NS_IMETHODIMP
 nsXMLHttpRequest::OpenRequest(const nsACString& method,
                               const nsACString& url,
                               PRBool async,
                               const nsAString& user,
@@ -1575,16 +1585,18 @@ nsXMLHttpRequest::OpenRequest(const nsAC
 
     if (expiration <= PR_Now()) {
       // Either it wasn't cached or the cached result has expired. Build a
       // channel for the OPTIONS request.
       rv = NS_NewChannel(getter_AddRefs(mACGetChannel), uri, nsnull, loadGroup,
                          nsnull, loadFlags);
       NS_ENSURE_SUCCESS(rv, rv);
 
+      rv = nsCrossSiteListenerProxy::AddRequestHeaders(mACGetChannel, mPrincipal);
+
       nsCOMPtr<nsIHttpChannel> acHttp = do_QueryInterface(mACGetChannel);
       NS_ASSERTION(acHttp, "Failed to QI to nsIHttpChannel!");
 
       rv = acHttp->SetRequestMethod(NS_LITERAL_CSTRING("OPTIONS"));
       NS_ENSURE_SUCCESS(rv, rv);
     }
   }
 
@@ -2273,20 +2285,18 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
     if (!listener) {
       return NS_ERROR_OUT_OF_MEMORY;
     }
   }
 
   if (!(mState & XML_HTTP_REQUEST_XSITEENABLED)) {
     // 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,
-                                            &rv);
+    listener = new nsCrossSiteListenerProxy(listener, mPrincipal);
     NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
-    NS_ENSURE_SUCCESS(rv, rv);
   }
 
   // Bypass the network cache in cases where it makes no sense:
   // 1) Multipart responses are very large and would likely be doomed by the
   //    cache once they grow too large, so they are not worth caching.
   // 2) POST responses are always unique, and we provide no API that would
   //    allow our consumers to specify a "cache key" to access old POST
   //    responses, so they are not worth caching.
@@ -2313,20 +2323,18 @@ nsXMLHttpRequest::Send(nsIVariant *aBody
 
   // If we're doing a cross-site non-GET request we need to first do
   // a GET request to the same URI. Set that up if needed
   if (mACGetChannel) {
     nsCOMPtr<nsIStreamListener> acListener =
       new nsACProxyListener(mChannel, listener, nsnull, mPrincipal, method);
     NS_ENSURE_TRUE(acListener, NS_ERROR_OUT_OF_MEMORY);
 
-    listener = new nsCrossSiteListenerProxy(acListener, mPrincipal,
-                                            mACGetChannel, &rv);
+    listener = new nsCrossSiteListenerProxy(acListener, mPrincipal);
     NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
-    NS_ENSURE_SUCCESS(rv, rv);
 
     rv = mACGetChannel->AsyncOpen(listener, nsnull);
   }
   else {
     // Start reading from the channel
     rv = mChannel->AsyncOpen(listener, nsnull);
   }
 
--- a/content/xml/document/src/nsXMLContentSink.cpp
+++ b/content/xml/document/src/nsXMLContentSink.cpp
@@ -766,16 +766,19 @@ nsXMLContentSink::ProcessStyleLink(nsICo
 
     // Do security check
     nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
     rv = secMan->
       CheckLoadURIWithPrincipal(mDocument->NodePrincipal(), url,
                                 nsIScriptSecurityManager::ALLOW_CHROME);
     NS_ENSURE_SUCCESS(rv, NS_OK);
 
+    rv = secMan->CheckSameOriginURI(mDocumentURI, url, PR_TRUE);
+    NS_ENSURE_SUCCESS(rv, NS_OK);
+
     // Do content policy check
     PRInt16 decision = nsIContentPolicy::ACCEPT;
     rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
                                    url,
                                    mDocument->NodePrincipal(),
                                    aElement,
                                    type,
                                    nsnull,
--- a/content/xml/document/src/nsXMLDocument.cpp
+++ b/content/xml/document/src/nsXMLDocument.cpp
@@ -373,19 +373,16 @@ nsXMLDocument::Load(const nsAString& aUr
 
   // Get security manager, check to see whether the current document
   // is allowed to load this URI. It's important to use the current
   // document's principal for this check so that we don't end up in a
   // case where code with elevated privileges is calling us and
   // changing the principal of this document.
   nsIScriptSecurityManager *secMan = nsContentUtils::GetSecurityManager();
 
-  // Enforce same-origin even for chrome loaders to avoid someone accidentally
-  // using a document that content has a reference to and turn that into a
-  // chrome document.
   if (codebase) {
     rv = secMan->CheckSameOriginURI(codebase, uri, PR_FALSE);
 
     if (NS_FAILED(rv)) {
       return rv;
     }
   } else {
     // We're called from chrome, check to make sure the URI we're
--- a/content/xslt/src/xml/txXMLParser.cpp
+++ b/content/xslt/src/xml/txXMLParser.cpp
@@ -95,25 +95,28 @@ txParseDocumentFromURI(const nsAString& 
     nsCOMPtr<nsIURI> documentURI;
     nsresult rv = NS_NewURI(getter_AddRefs(documentURI), aHref);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsIDocument* loaderDocument = txXPathNativeNode::getDocument(aLoader);
 
     nsCOMPtr<nsILoadGroup> loadGroup = loaderDocument->GetDocumentLoadGroup();
 
+    nsCOMPtr<nsIURI> loaderUri;
+    rv = loaderDocument->NodePrincipal()->GetURI(getter_AddRefs(loaderUri));
+    NS_ENSURE_SUCCESS(rv, rv);
+
     // For the system principal loaderUri will be null here, which is good
     // since that means that chrome documents can load any uri.
 
     // Raw pointer, we want the resulting txXPathNode to hold a reference to
     // the document.
     nsIDOMDocument* theDocument = nsnull;
-    rv = nsSyncLoadService::LoadDocument(documentURI,
-                                         loaderDocument->NodePrincipal(),
-                                         loadGroup, PR_TRUE, &theDocument);
+    rv = nsSyncLoadService::LoadDocument(documentURI, loaderUri, loadGroup,
+                                         PR_TRUE, &theDocument);
 
     if (NS_FAILED(rv)) {
         aErrMsg.Append(NS_LITERAL_STRING("Document load of ") + 
                        aHref + NS_LITERAL_STRING(" failed."));
         return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
     }
 
     *aResult = txXPathNativeNode::createXPathNode(theDocument);
--- a/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
+++ b/content/xslt/src/xslt/txMozillaStylesheetCompiler.cpp
@@ -65,18 +65,16 @@
 #include "txAtoms.h"
 #include "txLog.h"
 #include "txMozillaXSLTProcessor.h"
 #include "txStylesheetCompiler.h"
 #include "txXMLUtils.h"
 #include "nsAttrName.h"
 #include "nsIScriptError.h"
 #include "nsIURL.h"
-#include "nsCrossSiteListenerProxy.h"
-#include "nsDOMError.h"
 
 static NS_DEFINE_CID(kCParserCID, NS_PARSER_CID);
 
 static void
 getSpec(nsIChannel* aChannel, nsAString& aSpec)
 {
     if (!aChannel) {
         return;
@@ -91,25 +89,27 @@ getSpec(nsIChannel* aChannel, nsAString&
     nsCAutoString spec;
     uri->GetSpec(spec);
     AppendUTF8toUTF16(spec, aSpec);
 }
 
 class txStylesheetSink : public nsIXMLContentSink,
                          public nsIExpatSink,
                          public nsIStreamListener,
+                         public nsIChannelEventSink,
                          public nsIInterfaceRequestor
 {
 public:
     txStylesheetSink(txStylesheetCompiler* aCompiler, nsIParser* aParser);
 
     NS_DECL_ISUPPORTS
     NS_DECL_NSIEXPATSINK
     NS_DECL_NSISTREAMLISTENER
     NS_DECL_NSIREQUESTOBSERVER
+    NS_DECL_NSICHANNELEVENTSINK
     NS_DECL_NSIINTERFACEREQUESTOR
 
     // nsIContentSink
     NS_IMETHOD WillTokenize(void) { return NS_OK; }
     NS_IMETHOD WillBuildModel(void) { return NS_OK; }
     NS_IMETHOD DidBuildModel();
     NS_IMETHOD WillInterrupt(void) { return NS_OK; }
     NS_IMETHOD WillResume(void) { return NS_OK; }
@@ -131,22 +131,23 @@ protected:
 txStylesheetSink::txStylesheetSink(txStylesheetCompiler* aCompiler,
                                    nsIParser* aParser)
     : mCompiler(aCompiler),
       mCheckedForXML(PR_FALSE)
 {
     mListener = do_QueryInterface(aParser);
 }
 
-NS_IMPL_ISUPPORTS6(txStylesheetSink,
+NS_IMPL_ISUPPORTS7(txStylesheetSink,
                    nsIXMLContentSink,
                    nsIContentSink,
                    nsIExpatSink,
                    nsIStreamListener,
                    nsIRequestObserver,
+                   nsIChannelEventSink,
                    nsIInterfaceRequestor)
 
 NS_IMETHODIMP
 txStylesheetSink::HandleStartElement(const PRUnichar *aName,
                                      const PRUnichar **aAtts,
                                      PRUint32 aAttsCount,
                                      PRInt32 aIndex,
                                      PRUint32 aLineNumber)
@@ -369,16 +370,39 @@ txStylesheetSink::OnStopRequest(nsIReque
     }
 
     nsresult rv = mListener->OnStopRequest(aRequest, aContext, aStatusCode);
     mListener = nsnull;
     return rv;
 }
 
 NS_IMETHODIMP
+txStylesheetSink::OnChannelRedirect(nsIChannel *aOldChannel,
+                                    nsIChannel *aNewChannel,
+                                    PRUint32    aFlags)
+{
+    NS_PRECONDITION(aNewChannel, "Redirect without a channel?");
+
+    nsresult rv;
+    nsCOMPtr<nsIScriptSecurityManager> secMan =
+        do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID, &rv);
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIURI> oldURI;
+    rv = aOldChannel->GetURI(getter_AddRefs(oldURI)); // The original URI
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    nsCOMPtr<nsIURI> newURI;
+    rv = aNewChannel->GetURI(getter_AddRefs(newURI)); // The new URI
+    NS_ENSURE_SUCCESS(rv, rv);
+
+    return secMan->CheckSameOriginURI(oldURI, newURI, PR_TRUE);
+}
+
+NS_IMETHODIMP
 txStylesheetSink::GetInterface(const nsIID& aIID, void** aResult)
 {
     if (aIID.Equals(NS_GET_IID(nsIAuthPrompt))) {
         NS_ENSURE_ARG(aResult);
         *aResult = nsnull;
 
         nsresult rv;
         nsCOMPtr<nsIWindowWatcher> wwatcher =
@@ -391,17 +415,17 @@ txStylesheetSink::GetInterface(const nsI
 
         nsIAuthPrompt* rawPtr = nsnull;
         prompt.swap(rawPtr);
         *aResult = rawPtr;
 
         return NS_OK;
     }
 
-    return NS_ERROR_NO_INTERFACE;
+    return QueryInterface(aIID, aResult);
 }
 
 class txCompileObserver : public txACompileObserver
 {
 public:
     txCompileObserver(txMozillaXSLTProcessor* aProcessor,
                       nsILoadGroup* aLoadGroup);
 
@@ -464,29 +488,23 @@ txCompileObserver::loadURI(const nsAStri
     rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIPrincipal> referrerPrincipal;
     rv = nsContentUtils::GetSecurityManager()->
       GetCodebasePrincipal(referrerUri, getter_AddRefs(referrerPrincipal));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    // Content Policy
-    PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
-    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
-                                   uri,
-                                   referrerPrincipal,
-                                   nsnull,
-                                   NS_LITERAL_CSTRING("application/xml"),
-                                   nsnull,
-                                   &shouldLoad);
+    // Do security check.
+    rv = nsContentUtils::
+      CheckSecurityBeforeLoad(uri, referrerPrincipal,
+                              nsIScriptSecurityManager::STANDARD, PR_FALSE,
+                              nsIContentPolicy::TYPE_STYLESHEET,
+                              nsnull, NS_LITERAL_CSTRING("application/xml"));
     NS_ENSURE_SUCCESS(rv, rv);
-    if (NS_CP_REJECTED(shouldLoad)) {
-        return NS_ERROR_DOM_BAD_URI;
-    }
 
     return startLoad(uri, aCompiler, referrerPrincipal);
 }
 
 void
 txCompileObserver::onDoneCompiling(txStylesheetCompiler* aCompiler,
                                    nsresult aResult,
                                    const PRUnichar *aErrorText,
@@ -532,47 +550,35 @@ txCompileObserver::startLoad(nsIURI* aUr
     NS_ENSURE_TRUE(sink, NS_ERROR_OUT_OF_MEMORY);
 
     channel->SetNotificationCallbacks(sink);
 
     parser->SetCommand(kLoadAsData);
     parser->SetContentSink(sink);
     parser->Parse(aUri);
 
-    // Always install in case of redirects
-    nsCOMPtr<nsIStreamListener> listener =
-        new nsCrossSiteListenerProxy(sink, aReferrerPrincipal, channel, &rv);
-    NS_ENSURE_TRUE(listener, NS_ERROR_OUT_OF_MEMORY);
-    NS_ENSURE_SUCCESS(rv, rv);
-
     return channel->AsyncOpen(sink, parser);
 }
 
 nsresult
 TX_LoadSheet(nsIURI* aUri, txMozillaXSLTProcessor* aProcessor,
              nsILoadGroup* aLoadGroup, nsIPrincipal* aCallerPrincipal)
 {
     nsCAutoString spec;
     aUri->GetSpec(spec);
     PR_LOG(txLog::xslt, PR_LOG_ALWAYS, ("TX_LoadSheet: %s\n", spec.get()));
 
-    // Content Policy
-    PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
-    nsresult rv =
-        NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
-                                  aUri,
-                                  aCallerPrincipal,
-                                  aProcessor->GetSourceContentModel(),
-                                  NS_LITERAL_CSTRING("application/xml"),
-                                  nsnull,
-                                  &shouldLoad);
+    // Pass source document as the context
+    nsresult rv = nsContentUtils::
+      CheckSecurityBeforeLoad(aUri, aCallerPrincipal,
+                              nsIScriptSecurityManager::STANDARD, PR_FALSE,
+                              nsIContentPolicy::TYPE_STYLESHEET,
+                              aProcessor->GetSourceContentModel(),
+                              NS_LITERAL_CSTRING("application/xml"));
     NS_ENSURE_SUCCESS(rv, rv);
-    if (NS_CP_REJECTED(shouldLoad)) {
-        return NS_ERROR_DOM_BAD_URI;
-    }
 
     nsRefPtr<txCompileObserver> observer =
         new txCompileObserver(aProcessor, aLoadGroup);
     NS_ENSURE_TRUE(observer, NS_ERROR_OUT_OF_MEMORY);
 
     nsRefPtr<txStylesheetCompiler> compiler =
         new txStylesheetCompiler(NS_ConvertUTF8toUTF16(spec), observer);
     NS_ENSURE_TRUE(compiler, NS_ERROR_OUT_OF_MEMORY);
@@ -704,35 +710,28 @@ txSyncCompileObserver::loadURI(const nsA
     rv = NS_NewURI(getter_AddRefs(referrerUri), aReferrerUri);
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIPrincipal> referrerPrincipal;
     rv = nsContentUtils::GetSecurityManager()->
       GetCodebasePrincipal(referrerUri, getter_AddRefs(referrerPrincipal));
     NS_ENSURE_SUCCESS(rv, rv);
 
-    // Content Policy
-    PRInt16 shouldLoad = nsIContentPolicy::ACCEPT;
-    rv = NS_CheckContentLoadPolicy(nsIContentPolicy::TYPE_STYLESHEET,
-                                   uri,
-                                   referrerPrincipal,
-                                   nsnull,
-                                   NS_LITERAL_CSTRING("application/xml"),
-                                   nsnull,
-                                   &shouldLoad);
+    rv = nsContentUtils::
+      CheckSecurityBeforeLoad(uri, referrerPrincipal,
+                              nsIScriptSecurityManager::STANDARD,
+                              PR_FALSE, nsIContentPolicy::TYPE_STYLESHEET,
+                              nsnull, NS_LITERAL_CSTRING("application/xml"));
     NS_ENSURE_SUCCESS(rv, rv);
-    if (NS_CP_REJECTED(shouldLoad)) {
-        return NS_ERROR_DOM_BAD_URI;
-    }
 
     // This is probably called by js, a loadGroup for the channel doesn't
     // make sense.
     nsCOMPtr<nsIDOMDocument> document;
-    rv = nsSyncLoadService::LoadDocument(uri, referrerPrincipal, nsnull,
-                                         PR_FALSE, getter_AddRefs(document));
+    rv = nsSyncLoadService::LoadDocument(uri, referrerUri, nsnull, PR_FALSE,
+                                         getter_AddRefs(document));
     NS_ENSURE_SUCCESS(rv, rv);
 
     nsCOMPtr<nsIDocument> doc = do_QueryInterface(document);
     rv = handleNode(doc, aCompiler);
     if (NS_FAILED(rv)) {
         nsCAutoString spec;
         uri->GetSpec(spec);
         aCompiler->cancel(rv, nsnull, NS_ConvertUTF8toUTF16(spec).get());
--- a/content/xul/document/src/nsXULDocument.cpp
+++ b/content/xul/document/src/nsXULDocument.cpp
@@ -2600,23 +2600,26 @@ nsXULDocument::LoadOverlayInternal(nsIUR
         PR_LOG(gXULLog, PR_LOG_DEBUG,
                 ("xul: loading overlay %s", urlspec.get()));
     }
 #endif
 
     if (aIsDynamic)
         mResolutionPhase = nsForwardReference::eStart;
 
+    nsIScriptSecurityManager* secMan = nsContentUtils::GetSecurityManager();
+    NS_ENSURE_TRUE(secMan, NS_ERROR_NOT_AVAILABLE);
+
     // Chrome documents are allowed to load overlays from anywhere.
     // In all other cases, the overlay is only allowed to load if
     // the master document and prototype document have the same origin.
 
     if (!IsChromeURI(mDocumentURI)) {
         // Make sure we're allowed to load this overlay.
-        rv = NodePrincipal()->CheckMayLoad(aURI, PR_TRUE);
+        rv = secMan->CheckSameOriginURI(mDocumentURI, aURI, PR_TRUE);
         if (NS_FAILED(rv)) {
             *aFailureFromContent = PR_TRUE;
             return rv;
         }
     }
 
     // Look in the prototype cache for the prototype document with
     // the specified overlay URI.
--- a/extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp
+++ b/extensions/canvas3d/src/nsCanvasRenderingContextGL.cpp
@@ -708,26 +708,40 @@ nsCanvasRenderingContextGLPrivate::DoDra
 
     fprintf (stderr, "DoDrawImageSecuritycheck this 3: %p\n", this);
     if (forceWriteOnly) {
         mCanvasElement->SetWriteOnly();
         return;
     }
 
     fprintf (stderr, "DoDrawImageSecuritycheck this 4: %p\n", this);
+    nsCOMPtr<nsIScriptSecurityManager> ssm =
+        do_GetService(NS_SCRIPTSECURITYMANAGER_CONTRACTID);
+    if (!ssm) {
+        mCanvasElement->SetWriteOnly();
+        return;
+    }
+
+    fprintf (stderr, "DoDrawImageSecuritycheck this 5: %p\n", this);
     nsCOMPtr<nsINode> elem = do_QueryInterface(mCanvasElement);
-    if (elem) {
-        rv = elem->NodePrincipal()->CheckMayLoad(aURI);
-        if (NS_SUCCEEDED(rv)) {
-            // Same origin
-            return;
+    if (elem && ssm) {
+        nsCOMPtr<nsIPrincipal> uriPrincipal;
+        ssm->GetCodebasePrincipal(aURI, getter_AddRefs(uriPrincipal));
+
+        if (uriPrincipal) {
+            nsresult rv = ssm->CheckSameOriginPrincipal(elem->NodePrincipal(),
+                                                        uriPrincipal);
+            if (NS_SUCCEEDED(rv)) {
+                // Same origin
+                return;
+            }
         }
     }
 
-    fprintf (stderr, "DoDrawImageSecuritycheck this 5: %p\n", this); fflush(stderr);
+    fprintf (stderr, "DoDrawImageSecuritycheck this 6: %p\n", this); fflush(stderr);
     mCanvasElement->SetWriteOnly();
 #endif
 }
 
 
 nsCanvasRenderingContextGLPrivate::nsCanvasRenderingContextGLPrivate()
     : mGLPbuffer(nsnull), mWidth(0), mHeight(0), mCanvasElement(nsnull)
 {