Followup patch to bug 425201. Make sure to throw if xhr.open is called with an illegal uri. Also restore the nsIScriptSecurityManager.CheckConnect API as soap still uses it
This commit is contained in:
Родитель
4d1513544b
Коммит
3cbf219992
|
@ -51,6 +51,15 @@ interface nsIURI;
|
|||
[ptr] native JSContext(JSContext);
|
||||
[ptr] native JSPrincipals(JSPrincipals);
|
||||
|
||||
/**
|
||||
* WARNING!! The JEP needs to call GetOrigin() to support
|
||||
* JavaScript-to-Java LiveConnect. So every change to the nsIPrincipal
|
||||
* interface (big enough to change its IID) also breaks JavaScript-to-Java
|
||||
* LiveConnect on mac.
|
||||
*
|
||||
* If you REALLY have to change this interface, please mark your bug as
|
||||
* blocking bug 293973.
|
||||
*/
|
||||
[scriptable, uuid(b8268b9a-2403-44ed-81e3-614075c92034)]
|
||||
interface nsIPrincipal : nsISerializable
|
||||
{
|
||||
|
|
|
@ -41,8 +41,16 @@
|
|||
interface nsIURI;
|
||||
interface nsIChannel;
|
||||
|
||||
|
||||
[scriptable, uuid(e74487fd-98ef-48d1-b973-3f2938f04e8e)]
|
||||
/**
|
||||
* WARNING!! The JEP needs to call GetSubjectPrincipal()
|
||||
* to support JavaScript-to-Java LiveConnect. So every change to the
|
||||
* nsIScriptSecurityManager interface (big enough to change its IID) also
|
||||
* breaks JavaScript-to-Java LiveConnect on mac.
|
||||
*
|
||||
* If you REALLY have to change this interface, please mark your bug as
|
||||
* blocking bug 293973.
|
||||
*/
|
||||
[scriptable, uuid(3fffd8e8-3fea-442e-a0ed-2ba81ae197d5)]
|
||||
interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
||||
{
|
||||
///////////////// Security Checks //////////////////
|
||||
|
@ -55,6 +63,14 @@ interface nsIScriptSecurityManager : nsIXPCSecurityManager
|
|||
in JSVal aProperty,
|
||||
in PRUint32 aAction);
|
||||
|
||||
/**
|
||||
* Checks whether the running script is allowed to connect to aTargetURI
|
||||
*/
|
||||
[noscript] void checkConnect(in JSContextPtr aJSContext,
|
||||
in nsIURI aTargetURI,
|
||||
in string aClassName,
|
||||
in string aProperty);
|
||||
|
||||
/**
|
||||
* Check that the script currently running in context "cx" can load "uri".
|
||||
*
|
||||
|
|
|
@ -408,7 +408,8 @@ public:
|
|||
nsIURI* aSource, nsIURI* aTarget);
|
||||
static nsresult
|
||||
CheckSameOriginPrincipal(nsIPrincipal* aSubject,
|
||||
nsIPrincipal* aObject);
|
||||
nsIPrincipal* aObject,
|
||||
PRBool aIsCheckConnect);
|
||||
|
||||
static PRBool
|
||||
GetStrictFileOriginPolicy()
|
||||
|
@ -445,7 +446,7 @@ private:
|
|||
CheckPropertyAccessImpl(PRUint32 aAction,
|
||||
nsAXPCNativeCallContext* aCallContext,
|
||||
JSContext* cx, JSObject* aJSObject,
|
||||
nsISupports* aObj,
|
||||
nsISupports* aObj, nsIURI* aTargetURI,
|
||||
nsIClassInfo* aClassInfo,
|
||||
const char* aClassName, jsval aProperty,
|
||||
void** aCachedClassPolicy);
|
||||
|
@ -453,7 +454,8 @@ private:
|
|||
nsresult
|
||||
CheckSameOriginDOMProp(nsIPrincipal* aSubject,
|
||||
nsIPrincipal* aObject,
|
||||
PRUint32 aAction);
|
||||
PRUint32 aAction,
|
||||
PRBool aIsCheckConnect);
|
||||
|
||||
nsresult
|
||||
LookupPolicy(nsIPrincipal* principal,
|
||||
|
|
|
@ -291,7 +291,8 @@ nsPrincipal::Equals(nsIPrincipal *aOther, PRBool *aResult)
|
|||
// Codebases are equal if they have the same origin.
|
||||
*aResult =
|
||||
NS_SUCCEEDED(nsScriptSecurityManager::CheckSameOriginPrincipal(this,
|
||||
aOther));
|
||||
aOther,
|
||||
PR_FALSE));
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
|
|
|
@ -571,10 +571,38 @@ nsScriptSecurityManager::CheckPropertyAccess(JSContext* cx,
|
|||
PRUint32 aAction)
|
||||
{
|
||||
return CheckPropertyAccessImpl(aAction, nsnull, cx, aJSObject,
|
||||
nsnull, nsnull,
|
||||
nsnull, nsnull, nsnull,
|
||||
aClassName, aProperty, nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckConnect(JSContext* cx,
|
||||
nsIURI* aTargetURI,
|
||||
const char* aClassName,
|
||||
const char* aPropertyName)
|
||||
{
|
||||
// Get a context if necessary
|
||||
if (!cx)
|
||||
{
|
||||
cx = GetCurrentJSContext();
|
||||
if (!cx)
|
||||
return NS_OK; // No JS context, so allow the load
|
||||
}
|
||||
|
||||
nsresult rv = CheckLoadURIFromScript(cx, aTargetURI);
|
||||
if (NS_FAILED(rv)) return rv;
|
||||
|
||||
JSAutoRequest ar(cx);
|
||||
|
||||
JSString* propertyName = ::JS_InternString(cx, aPropertyName);
|
||||
if (!propertyName)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
return CheckPropertyAccessImpl(nsIXPCSecurityManager::ACCESS_CALL_METHOD, nsnull,
|
||||
cx, nsnull, nsnull, aTargetURI,
|
||||
nsnull, aClassName, STRING_TO_JSVAL(propertyName), nsnull);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsScriptSecurityManager::CheckSameOrigin(JSContext* cx,
|
||||
nsIURI* aTargetURI)
|
||||
|
@ -645,7 +673,7 @@ nsresult
|
|||
nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
|
||||
nsAXPCNativeCallContext* aCallContext,
|
||||
JSContext* cx, JSObject* aJSObject,
|
||||
nsISupports* aObj,
|
||||
nsISupports* aObj, nsIURI* aTargetURI,
|
||||
nsIClassInfo* aClassInfo,
|
||||
const char* aClassName, jsval aProperty,
|
||||
void** aCachedClassPolicy)
|
||||
|
@ -720,14 +748,22 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
|
|||
if (!objectPrincipal)
|
||||
rv = NS_ERROR_DOM_SECURITY_ERR;
|
||||
}
|
||||
else if(aTargetURI)
|
||||
{
|
||||
if (NS_FAILED(GetCodebasePrincipal(
|
||||
aTargetURI, getter_AddRefs(principalHolder))))
|
||||
return NS_ERROR_FAILURE;
|
||||
|
||||
objectPrincipal = principalHolder;
|
||||
}
|
||||
else
|
||||
{
|
||||
NS_ERROR("CheckPropertyAccessImpl called without a target object");
|
||||
NS_ERROR("CheckPropertyAccessImpl called without a target object or URL");
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
if(NS_SUCCEEDED(rv))
|
||||
rv = CheckSameOriginDOMProp(subjectPrincipal, objectPrincipal,
|
||||
aAction);
|
||||
aAction, aTargetURI != nsnull);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
@ -862,7 +898,8 @@ nsScriptSecurityManager::CheckPropertyAccessImpl(PRUint32 aAction,
|
|||
/* static */
|
||||
nsresult
|
||||
nsScriptSecurityManager::CheckSameOriginPrincipal(nsIPrincipal* aSubject,
|
||||
nsIPrincipal* aObject)
|
||||
nsIPrincipal* aObject,
|
||||
PRBool aIsCheckConnect)
|
||||
{
|
||||
/*
|
||||
** Get origin of subject and object and compare.
|
||||
|
@ -870,12 +907,23 @@ nsScriptSecurityManager::CheckSameOriginPrincipal(nsIPrincipal* aSubject,
|
|||
if (aSubject == aObject)
|
||||
return NS_OK;
|
||||
|
||||
// These booleans are only used when !aIsCheckConnect. Default
|
||||
// them to false, and change if that turns out wrong.
|
||||
PRBool subjectSetDomain = PR_FALSE;
|
||||
PRBool objectSetDomain = PR_FALSE;
|
||||
|
||||
nsCOMPtr<nsIURI> subjectURI;
|
||||
nsCOMPtr<nsIURI> objectURI;
|
||||
|
||||
if (aIsCheckConnect)
|
||||
{
|
||||
// Don't use domain for CheckConnect calls, since that's called for
|
||||
// data-only load checks like XMLHTTPRequest (bug 290100).
|
||||
aSubject->GetURI(getter_AddRefs(subjectURI));
|
||||
aObject->GetURI(getter_AddRefs(objectURI));
|
||||
}
|
||||
else
|
||||
{
|
||||
aSubject->GetDomain(getter_AddRefs(subjectURI));
|
||||
if (!subjectURI) {
|
||||
aSubject->GetURI(getter_AddRefs(subjectURI));
|
||||
|
@ -889,6 +937,7 @@ nsScriptSecurityManager::CheckSameOriginPrincipal(nsIPrincipal* aSubject,
|
|||
} else {
|
||||
objectSetDomain = PR_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
if (SecurityCompareURIs(subjectURI, objectURI))
|
||||
{ // If either the subject or the object has changed its principal by
|
||||
|
@ -896,6 +945,12 @@ nsScriptSecurityManager::CheckSameOriginPrincipal(nsIPrincipal* aSubject,
|
|||
// done so in order to be considered the same origin. This prevents
|
||||
// DNS spoofing based on document.domain (154930)
|
||||
|
||||
// But this restriction does not apply to CheckConnect calls, since
|
||||
// that's called for data-only load checks like XMLHTTPRequest where
|
||||
// we ignore domain (bug 290100).
|
||||
if (aIsCheckConnect)
|
||||
return NS_OK;
|
||||
|
||||
// If both or neither explicitly set their domain, allow the access
|
||||
if (subjectSetDomain == objectSetDomain)
|
||||
return NS_OK;
|
||||
|
@ -911,14 +966,22 @@ nsScriptSecurityManager::CheckSameOriginPrincipal(nsIPrincipal* aSubject,
|
|||
nsresult
|
||||
nsScriptSecurityManager::CheckSameOriginDOMProp(nsIPrincipal* aSubject,
|
||||
nsIPrincipal* aObject,
|
||||
PRUint32 aAction)
|
||||
PRUint32 aAction,
|
||||
PRBool aIsCheckConnect)
|
||||
{
|
||||
nsresult rv;
|
||||
if (aIsCheckConnect) {
|
||||
// Don't do equality compares, just do a same-origin compare,
|
||||
// since the object principal isn't a real principal, just a
|
||||
// GetCodebasePrincipal() on whatever URI we started with.
|
||||
rv = CheckSameOriginPrincipal(aSubject, aObject, aIsCheckConnect);
|
||||
} else {
|
||||
PRBool subsumes;
|
||||
rv = aSubject->Subsumes(aObject, &subsumes);
|
||||
if (NS_SUCCEEDED(rv) && !subsumes) {
|
||||
rv = NS_ERROR_DOM_PROP_ACCESS_DENIED;
|
||||
}
|
||||
}
|
||||
|
||||
if (NS_SUCCEEDED(rv))
|
||||
return NS_OK;
|
||||
|
@ -3062,7 +3125,7 @@ nsScriptSecurityManager::CanAccess(PRUint32 aAction,
|
|||
void** aPolicy)
|
||||
{
|
||||
return CheckPropertyAccessImpl(aAction, aCallContext, cx,
|
||||
aJSObject, aObj, aClassInfo,
|
||||
aJSObject, aObj, nsnull, aClassInfo,
|
||||
nsnull, aPropertyName, aPolicy);
|
||||
}
|
||||
|
||||
|
|
|
@ -1275,7 +1275,7 @@ nsXMLHttpRequest::Open(const nsACString& method, const nsACString& url)
|
|||
} else {
|
||||
mState &= ~XML_HTTP_REQUEST_XSITEENABLED;
|
||||
rv = mPrincipal->CheckMayLoad(targetURI, PR_TRUE);
|
||||
NS_ENSURE_SUCCESS(rv, NS_OK);
|
||||
NS_ENSURE_SUCCESS(rv, rv);
|
||||
}
|
||||
|
||||
if (argc > 2) {
|
||||
|
|
|
@ -174,6 +174,7 @@ _TEST_FILES = test_bug5141.html \
|
|||
test_bug428847.html \
|
||||
file_bug428847-1.xhtml \
|
||||
file_bug428847-2.xhtml \
|
||||
test_bug425201.html \
|
||||
$(NULL)
|
||||
|
||||
libs:: $(_TEST_FILES)
|
||||
|
|
|
@ -0,0 +1,48 @@
|
|||
<!DOCTYPE HTML>
|
||||
<html>
|
||||
<!--
|
||||
https://bugzilla.mozilla.org/show_bug.cgi?id=425201
|
||||
-->
|
||||
<head>
|
||||
<title>Test for Bug 425201</title>
|
||||
<script type="text/javascript" src="/MochiKit/MochiKit.js"></script>
|
||||
<script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
|
||||
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" />
|
||||
</head>
|
||||
<body>
|
||||
<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=425201">Mozilla Bug 425201</a>
|
||||
<p id="display"></p>
|
||||
<div id="content" style="display: none">
|
||||
|
||||
</div>
|
||||
<pre id="test">
|
||||
<script class="testbody" type="text/javascript">
|
||||
|
||||
/** Test for Bug 425201 **/
|
||||
|
||||
var req = new XMLHttpRequest();
|
||||
|
||||
var threw = false;
|
||||
try {
|
||||
req.open("GET", "http://www.example.com/", false);
|
||||
}
|
||||
catch (e) {
|
||||
threw = true;
|
||||
}
|
||||
|
||||
ok(threw, "Open should have thrown");
|
||||
|
||||
threw = false;
|
||||
try {
|
||||
req.send(null);
|
||||
}
|
||||
catch (e) {
|
||||
threw = true;
|
||||
}
|
||||
|
||||
ok(threw, "Send should have thrown");
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
</html>
|
Загрузка…
Ссылка в новой задаче