Backed out changeset f4964171a9c0 (bug 994320) and changeset a4655f5da435 (bug 994318) for bustage.

CLOSED TREE
This commit is contained in:
Ryan VanderMeulen 2014-05-20 14:00:26 -04:00
Родитель ad46289006
Коммит 64675d893d
5 изменённых файлов: 13 добавлений и 210 удалений

Просмотреть файл

@ -26,7 +26,6 @@
#include "nsIPrincipal.h"
#include "nsIPropertyBag2.h"
#include "nsIScriptError.h"
#include "nsIWebNavigation.h"
#include "nsIWritablePropertyBag2.h"
#include "nsString.h"
#include "prlog.h"
@ -46,47 +45,6 @@ GetCspContextLog()
#define CSPCONTEXTLOG(args) PR_LOG(GetCspContextLog(), 4, args)
static const uint32_t CSP_CACHE_URI_CUTOFF_SIZE = 512;
/**
* Creates a key for use in the ShouldLoad cache.
* Looks like: <uri>!<nsIContentPolicy::LOAD_TYPE>
*/
nsresult
CreateCacheKey_Internal(nsIURI* aContentLocation,
nsContentPolicyType aContentType,
nsACString& outCacheKey)
{
if (!aContentLocation) {
return NS_ERROR_FAILURE;
}
bool isDataScheme = false;
nsresult rv = aContentLocation->SchemeIs("data", &isDataScheme);
NS_ENSURE_SUCCESS(rv, rv);
outCacheKey.Truncate();
if (aContentType != nsIContentPolicy::TYPE_SCRIPT && isDataScheme) {
// For non-script data: URI, use ("data:", aContentType) as the cache key.
outCacheKey.Append(NS_LITERAL_CSTRING("data:"));
outCacheKey.AppendInt(aContentType);
return NS_OK;
}
nsAutoCString spec;
rv = aContentLocation->GetSpec(spec);
NS_ENSURE_SUCCESS(rv, rv);
// Don't cache for a URI longer than the cutoff size.
if (spec.Length() <= CSP_CACHE_URI_CUTOFF_SIZE) {
outCacheKey.Append(spec);
outCacheKey.Append(NS_LITERAL_CSTRING("!"));
outCacheKey.AppendInt(aContentType);
}
return NS_OK;
}
/* ===== nsIContentSecurityPolicy impl ====== */
NS_IMETHODIMP
@ -116,16 +74,6 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
// * Content Type is not whitelisted (CSP Reports, TYPE_DOCUMENT, etc).
// * Fast Path for Apps
nsAutoCString cacheKey;
rv = CreateCacheKey_Internal(aContentLocation, aContentType, cacheKey);
NS_ENSURE_SUCCESS(rv, rv);
bool isCached = mShouldLoadCache.Get(cacheKey, outDecision);
if (isCached && cacheKey.Length() > 0) {
// this is cached, use the cached value.
return NS_OK;
}
// Default decision, CSP can revise it if there's a policy to enforce
*outDecision = nsIContentPolicy::ACCEPT;
@ -189,11 +137,6 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
// * Console error reporting, bug 994322
}
}
// Done looping, cache any relevant result
if (cacheKey.Length() > 0 && !isPreload) {
mShouldLoadCache.Put(cacheKey, *outDecision);
}
#ifdef PR_LOGGING
{
nsAutoCString spec;
@ -240,7 +183,6 @@ nsCSPContext::~nsCSPContext()
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
delete mPolicies[i];
}
mShouldLoadCache.Clear();
}
NS_IMETHODIMP
@ -273,8 +215,6 @@ nsCSPContext::RemovePolicy(uint32_t aIndex)
return NS_ERROR_ILLEGAL_VALUE;
}
mPolicies.RemoveElementAt(aIndex);
// reset cache since effective policy changes
mShouldLoadCache.Clear();
return NS_OK;
}
@ -297,8 +237,6 @@ nsCSPContext::AppendPolicy(const nsAString& aPolicyString,
nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy(aPolicyString, mSelfURI, aReportOnly, 0);
if (policy) {
mPolicies.AppendElement(policy);
// reset cache since effective policy changes
mShouldLoadCache.Clear();
}
return NS_OK;
}
@ -440,118 +378,11 @@ nsCSPContext::SetRequestContext(nsIURI* aSelfURI,
return NS_OK;
}
/**
* Based on the given docshell, determines if this CSP context allows the
* ancestry.
*
* In order to determine the URI of the parent document (one causing the load
* of this protected document), this function obtains the docShellTreeItem,
* then walks up the hierarchy until it finds a privileged (chrome) tree item.
* Getting the parent's URI looks like this in pseudocode:
*
* nsIDocShell->QI(nsIInterfaceRequestor)
* ->GI(nsIDocShellTreeItem)
* ->QI(nsIInterfaceRequestor)
* ->GI(nsIWebNavigation)
* ->GetCurrentURI();
*
* aDocShell is the docShell for the protected document.
*/
NS_IMETHODIMP
nsCSPContext::PermitsAncestry(nsIDocShell* aDocShell, bool* outPermitsAncestry)
{
nsresult rv;
// Can't check ancestry without a docShell.
if (aDocShell == nullptr) {
return NS_ERROR_FAILURE;
}
// For now, we allows permitsAncestry, this will be fixed in Bug 994320
*outPermitsAncestry = true;
// extract the ancestry as an array
nsCOMArray<nsIURI> ancestorsArray;
nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(aDocShell));
nsCOMPtr<nsIDocShellTreeItem> treeItem(do_GetInterface(ir));
nsCOMPtr<nsIDocShellTreeItem> parentTreeItem;
nsCOMPtr<nsIWebNavigation> webNav;
nsCOMPtr<nsIURI> currentURI;
nsCOMPtr<nsIURI> uriClone;
// iterate through each docShell parent item
while (NS_SUCCEEDED(treeItem->GetParent(getter_AddRefs(parentTreeItem))) &&
parentTreeItem != nullptr) {
ir = do_QueryInterface(parentTreeItem);
NS_ASSERTION(ir, "Could not QI docShellTreeItem to nsIInterfaceRequestor");
webNav = do_GetInterface(ir);
NS_ENSURE_TRUE(webNav, NS_ERROR_FAILURE);
rv = webNav->GetCurrentURI(getter_AddRefs(currentURI));
NS_ENSURE_SUCCESS(rv, rv);
if (currentURI) {
// stop when reaching chrome
bool isChrome = false;
rv = currentURI->SchemeIs("chrome", &isChrome);
NS_ENSURE_SUCCESS(rv, rv);
if (isChrome) { break; }
// delete the userpass from the URI.
rv = currentURI->CloneIgnoringRef(getter_AddRefs(uriClone));
NS_ENSURE_SUCCESS(rv, rv);
rv = uriClone->SetUserPass(EmptyCString());
NS_ENSURE_SUCCESS(rv, rv);
#ifdef PR_LOGGING
{
nsAutoCString spec;
uriClone->GetSpec(spec);
CSPCONTEXTLOG(("nsCSPContext::PermitsAncestry, found ancestor: %s", spec.get()));
}
#endif
ancestorsArray.AppendElement(uriClone);
}
// next ancestor
treeItem = parentTreeItem;
}
nsAutoString violatedDirective;
// Now that we've got the ancestry chain in ancestorsArray, time to check
// them against any CSP.
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
for (uint32_t a = 0; a < ancestorsArray.Length(); a++) {
// TODO(sid) the mapping from frame-ancestors context to TYPE_DOCUMENT is
// forced. while this works for now, we will implement something in
// bug 999656.
#ifdef PR_LOGGING
{
nsAutoCString spec;
ancestorsArray[a]->GetSpec(spec);
CSPCONTEXTLOG(("nsCSPContext::PermitsAncestry, checking ancestor: %s", spec.get()));
}
#endif
if (!mPolicies[i]->permits(nsIContentPolicy::TYPE_DOCUMENT,
ancestorsArray[a],
EmptyString(), // no nonce
violatedDirective)) {
// Policy is violated
nsCOMPtr<nsIObserverService> observerService =
mozilla::services::GetObserverService();
NS_ENSURE_TRUE(observerService, NS_ERROR_NOT_AVAILABLE);
observerService->NotifyObservers(ancestorsArray[a],
CSP_VIOLATION_TOPIC,
violatedDirective.get());
// TODO(sid) generate violation reports and remove NotifyObservers
// call. (in bug 994322)
// TODO(sid) implement logic for report-only (in bug 994322)
*outPermitsAncestry = false;
}
}
}
return NS_OK;
}

