зеркало из https://github.com/mozilla/gecko-dev.git
Bug 951457 - Create C++ CSP Parser and policy classes, part 1 - backend stubs r=sstamm, r=grobinson
This commit is contained in:
Родитель
457633046f
Коммит
e6344ed05a
|
@ -3,6 +3,7 @@
|
|||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "nsISerializable.idl"
|
||||
#include "nsIContentPolicy.idl"
|
||||
|
||||
interface nsIURI;
|
||||
interface nsIChannel;
|
||||
|
@ -16,7 +17,7 @@ interface nsIPrincipal;
|
|||
* one of these per document/principal.
|
||||
*/
|
||||
|
||||
[scriptable, uuid(8b91f829-b1bf-4327-8ece-4000aa823394)]
|
||||
[scriptable, uuid(1ae83090-e1e1-4272-b0c4-0fbd751c1e27)]
|
||||
interface nsIContentSecurityPolicy : nsISerializable
|
||||
{
|
||||
|
||||
|
@ -25,7 +26,7 @@ interface nsIContentSecurityPolicy : nsISerializable
|
|||
* enforce. This is a barrier for the nsDocument so it doesn't load any
|
||||
* sub-content until either it knows that a CSP is ready or will not be used.
|
||||
*/
|
||||
attribute boolean isInitialized;
|
||||
readonly attribute boolean isInitialized;
|
||||
|
||||
/**
|
||||
* Accessor method for a read-only string version of the policy at a given
|
||||
|
@ -37,7 +38,7 @@ interface nsIContentSecurityPolicy : nsISerializable
|
|||
* Returns the number of policies attached to this CSP instance. Useful with
|
||||
* getPolicy().
|
||||
*/
|
||||
attribute long policyCount;
|
||||
readonly attribute unsigned long policyCount;
|
||||
|
||||
/**
|
||||
* Remove a policy associated with this CSP context.
|
||||
|
@ -217,7 +218,7 @@ interface nsIContentSecurityPolicy : nsISerializable
|
|||
* Calls to this may trigger violation reports when queried, so
|
||||
* this value should not be cached.
|
||||
*/
|
||||
short shouldLoad(in unsigned long aContentType,
|
||||
short shouldLoad(in nsContentPolicyType aContentType,
|
||||
in nsIURI aContentLocation,
|
||||
in nsIURI aRequestOrigin,
|
||||
in nsISupports aContext,
|
||||
|
@ -229,11 +230,16 @@ interface nsIContentSecurityPolicy : nsISerializable
|
|||
* document are being processed. Given a bit of information about the request,
|
||||
* decides whether or not the policy is satisfied.
|
||||
*/
|
||||
short shouldProcess(in unsigned long aContentType,
|
||||
short shouldProcess(in nsContentPolicyType aContentType,
|
||||
in nsIURI aContentLocation,
|
||||
in nsIURI aRequestOrigin,
|
||||
in nsISupports aContext,
|
||||
in ACString aMimeType,
|
||||
in nsISupports aExtra);
|
||||
|
||||
%{ C++
|
||||
// nsIObserver topic to fire when the policy encounters a violation.
|
||||
#define CSP_VIOLATION_TOPIC "csp-on-violate-policy"
|
||||
%}
|
||||
|
||||
};
|
||||
|
|
|
@ -110,6 +110,7 @@ UNIFIED_SOURCES += [
|
|||
'nsContentSink.cpp',
|
||||
'nsCopySupport.cpp',
|
||||
'nsCrossSiteListenerProxy.cpp',
|
||||
'nsCSPContext.cpp',
|
||||
'nsCSPParser.cpp',
|
||||
'nsCSPService.cpp',
|
||||
'nsCSPUtils.cpp',
|
||||
|
|
|
@ -0,0 +1,204 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#include "mozilla/Preferences.h"
|
||||
#include "nsAsyncRedirectVerifyHelper.h"
|
||||
#include "nsChannelProperties.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsContentPolicyUtils.h"
|
||||
#include "nsContentUtils.h"
|
||||
#include "nsCSPContext.h"
|
||||
#include "nsCSPParser.h"
|
||||
#include "nsCSPService.h"
|
||||
#include "nsError.h"
|
||||
#include "nsIAsyncVerifyRedirectCallback.h"
|
||||
#include "nsIChannelEventSink.h"
|
||||
#include "nsIChannelPolicy.h"
|
||||
#include "nsIDocShell.h"
|
||||
#include "nsIDocShellTreeItem.h"
|
||||
#include "nsIHttpChannel.h"
|
||||
#include "nsIInterfaceRequestorUtils.h"
|
||||
#include "nsIObserver.h"
|
||||
#include "nsIObserverService.h"
|
||||
#include "nsIPrincipal.h"
|
||||
#include "nsIPropertyBag2.h"
|
||||
#include "nsIScriptError.h"
|
||||
#include "nsIWritablePropertyBag2.h"
|
||||
#include "nsString.h"
|
||||
#include "prlog.h"
|
||||
|
||||
using namespace mozilla;
|
||||
|
||||
/* ===== nsIContentSecurityPolicy impl ====== */
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
|
||||
nsIURI* aContentLocation,
|
||||
nsIURI* aRequestOrigin,
|
||||
nsISupports* aRequestContext,
|
||||
const nsACString& aMimeTypeGuess,
|
||||
nsISupports* aExtra,
|
||||
int16_t* outDecision)
|
||||
{
|
||||
*outDecision = nsIContentPolicy::ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::ShouldProcess(nsContentPolicyType aContentType,
|
||||
nsIURI* aContentLocation,
|
||||
nsIURI* aRequestOrigin,
|
||||
nsISupports* aRequestContext,
|
||||
const nsACString& aMimeType,
|
||||
nsISupports* aExtra,
|
||||
int16_t* outDecision)
|
||||
{
|
||||
*outDecision = nsIContentPolicy::ACCEPT;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* ===== nsISupports implementation ========== */
|
||||
|
||||
NS_IMPL_ISUPPORTS(nsCSPContext,
|
||||
nsIContentSecurityPolicy,
|
||||
nsISerializable)
|
||||
|
||||
nsCSPContext::nsCSPContext()
|
||||
{
|
||||
}
|
||||
|
||||
nsCSPContext::~nsCSPContext()
|
||||
{
|
||||
for (uint32_t i = 0; i < mPolicies.Length(); i++) {
|
||||
delete mPolicies[i];
|
||||
}
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetIsInitialized(bool *outIsInitialized)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetPolicy(uint32_t aIndex, nsAString& outStr)
|
||||
{
|
||||
if (aIndex >= mPolicies.Length()) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
mPolicies[aIndex]->toString(outStr);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetPolicyCount(uint32_t *outPolicyCount)
|
||||
{
|
||||
*outPolicyCount = mPolicies.Length();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::RemovePolicy(uint32_t aIndex)
|
||||
{
|
||||
if (aIndex >= mPolicies.Length()) {
|
||||
return NS_ERROR_ILLEGAL_VALUE;
|
||||
}
|
||||
mPolicies.RemoveElementAt(aIndex);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::AppendPolicy(const nsAString& aPolicyString,
|
||||
nsIURI* aSelfURI,
|
||||
bool aReportOnly,
|
||||
bool aSpecCompliant)
|
||||
{
|
||||
NS_ASSERTION(aSelfURI, "aSelfURI required for AppendPolicy");
|
||||
nsCSPPolicy* policy = nsCSPParser::parseContentSecurityPolicy(aPolicyString, aSelfURI, aReportOnly, 0);
|
||||
if (policy) {
|
||||
mPolicies.AppendElement(policy);
|
||||
}
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetAllowsInlineScript(bool* outShouldReportViolations,
|
||||
bool* outAllowsInlineScript)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetAllowsEval(bool* outShouldReportViolations,
|
||||
bool* outAllowsEval)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetAllowsInlineStyle(bool* outShouldReportViolations,
|
||||
bool* outAllowsInlineStyle)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetAllowsNonce(const nsAString& aNonce,
|
||||
uint32_t aContentType,
|
||||
bool* outShouldReportViolation,
|
||||
bool* outAllowsNonce)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::GetAllowsHash(const nsAString& aContent,
|
||||
uint16_t aContentType,
|
||||
bool* outShouldReportViolation,
|
||||
bool* outAllowsHash)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::LogViolationDetails(uint16_t aViolationType,
|
||||
const nsAString& aSourceFile,
|
||||
const nsAString& aScriptSample,
|
||||
int32_t aLineNum,
|
||||
const nsAString& aNonce,
|
||||
const nsAString& aContent)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::SetRequestContext(nsIURI* aSelfURI,
|
||||
nsIURI* aReferrer,
|
||||
nsIPrincipal* aDocumentPrincipal,
|
||||
nsIChannel* aChannel)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::PermitsAncestry(nsIDocShell* aDocShell, bool* outPermitsAncestry)
|
||||
{
|
||||
// For now, we allows permitsAncestry, this will be fixed in Bug 994320
|
||||
*outPermitsAncestry = true;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* ===== nsISerializable implementation ====== */
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::Read(nsIObjectInputStream* aStream)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
nsCSPContext::Write(nsIObjectOutputStream* aStream)
|
||||
{
|
||||
return NS_ERROR_NOT_IMPLEMENTED;
|
||||
}
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsCSPContext_h___
|
||||
#define nsCSPContext_h___
|
||||
|
||||
#include "nsCSPUtils.h"
|
||||
#include "nsIChannel.h"
|
||||
#include "nsIContentSecurityPolicy.h"
|
||||
#include "nsISerializable.h"
|
||||
#include "nsXPCOM.h"
|
||||
|
||||
class nsIObjectInputStream;
|
||||
class nsIObjectOutputStream;
|
||||
|
||||
#define NS_CSPCONTEXT_CONTRACTID "@mozilla.org/cspcontext;1"
|
||||
// 09d9ed1a-e5d4-4004-bfe0-27ceb923d9ac
|
||||
#define NS_CSPCONTEXT_CID \
|
||||
{ 0x09d9ed1a, 0xe5d4, 0x4004, \
|
||||
{ 0xbf, 0xe0, 0x27, 0xce, 0xb9, 0x23, 0xd9, 0xac } }
|
||||
|
||||
class nsCSPContext : public nsIContentSecurityPolicy
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSICONTENTSECURITYPOLICY
|
||||
NS_DECL_NSISERIALIZABLE
|
||||
|
||||
nsCSPContext();
|
||||
virtual ~nsCSPContext();
|
||||
|
||||
private:
|
||||
nsTArray<nsCSPPolicy*> mPolicies;
|
||||
nsCOMPtr<nsIURI> mSelfURI;
|
||||
};
|
||||
|
||||
#endif /* nsCSPContext_h___ */
|
|
@ -28,6 +28,7 @@ using namespace mozilla;
|
|||
|
||||
/* Keeps track of whether or not CSP is enabled */
|
||||
bool CSPService::sCSPEnabled = true;
|
||||
bool CSPService::sNewBackendEnabled = true;
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
static PRLogModuleInfo* gCspPRLog;
|
||||
|
@ -36,6 +37,7 @@ static PRLogModuleInfo* gCspPRLog;
|
|||
CSPService::CSPService()
|
||||
{
|
||||
Preferences::AddBoolVarCache(&sCSPEnabled, "security.csp.enable");
|
||||
Preferences::AddBoolVarCache(&sNewBackendEnabled, "security.csp.newbackend.enable");
|
||||
|
||||
#ifdef PR_LOGGING
|
||||
if (!gCspPRLog)
|
||||
|
@ -167,10 +169,10 @@ CSPService::ShouldLoad(uint32_t aContentType,
|
|||
if (csp) {
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
int numPolicies = 0;
|
||||
uint32_t numPolicies = 0;
|
||||
nsresult rv = csp->GetPolicyCount(&numPolicies);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
for (int i=0; i<numPolicies; i++) {
|
||||
for (uint32_t i=0; i<numPolicies; i++) {
|
||||
nsAutoString policy;
|
||||
csp->GetPolicy(i, policy);
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
|
@ -235,10 +237,10 @@ CSPService::ShouldProcess(uint32_t aContentType,
|
|||
if (csp) {
|
||||
#ifdef PR_LOGGING
|
||||
{
|
||||
int numPolicies = 0;
|
||||
uint32_t numPolicies = 0;
|
||||
nsresult rv = csp->GetPolicyCount(&numPolicies);
|
||||
if (NS_SUCCEEDED(rv)) {
|
||||
for (int i=0; i<numPolicies; i++) {
|
||||
for (uint32_t i=0; i<numPolicies; i++) {
|
||||
nsAutoString policy;
|
||||
csp->GetPolicy(i, policy);
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG,
|
||||
|
|
|
@ -3,6 +3,9 @@
|
|||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
#ifndef nsCSPService_h___
|
||||
#define nsCSPService_h___
|
||||
|
||||
#include "nsXPCOM.h"
|
||||
#include "nsIContentPolicy.h"
|
||||
#include "nsIChannel.h"
|
||||
|
@ -23,7 +26,9 @@ public:
|
|||
CSPService();
|
||||
virtual ~CSPService();
|
||||
static bool sCSPEnabled;
|
||||
static bool sNewBackendEnabled;
|
||||
private:
|
||||
// Maps origins to app status.
|
||||
nsDataHashtable<nsCStringHashKey, uint16_t> mAppStatusCache;
|
||||
};
|
||||
#endif /* nsCSPService_h___ */
|
||||
|
|
|
@ -2802,8 +2802,26 @@ nsDocument::InitCSP(nsIChannel* aChannel)
|
|||
}
|
||||
}
|
||||
|
||||
// create new CSP object
|
||||
csp = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
|
||||
// Create new CSP object - if we're using the new CSP implementation and backend,
|
||||
// use the new contract ID (same interface, but use C++ implementation).
|
||||
if (CSPService::sNewBackendEnabled) {
|
||||
if (oldHeaderIsPresent && !newHeaderIsPresent) {
|
||||
// New CSP implementation doesn't support old header! ABORT CSP INIT!
|
||||
// (Not a problem if newHeaderIsPresent because the old header will be
|
||||
// ignored). This check will get removed when x- header support is
|
||||
// removed (see bug 949533)
|
||||
#ifdef PR_LOGGING
|
||||
PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("%s %s %s",
|
||||
"This document has an old, x-content-security-policy",
|
||||
"header and the new CSP implementation doesn't support the non-standard",
|
||||
"CSP. Skipping CSP initialization."));
|
||||
#endif
|
||||
return NS_OK;
|
||||
}
|
||||
csp = do_CreateInstance("@mozilla.org/cspcontext;1", &rv);
|
||||
} else {
|
||||
csp = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv);
|
||||
}
|
||||
|
||||
if (NS_FAILED(rv)) {
|
||||
#ifdef PR_LOGGING
|
||||
|
|
|
@ -215,6 +215,7 @@ static void Shutdown();
|
|||
#include "mozilla/dom/GamepadService.h"
|
||||
#endif
|
||||
#include "nsCSPService.h"
|
||||
#include "nsCSPContext.h"
|
||||
#include "nsISmsService.h"
|
||||
#include "nsIMmsService.h"
|
||||
#include "nsIMobileMessageService.h"
|
||||
|
@ -588,6 +589,7 @@ NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(AudioChannelService, AudioChannelServic
|
|||
NS_GENERIC_FACTORY_CONSTRUCTOR(FakeSpeechRecognitionService)
|
||||
#endif
|
||||
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsCSPContext)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(CSPService)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR(nsMixedContentBlocker)
|
||||
|
||||
|
@ -732,6 +734,7 @@ NS_DEFINE_NAMED_CID(NS_GEOLOCATION_CID);
|
|||
NS_DEFINE_NAMED_CID(NS_AUDIOCHANNEL_SERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_FOCUSMANAGER_CID);
|
||||
NS_DEFINE_NAMED_CID(CSPSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_CSPCONTEXT_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_MIXEDCONTENTBLOCKER_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_EVENTLISTENERSERVICE_CID);
|
||||
NS_DEFINE_NAMED_CID(NS_GLOBALMESSAGEMANAGER_CID);
|
||||
|
@ -1021,6 +1024,7 @@ static const mozilla::Module::CIDEntry kLayoutCIDs[] = {
|
|||
{ &kNS_SYNTHVOICEREGISTRY_CID, true, nullptr, nsSynthVoiceRegistryConstructor },
|
||||
#endif
|
||||
{ &kCSPSERVICE_CID, false, nullptr, CSPServiceConstructor },
|
||||
{ &kNS_CSPCONTEXT_CID, false, nullptr, nsCSPContextConstructor },
|
||||
{ &kNS_MIXEDCONTENTBLOCKER_CID, false, nullptr, nsMixedContentBlockerConstructor },
|
||||
{ &kNS_EVENTLISTENERSERVICE_CID, false, nullptr, CreateEventListenerService },
|
||||
{ &kNS_GLOBALMESSAGEMANAGER_CID, false, nullptr, CreateGlobalMessageManager },
|
||||
|
@ -1174,6 +1178,7 @@ static const mozilla::Module::ContractIDEntry kLayoutContracts[] = {
|
|||
{ NS_SYNTHVOICEREGISTRY_CONTRACTID, &kNS_SYNTHVOICEREGISTRY_CID },
|
||||
#endif
|
||||
{ CSPSERVICE_CONTRACTID, &kCSPSERVICE_CID },
|
||||
{ NS_CSPCONTEXT_CONTRACTID, &kNS_CSPCONTEXT_CID },
|
||||
{ NS_MIXEDCONTENTBLOCKER_CONTRACTID, &kNS_MIXEDCONTENTBLOCKER_CID },
|
||||
{ NS_EVENTLISTENERSERVICE_CONTRACTID, &kNS_EVENTLISTENERSERVICE_CID },
|
||||
{ NS_GLOBALMESSAGEMANAGER_CONTRACTID, &kNS_GLOBALMESSAGEMANAGER_CID },
|
||||
|
|
|
@ -1555,6 +1555,7 @@ pref("security.notification_enable_delay", 500);
|
|||
pref("security.csp.enable", true);
|
||||
pref("security.csp.debug", false);
|
||||
pref("security.csp.experimentalEnabled", false);
|
||||
pref("security.csp.newbackend.enable", false);
|
||||
|
||||
// Mixed content blocking
|
||||
pref("security.mixed_content.block_active_content", false);
|
||||
|
|
Загрузка…
Ссылка в новой задаче