Bug 495337 - Make sessionStorage use principals instead of string domains, r=bz+bclary

This commit is contained in:
Honza Bambas 2012-02-23 18:41:25 +01:00
parent e88d6a612d
commit e9c33fe76e
13 changed files with 77 additions and 70 deletions

View File

@ -52,7 +52,7 @@ interface nsIContentSecurityPolicy;
[ptr] native JSContext(JSContext);
[ptr] native JSPrincipals(JSPrincipals);
[scriptable, uuid(B406A2DB-E547-4C95-B8E2-AD09ECB54CE0)]
[scriptable, uuid(1f83b0e0-6b63-4bdc-a50a-b9afe256bd25)]
interface nsIPrincipal : nsISerializable
{
/**
@ -206,6 +206,12 @@ interface nsIPrincipal : nsISerializable
*/
boolean subsumes(in nsIPrincipal other);
/**
* Same as the previous method, subsumes(), but for codebase principals
* ignores changes to document.domain.
*/
boolean subsumesIgnoringDomain(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

View File

@ -336,6 +336,12 @@ nsNullPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
return NS_OK;
}
NS_IMETHODIMP
nsNullPrincipal::SubsumesIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
{
return Subsumes(aOther, aResult);
}
NS_IMETHODIMP
nsNullPrincipal::CheckMayLoad(nsIURI* aURI, bool aReport)
{

View File

@ -377,6 +377,12 @@ nsPrincipal::Subsumes(nsIPrincipal *aOther, bool *aResult)
return Equals(aOther, aResult);
}
NS_IMETHODIMP
nsPrincipal::SubsumesIgnoringDomain(nsIPrincipal *aOther, bool *aResult)
{
return EqualsIgnoringDomain(aOther, aResult);
}
static bool
URIIsLocalFile(nsIURI *aURI)
{

View File

@ -120,6 +120,13 @@ nsSystemPrincipal::EqualsIgnoringDomain(nsIPrincipal *other, bool *result)
NS_IMETHODIMP
nsSystemPrincipal::Subsumes(nsIPrincipal *other, bool *result)
{
*result = PR_TRUE;
return NS_OK;
}
NS_IMETHODIMP
nsSystemPrincipal::SubsumesIgnoringDomain(nsIPrincipal *other, bool *result)
{
*result = true;
return NS_OK;

View File

@ -2310,34 +2310,6 @@ nsDocShell::HistoryTransactionRemoved(PRInt32 aIndex)
return NS_OK;
}
static
nsresult
GetPrincipalDomain(nsIPrincipal* aPrincipal, nsACString& aDomain)
{
aDomain.Truncate();
nsCOMPtr<nsIURI> codebaseURI;
nsresult rv = aPrincipal->GetDomain(getter_AddRefs(codebaseURI));
NS_ENSURE_SUCCESS(rv, rv);
if (!codebaseURI) {
rv = aPrincipal->GetURI(getter_AddRefs(codebaseURI));
NS_ENSURE_SUCCESS(rv, rv);
}
if (!codebaseURI)
return NS_OK;
nsCOMPtr<nsIURI> innerURI = NS_GetInnermostURI(codebaseURI);
NS_ASSERTION(innerURI, "Failed to get innermost URI");
NS_ENSURE_SUCCESS(rv, rv);
rv = innerURI->GetAsciiHost(aDomain);
if (NS_FAILED(rv))
return rv;
return NS_OK;
}
NS_IMETHODIMP
nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
const nsAString& aDocumentURI,
@ -2367,15 +2339,15 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
aCreate,
aStorage);
nsCAutoString currentDomain;
rv = GetPrincipalDomain(aPrincipal, currentDomain);
nsXPIDLCString origin;
rv = aPrincipal->GetOrigin(getter_Copies(origin));
if (NS_FAILED(rv))
return rv;
if (currentDomain.IsEmpty())
if (origin.IsEmpty())
return NS_OK;
if (!mStorages.Get(currentDomain, aStorage) && aCreate) {
if (!mStorages.Get(origin, aStorage) && aCreate) {
nsCOMPtr<nsIDOMStorage> newstorage =
do_CreateInstance("@mozilla.org/dom/storage;2");
if (!newstorage)
@ -2384,11 +2356,12 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
nsCOMPtr<nsPIDOMStorage> pistorage = do_QueryInterface(newstorage);
if (!pistorage)
return NS_ERROR_FAILURE;
rv = pistorage->InitAsSessionStorage(aPrincipal, aDocumentURI);
if (NS_FAILED(rv))
return rv;
if (!mStorages.Put(currentDomain, newstorage))
if (!mStorages.Put(origin, newstorage))
return NS_ERROR_OUT_OF_MEMORY;
newstorage.swap(*aStorage);
@ -2399,22 +2372,32 @@ nsDocShell::GetSessionStorageForPrincipal(nsIPrincipal* aPrincipal,
#endif
}
else if (*aStorage) {
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(*aStorage);
if (piStorage) {
bool canAccess = piStorage->CanAccess(aPrincipal);
NS_ASSERTION(canAccess,
"GetSessionStorageForPrincipal got a storage "
"that could not be accessed!");
if (!canAccess) {
NS_RELEASE(*aStorage);
return NS_ERROR_DOM_SECURITY_ERR;
}
}
nsCOMPtr<nsPIDOMStorage> piStorage = do_QueryInterface(*aStorage);
if (piStorage) {
nsCOMPtr<nsIPrincipal> storagePrincipal = piStorage->Principal();
// The origin string used to map items in the hash table is
// an implicit security check. That check is double-confirmed
// by checking the principal a storage was demanded for
// really is the principal for which that storage was originally
// created. Originally, the check was hidden in the CanAccess
// method but it's implementation has changed.
bool equals;
nsresult rv = aPrincipal->EqualsIgnoringDomain(storagePrincipal, &equals);
NS_ASSERTION(NS_SUCCEEDED(rv) && equals,
"GetSessionStorageForPrincipal got a storage "
"that could not be accessed!");
if (NS_FAILED(rv) || !equals) {
NS_RELEASE(*aStorage);
return NS_ERROR_DOM_SECURITY_ERR;
}
}
#if defined(PR_LOGGING) && defined(DEBUG)
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
("nsDocShell[%p]: returns existing sessionStorage %p",
this, *aStorage));
PR_LOG(gDocShellLog, PR_LOG_DEBUG,
("nsDocShell[%p]: returns existing sessionStorage %p",
this, *aStorage));
#endif
}
@ -2499,16 +2482,16 @@ nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
if (topItem) {
nsCOMPtr<nsIDocShell> topDocShell = do_QueryInterface(topItem);
if (topDocShell == this) {
nsCAutoString currentDomain;
rv = GetPrincipalDomain(aPrincipal, currentDomain);
nsXPIDLCString origin;
rv = aPrincipal->GetOrigin(getter_Copies(origin));
if (NS_FAILED(rv))
return rv;
if (currentDomain.IsEmpty())
if (origin.IsEmpty())
return NS_ERROR_FAILURE;
// Do not replace an existing session storage.
if (mStorages.GetWeak(currentDomain))
if (mStorages.GetWeak(origin))
return NS_ERROR_NOT_AVAILABLE;
#if defined(PR_LOGGING) && defined(DEBUG)
@ -2516,7 +2499,7 @@ nsDocShell::AddSessionStorage(nsIPrincipal* aPrincipal,
("nsDocShell[%p]: was added a sessionStorage %p",
this, aStorage));
#endif
if (!mStorages.Put(currentDomain, aStorage))
if (!mStorages.Put(origin, aStorage))
return NS_ERROR_OUT_OF_MEMORY;
}
else {

View File

@ -1848,8 +1848,7 @@ nsDOMStorage2::InitAsSessionStorage(nsIPrincipal *aPrincipal, const nsSubstring
if (!mStorage)
return NS_ERROR_OUT_OF_MEMORY;
// Leave security checks only for domain (nsDOMStorage implementation)
mStorage->mSecurityChecker = mStorage;
mStorage->mSecurityChecker = this;
mPrincipal = aPrincipal;
mDocumentURI = aDocumentURI;
@ -1949,7 +1948,7 @@ nsDOMStorage2::CanAccess(nsIPrincipal *aPrincipal)
// Allow more powerful principals (e.g. system) to access the storage
bool subsumes;
nsresult rv = aPrincipal->Subsumes(mPrincipal, &subsumes);
nsresult rv = aPrincipal->SubsumesIgnoringDomain(mPrincipal, &subsumes);
if (NS_FAILED(rv))
return false;

View File

@ -16,7 +16,7 @@ function startTest()
sessionStorage;
}
catch (e) {
is(e.result, 2152923145,
is(e.result, Components.results.NS_ERROR_NOT_AVAILABLE,
"Testing that we get the expected exception.");
exceptionCaught = true;
}

View File

@ -18,7 +18,7 @@ script 10.1.5-4.js
script 10.1.8-2.js
script 10.1.8-3.js
script 10.2.1.js
skip-if(!xulRuntime.shell) script 10.2.2-1.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR Line 91
skip-if(!xulRuntime.shell) script 10.2.2-2.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR Line 177
skip-if(Android) script 10.2.2-1.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script 10.2.2-2.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script 10.2.3-1.js
script 10.2.3-2.js

View File

@ -7,7 +7,7 @@ script dowhile-005.js
script dowhile-006.js
script dowhile-007.js
script forin-001.js
fails-if(!xulRuntime.shell) script forin-002.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 112
skip-if(Android) script forin-002.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script if-001.js
script label-001.js
script label-002.js

View File

@ -3,7 +3,7 @@ script 11.1.4.js
script array-001.js
random script regress-101964.js # bogus perf test (bug 467263)
script regress-107138.js
fails-if(!xulRuntime.shell) script regress-108440.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 74
skip-if(Android) script regress-108440.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script regress-154338.js
skip-if(xulRuntime.XPCOMABI.match(/x86_64/)||Android) script regress-157652.js # No test results
script regress-178722.js

View File

@ -3,15 +3,15 @@ script regress-312385-01.js
script regress-352392.js
script regress-385393-08.js
script regress-414098.js
fails-if(!xulRuntime.shell) script regress-455464-01.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 1
fails-if(!xulRuntime.shell) script regress-455464-02.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 49
fails-if(!xulRuntime.shell) script regress-455464-03.js # bug - NS_ERROR_DOM_NOT_SUPPORTED_ERR line 1
fails-if(!xulRuntime.shell&&!isDebugBuild) skip-if((!xulRuntime.shell&&isDebugBuild)||Android) script regress-455464-04.js # bug xxx - hangs reftests in debug, ### bug xxx - NS_ERROR_DOM_NOT_SUPPORTED_ERR in opt
skip-if(Android) script regress-455464-01.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script regress-455464-02.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script regress-455464-03.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script regress-455464-04.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(!xulRuntime.shell||Android) slow script regress-456826.js # bug 504632
script regress-457521.js
script regress-465443.js
script regress-470310.js
script regress-472508.js
fails-if(!xulRuntime.shell) script regress-475144.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
skip-if(Android) script regress-475144.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script regress-479567.js
script regress-565521.js

View File

@ -51,8 +51,8 @@ script regress-392308.js
script regress-396326.js
script regress-429266.js
script regress-453955.js
fails-if(!xulRuntime.shell) script regress-455982-01.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
fails-if(!xulRuntime.shell) script regress-455982-02.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
skip-if(Android) script regress-455982-01.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(Android) script regress-455982-02.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
skip-if(!xulRuntime.shell||xulRuntime.shell&&xulRuntime.XPCOMABI.match(/x86_64/)) slow script regress-458679.js
script regress-469234.js
script regress-469405-01.js

View File

@ -20,7 +20,7 @@ script regress-422269.js
skip script regress-445818.js
skip script regress-446169-01.js
skip script regress-446169-02.js
fails-if(!xulRuntime.shell) script regress-452476.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
skip-if(Android) script regress-452476.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script regress-452913.js
script regress-454744.js
script regress-455973.js
@ -34,7 +34,7 @@ script regress-473040.js
skip script regress-475971.js
skip-if(!xulRuntime.shell) slow script regress-476414-01.js
skip-if(!xulRuntime.shell) slow script regress-476414-02.js
fails-if(!xulRuntime.shell) script regress-476427.js # NS_ERROR_DOM_NOT_SUPPORTED_ERR
skip-if(Android) script regress-476427.js # bug - nsIDOMWindow.crypto throws NS_ERROR_NOT_IMPLEMENTED on Android
script regress-476653.js
skip-if(Android) script regress-476869.js
script regress-476871-02.js