Просмотреть файл

@ -7,7 +7,6 @@
#define nsCSPContext_h___
#include "nsCSPUtils.h"
#include "nsDataHashtable.h"
#include "nsIChannel.h"
#include "nsIClassInfo.h"
#include "nsIContentSecurityPolicy.h"
@ -37,9 +36,8 @@ class nsCSPContext : public nsIContentSecurityPolicy
bool* outShouldReportViolations,
bool* outIsAllowed) const;
nsTArray<nsCSPPolicy*> mPolicies;
nsCOMPtr<nsIURI> mSelfURI;
nsDataHashtable<nsCStringHashKey, int16_t> mShouldLoadCache;
nsTArray<nsCSPPolicy*> mPolicies;
nsCOMPtr<nsIURI> mSelfURI;
};
#endif /* nsCSPContext_h___ */

Просмотреть файл

@ -636,8 +636,6 @@ CSP_DirectiveToContentType(enum CSPDirective aDir)
case CSP_MEDIA_SRC: return nsIContentPolicy::TYPE_MEDIA;
case CSP_OBJECT_SRC: return nsIContentPolicy::TYPE_OBJECT;
case CSP_FRAME_SRC: return nsIContentPolicy::TYPE_SUBDOCUMENT;
// TODO(sid): fix this mapping to be more precise (bug 999656)
case CSP_FRAME_ANCESTORS: return nsIContentPolicy::TYPE_DOCUMENT;
// Fall through to error for the following Directives:
case CSP_DEFAULT_SRC:

