From 4eb52aa84b3d5919e863fec51291f3aa0d49bfea Mon Sep 17 00:00:00 2001 From: "norris%netscape.com" Date: Fri, 24 Mar 2000 22:15:37 +0000 Subject: [PATCH] Fix 32088 Circumventing Same Origin security policy using javascript: URLs 32040 about: can't be link Also remove deprecated method r=mstoltz --- caps/src/nsScriptSecurityManager.cpp | 13 +------ content/html/document/src/nsHTMLDocument.cpp | 39 +++++++++++++++++++ content/xml/document/src/nsXMLContentSink.cpp | 3 +- dom/public/nsIScriptContext.h | 8 ---- dom/src/base/nsJSEnvironment.cpp | 12 ------ dom/src/base/nsJSEnvironment.h | 6 --- editor/base/nsEditorShell.cpp | 2 +- editor/composer/src/nsEditorShell.cpp | 2 +- layout/html/document/src/nsHTMLDocument.cpp | 39 +++++++++++++++++++ layout/xml/document/src/nsXMLContentSink.cpp | 3 +- webshell/tests/viewer/JSConsole.cpp | 2 + xpfe/browser/src/nsBrowserInstance.cpp | 2 +- 12 files changed, 89 insertions(+), 42 deletions(-) diff --git a/caps/src/nsScriptSecurityManager.cpp b/caps/src/nsScriptSecurityManager.cpp index fece22707cb4..53cf967f66a8 100644 --- a/caps/src/nsScriptSecurityManager.cpp +++ b/caps/src/nsScriptSecurityManager.cpp @@ -471,12 +471,12 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aFromURI, nsIURI *aURI, return NS_OK; } - enum Action { AllowProtocol, DenyProtocol, AboutProtocol}; + enum Action { AllowProtocol, DenyProtocol }; struct { const char *name; Action action; } protocolList[] = { - { "about", AboutProtocol }, + { "about", AllowProtocol }, { "data", AllowProtocol }, { "file", DenyProtocol }, { "ftp", AllowProtocol }, @@ -505,15 +505,6 @@ nsScriptSecurityManager::CheckLoadURI(nsIURI *aFromURI, nsIURI *aURI, case DenyProtocol: // Deny access return NS_ERROR_DOM_BAD_URI; - case AboutProtocol: - // Allow for about:blank, deny for others. - nsXPIDLCString spec; - if (NS_FAILED(aURI->GetSpec(getter_Copies(spec)))) - return NS_ERROR_FAILURE; - if (nsCRT::strcasecmp(spec, "about:blank") == 0) { - return NS_OK; - } - return NS_ERROR_DOM_BAD_URI; } } } diff --git a/content/html/document/src/nsHTMLDocument.cpp b/content/html/document/src/nsHTMLDocument.cpp index 6ed4772c0938..dfba2150e542 100644 --- a/content/html/document/src/nsHTMLDocument.cpp +++ b/content/html/document/src/nsHTMLDocument.cpp @@ -2000,6 +2000,45 @@ nsHTMLDocument::ScriptWriteCommon(JSContext *cx, { nsresult result = NS_OK; + + nsXPIDLCString spec; + if (!mDocumentURL || + (NS_SUCCEEDED(mDocumentURL->GetSpec(getter_Copies(spec))) && + nsCRT::strcasecmp(spec, "about:blank") == 0)) + { + // The current document's URL and principal are empty or "about:blank". + // By writing to this document, the script acquires responsibility for the + // document for security purposes. Thus a document.write of a script tag + // ends up producing a script with the same principals as the script + // that performed the write. + nsIScriptContext *context = (nsIScriptContext*)JS_GetContextPrivate(cx); + JSObject* obj; + if (NS_FAILED(GetScriptObject(context, (void**)&obj))) + return NS_ERROR_FAILURE; + nsIScriptSecurityManager *sm = nsJSUtils::nsGetSecurityManager(cx, nsnull); + if (!sm) + return NS_ERROR_FAILURE; + nsCOMPtr subject; + if (NS_FAILED(sm->GetSubjectPrincipal(getter_AddRefs(subject)))) + return NS_ERROR_FAILURE; + if (subject) { + nsCOMPtr codebase = do_QueryInterface(subject); + if (codebase) { + nsCOMPtr subjectURI; + if (NS_FAILED(codebase->GetURI(getter_AddRefs(subjectURI)))) + return NS_ERROR_FAILURE; + + NS_IF_RELEASE(mDocumentURL); + mDocumentURL = subjectURI; + NS_ADDREF(mDocumentURL); + + NS_IF_RELEASE(mPrincipal); + mPrincipal = subject; + NS_ADDREF(mPrincipal); + } + } + } + if (nsnull == mParser) { result = Open(cx, argv, argc); if (NS_OK != result) { diff --git a/content/xml/document/src/nsXMLContentSink.cpp b/content/xml/document/src/nsXMLContentSink.cpp index 73e32252ec39..ffc6f92c8bd4 100644 --- a/content/xml/document/src/nsXMLContentSink.cpp +++ b/content/xml/document/src/nsXMLContentSink.cpp @@ -1675,7 +1675,8 @@ nsXMLContentSink::EvaluateScript(nsString& aScript, PRUint32 aLineNo, const char nsAutoString val; PRBool isUndefined; - (void) context->EvaluateString(aScript, url, aLineNo, aVersion, + // XXX need principal + (void) context->EvaluateString(aScript, nsnull, nsnull, url, aLineNo, aVersion, val, &isUndefined); NS_IF_RELEASE(docURL); diff --git a/dom/public/nsIScriptContext.h b/dom/public/nsIScriptContext.h index 53d01018c492..474b41e1a55e 100644 --- a/dom/public/nsIScriptContext.h +++ b/dom/public/nsIScriptContext.h @@ -51,14 +51,6 @@ class nsIScriptContext : public nsISupports { public: NS_DEFINE_STATIC_IID_ACCESSOR(NS_ISCRIPTCONTEXT_IID) - // deprecated: remove later (XXXbe when is later?) - NS_IMETHOD EvaluateString(const nsString& aScript, - const char *aURL, - PRUint32 aLineNo, - const char* aVersion, - nsString& aRetValue, - PRBool* aIsUndefined) = 0; - /** * Compile and execute a script. * diff --git a/dom/src/base/nsJSEnvironment.cpp b/dom/src/base/nsJSEnvironment.cpp index ed2f75ff3389..05a11ad5d51c 100644 --- a/dom/src/base/nsJSEnvironment.cpp +++ b/dom/src/base/nsJSEnvironment.cpp @@ -193,17 +193,6 @@ nsJSContext::~nsJSContext() NS_IMPL_ISUPPORTS(nsJSContext, NS_GET_IID(nsIScriptContext)); -NS_IMETHODIMP -nsJSContext::EvaluateString(const nsString& aScript, - const char *aURL, - PRUint32 aLineNo, - const char* aVersion, - nsString& aRetValue, - PRBool* aIsUndefined) -{ - return EvaluateString(aScript, nsnull, nsnull, aURL, aLineNo, aVersion, aRetValue, aIsUndefined); -} - NS_IMETHODIMP nsJSContext::EvaluateString(const nsString& aScript, void *aScopeObject, @@ -227,7 +216,6 @@ nsJSContext::EvaluateString(const nsString& aScript, aPrincipal->GetJSPrincipals(&jsprin); } else { - // norris TODO: Using GetGlobalObject to get principals is broken? nsCOMPtr global = dont_AddRef(GetGlobalObject()); if (!global) return NS_ERROR_FAILURE; diff --git a/dom/src/base/nsJSEnvironment.h b/dom/src/base/nsJSEnvironment.h index c57fcb8417e9..087d84e0d98b 100644 --- a/dom/src/base/nsJSEnvironment.h +++ b/dom/src/base/nsJSEnvironment.h @@ -53,12 +53,6 @@ public: NS_DECL_ISUPPORTS - NS_IMETHOD EvaluateString(const nsString& aScript, - const char *aURL, - PRUint32 aLineNo, - const char* aVersion, - nsString& aRetValue, - PRBool* aIsUndefined); NS_IMETHOD EvaluateString(const nsString& aScript, void *aScopeObject, nsIPrincipal *principal, diff --git a/editor/base/nsEditorShell.cpp b/editor/base/nsEditorShell.cpp index e03c9dbcd1ee..db8067e50264 100644 --- a/editor/base/nsEditorShell.cpp +++ b/editor/base/nsEditorShell.cpp @@ -3961,7 +3961,7 @@ nsEditorShell::ExecuteScript(nsIScriptContext * aContext, const nsString& aScrip nsCRT::free(script_str); #endif - aContext->EvaluateString(aScript, url, 0, nsnull, rVal, &isUndefined); + aContext->EvaluateString(aScript, nsnull, nsnull, url, 0, nsnull, rVal, &isUndefined); } return NS_OK; } diff --git a/editor/composer/src/nsEditorShell.cpp b/editor/composer/src/nsEditorShell.cpp index e03c9dbcd1ee..db8067e50264 100644 --- a/editor/composer/src/nsEditorShell.cpp +++ b/editor/composer/src/nsEditorShell.cpp @@ -3961,7 +3961,7 @@ nsEditorShell::ExecuteScript(nsIScriptContext * aContext, const nsString& aScrip nsCRT::free(script_str); #endif - aContext->EvaluateString(aScript, url, 0, nsnull, rVal, &isUndefined); + aContext->EvaluateString(aScript, nsnull, nsnull, url, 0, nsnull, rVal, &isUndefined); } return NS_OK; } diff --git a/layout/html/document/src/nsHTMLDocument.cpp b/layout/html/document/src/nsHTMLDocument.cpp index 6ed4772c0938..dfba2150e542 100644 --- a/layout/html/document/src/nsHTMLDocument.cpp +++ b/layout/html/document/src/nsHTMLDocument.cpp @@ -2000,6 +2000,45 @@ nsHTMLDocument::ScriptWriteCommon(JSContext *cx, { nsresult result = NS_OK; + + nsXPIDLCString spec; + if (!mDocumentURL || + (NS_SUCCEEDED(mDocumentURL->GetSpec(getter_Copies(spec))) && + nsCRT::strcasecmp(spec, "about:blank") == 0)) + { + // The current document's URL and principal are empty or "about:blank". + // By writing to this document, the script acquires responsibility for the + // document for security purposes. Thus a document.write of a script tag + // ends up producing a script with the same principals as the script + // that performed the write. + nsIScriptContext *context = (nsIScriptContext*)JS_GetContextPrivate(cx); + JSObject* obj; + if (NS_FAILED(GetScriptObject(context, (void**)&obj))) + return NS_ERROR_FAILURE; + nsIScriptSecurityManager *sm = nsJSUtils::nsGetSecurityManager(cx, nsnull); + if (!sm) + return NS_ERROR_FAILURE; + nsCOMPtr subject; + if (NS_FAILED(sm->GetSubjectPrincipal(getter_AddRefs(subject)))) + return NS_ERROR_FAILURE; + if (subject) { + nsCOMPtr codebase = do_QueryInterface(subject); + if (codebase) { + nsCOMPtr subjectURI; + if (NS_FAILED(codebase->GetURI(getter_AddRefs(subjectURI)))) + return NS_ERROR_FAILURE; + + NS_IF_RELEASE(mDocumentURL); + mDocumentURL = subjectURI; + NS_ADDREF(mDocumentURL); + + NS_IF_RELEASE(mPrincipal); + mPrincipal = subject; + NS_ADDREF(mPrincipal); + } + } + } + if (nsnull == mParser) { result = Open(cx, argv, argc); if (NS_OK != result) { diff --git a/layout/xml/document/src/nsXMLContentSink.cpp b/layout/xml/document/src/nsXMLContentSink.cpp index 73e32252ec39..ffc6f92c8bd4 100644 --- a/layout/xml/document/src/nsXMLContentSink.cpp +++ b/layout/xml/document/src/nsXMLContentSink.cpp @@ -1675,7 +1675,8 @@ nsXMLContentSink::EvaluateScript(nsString& aScript, PRUint32 aLineNo, const char nsAutoString val; PRBool isUndefined; - (void) context->EvaluateString(aScript, url, aLineNo, aVersion, + // XXX need principal + (void) context->EvaluateString(aScript, nsnull, nsnull, url, aLineNo, aVersion, val, &isUndefined); NS_IF_RELEASE(docURL); diff --git a/webshell/tests/viewer/JSConsole.cpp b/webshell/tests/viewer/JSConsole.cpp index df7f64845fe5..93fa9902c29c 100644 --- a/webshell/tests/viewer/JSConsole.cpp +++ b/webshell/tests/viewer/JSConsole.cpp @@ -889,6 +889,8 @@ void JSConsole::EvaluateText(UINT aStartSel, UINT aEndSel) PRBool isUndefined; if (NS_SUCCEEDED(mContext->EvaluateString(nsString(cleanBuffer), + nsnull, + nsnull, nsnull, 0, nsnull, diff --git a/xpfe/browser/src/nsBrowserInstance.cpp b/xpfe/browser/src/nsBrowserInstance.cpp index 46102ab0cce0..f089205d0087 100644 --- a/xpfe/browser/src/nsBrowserInstance.cpp +++ b/xpfe/browser/src/nsBrowserInstance.cpp @@ -1986,7 +1986,7 @@ nsBrowserAppCore::ExecuteScript(nsIScriptContext * aContext, const nsString& aSc if (APP_DEBUG) { printf("Executing [%s]\n", (const char *)nsCAutoString(aScript)); } - aContext->EvaluateString(aScript, url, 0, nsnull, rVal, &isUndefined); + aContext->EvaluateString(aScript, nsnull, nsnull, url, 0, nsnull, rVal, &isUndefined); } return NS_OK; }