Just drop loads of scripts that are not signed if the loading page is. Bug 424426, r+sr=jst, a=beltzner

This commit is contained in:
bzbarsky@mit.edu 2008-03-24 16:58:42 -07:00
parent 4c2b6f5cd4
commit 623db8c5f5
3 changed files with 30 additions and 53 deletions

View File

@ -850,11 +850,9 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
"Could not convert external JavaScript to Unicode!");
NS_ENSURE_SUCCESS(rv, rv);
// -- Merge the principal of the script file with that of the document; if
// the script has a non-cert principal, the document's principal should be
// downgraded.
rv = DowngradePrincipalIfNeeded(mDocument, channel);
NS_ENSURE_SUCCESS(rv, rv);
if (!ShouldExecuteScript(mDocument, channel)) {
return NS_ERROR_NOT_AVAILABLE;
}
}
// This assertion could fire errorously if we ran out of memory when
@ -871,48 +869,31 @@ nsScriptLoader::PrepareLoadedRequest(nsScriptLoadRequest* aRequest,
}
/* static */
nsresult
nsScriptLoader::DowngradePrincipalIfNeeded(nsIDocument* aDocument,
nsIChannel* aChannel)
PRBool
nsScriptLoader::ShouldExecuteScript(nsIDocument* aDocument,
nsIChannel* aChannel)
{
if (!aChannel) {
return NS_ERROR_UNEXPECTED;
return PR_FALSE;
}
PRBool hasCert;
nsIPrincipal* docPrincipal = aDocument->NodePrincipal();
docPrincipal->GetHasCertificate(&hasCert);
if (!hasCert) {
return PR_TRUE;
}
nsCOMPtr<nsIPrincipal> channelPrincipal;
nsresult rv = nsContentUtils::GetSecurityManager()->
GetChannelPrincipal(aChannel, getter_AddRefs(channelPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
NS_ENSURE_SUCCESS(rv, PR_FALSE);
NS_ASSERTION(channelPrincipal, "Gotta have a principal here!");
// If the document principal is a cert principal and aNewPrincipal
// is not the same as the channel principal, downgrade the document
// principal to a codebase principal.
PRBool hasCert;
nsIPrincipal* docPrincipal = aDocument->NodePrincipal();
docPrincipal->GetHasCertificate(&hasCert);
if (hasCert) {
PRBool equal;
docPrincipal->Equals(channelPrincipal, &equal);
if (!equal) {
nsCOMPtr<nsIURI> uri, domain;
docPrincipal->GetURI(getter_AddRefs(uri));
docPrincipal->GetDomain(getter_AddRefs(domain));
nsCOMPtr<nsIPrincipal> newPrincipal;
rv = nsContentUtils::GetSecurityManager()->
GetCodebasePrincipal(uri, getter_AddRefs(newPrincipal));
NS_ENSURE_SUCCESS(rv, rv);
NS_ASSERTION(newPrincipal, "Gotta have a new principal");
if (domain) {
newPrincipal->SetDomain(domain);
}
aDocument->SetPrincipal(newPrincipal);
}
}
return NS_OK;
// If the document principal is a cert principal and is not the same
// as the channel principal, then we don't execute the script.
PRBool equal;
rv = docPrincipal->Equals(channelPrincipal, &equal);
return NS_SUCCEEDED(rv) && equal;
}

View File

@ -181,11 +181,11 @@ public:
void ProcessPendingRequests();
/**
* If needed, downgrade the principal of aDocument based on the
* principal of aChannel.
* Check whether it's OK to execute a script loaded via aChannel in
* aDocument.
*/
static nsresult DowngradePrincipalIfNeeded(nsIDocument* aDocument,
nsIChannel* aChannel);
static PRBool ShouldExecuteScript(nsIDocument* aDocument,
nsIChannel* aChannel);
protected:
/**

View File

@ -3336,18 +3336,15 @@ nsXULDocument::OnStreamComplete(nsIStreamLoader* aLoader,
rv = nsScriptLoader::ConvertToUTF16(channel, string, stringLen,
EmptyString(), this, stringStr);
if (NS_SUCCEEDED(rv)) {
// Downgrade _before_ compiling, since that's when the
// script saves its principal.
rv = nsScriptLoader::DowngradePrincipalIfNeeded(this, channel);
if (NS_SUCCEEDED(rv)) {
rv = scriptProto->Compile(stringStr.get(), stringStr.Length(),
uri, 1, this, mCurrentPrototype);
}
rv = scriptProto->Compile(stringStr.get(), stringStr.Length(),
uri, 1, this, mCurrentPrototype);
}
aStatus = rv;
if (NS_SUCCEEDED(rv)) {
rv = ExecuteScript(scriptProto);
if (nsScriptLoader::ShouldExecuteScript(this, channel)) {
rv = ExecuteScript(scriptProto);
}
// If the XUL cache is enabled, save the script object there in
// case different XUL documents source the same script.
@ -3429,8 +3426,7 @@ nsXULDocument::OnStreamComplete(nsIStreamLoader* aLoader,
// Execute only if we loaded and compiled successfully, then resume
if (NS_SUCCEEDED(aStatus) && scriptProto->mScriptObject.mObject &&
NS_SUCCEEDED(nsScriptLoader::DowngradePrincipalIfNeeded(doc,
channel))) {
nsScriptLoader::ShouldExecuteScript(doc, channel)) {
doc->ExecuteScript(scriptProto);
}
doc->ResumeWalk();