Просмотреть файл

@ -49,24 +49,22 @@ enum CSPDirective {
CSP_FONT_SRC,
CSP_CONNECT_SRC,
CSP_REPORT_URI,
CSP_FRAME_ANCESTORS,
// CSP_LAST_DIRECTIVE_VALUE always needs to be the last element in the enum
// because we use it to calculate the size for the char* array.
CSP_LAST_DIRECTIVE_VALUE
};
static const char* CSPStrDirectives[] = {
"default-src", // CSP_DEFAULT_SRC = 0
"script-src", // CSP_SCRIPT_SRC
"object-src", // CSP_OBJECT_SRC
"style-src", // CSP_STYLE_SRC
"img-src", // CSP_IMG_SRC
"media-src", // CSP_MEDIA_SRC
"frame-src", // CSP_FRAME_SRC
"font-src", // CSP_FONT_SRC
"connect-src", // CSP_CONNECT_SRC
"report-uri", // CSP_REPORT_URI
"frame-ancestors" // CSP_FRAME_ANCESTORS
"default-src", // CSP_DEFAULT_SRC = 0
"script-src", // CSP_SCRIPT_SRC
"object-src", // CSP_OBJECT_SRC
"style-src", // CSP_STYLE_SRC
"img-src", // CSP_IMG_SRC
"media-src", // CSP_MEDIA_SRC
"frame-src", // CSP_FRAME_SRC
"font-src", // CSP_FONT_SRC
"connect-src", // CSP_CONNECT_SRC
"report-uri", // CSP_REPORT_URI
};
inline const char* CSP_EnumToDirective(enum CSPDirective aDir)

Просмотреть файл

@ -667,28 +667,6 @@ nsresult TestGoodGeneratedPolicies() {
"script-src http://policy-uri" },
{ "img-src 'self'; ",
"img-src http://www.selfuri.com" },
{ "frame-ancestors foo-bar.com",
"frame-ancestors http://foo-bar.com" },
{ "frame-ancestors http://a.com",
"frame-ancestors http://a.com" },
{ "frame-ancestors 'self'",
"frame-ancestors http://www.selfuri.com" },
{ "frame-ancestors http://self.com:88",
"frame-ancestors http://self.com:88" },
{ "frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com",
"frame-ancestors http://a.b.c.d.e.f.g.h.i.j.k.l.x.com" },
{ "frame-ancestors https://self.com:34",
"frame-ancestors https://self.com:34" },
{ "default-src 'none'; frame-ancestors 'self'",
"default-src 'none'; frame-ancestors http://www.selfuri.com" },
{ "frame-ancestors http://self:80",
"frame-ancestors http://self:80" },
{ "frame-ancestors http://self.com/bar",
"frame-ancestors http://self.com" },
{ "default-src 'self'; frame-ancestors 'self'",
"default-src http://www.selfuri.com; frame-ancestors http://www.selfuri.com" },
{ "frame-ancestors http://bar.com/foo.png",
"frame-ancestors http://bar.com" },
};
uint32_t policyCount = sizeof(policies) / sizeof(PolicyTest);