Bug 1476592 - Remove the cache from nsCSPContext - part 2 - sendViolationReports parameter, r=ckerschb, r=aosmond

This commit is contained in:
Andrea Marchesini 2018-08-01 06:35:24 +02:00
Родитель 277949ed10
Коммит 44ce53c72e
16 изменённых файлов: 79 добавлений и 32 удалений

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

@ -304,7 +304,8 @@ interface nsIContentSecurityPolicy : nsISerializable
in nsIURI aRequestOrigin,
in nsISupports aContext,
in ACString aMimeTypeGuess,
in nsIURI aOriginalURIIfRedirect);
in nsIURI aOriginalURIIfRedirect,
in bool aSendViolationReports);
%{ C++
// nsIObserver topic to fire when the policy encounters a violation.

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

@ -123,6 +123,7 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
nsISupports* aRequestContext,
const nsACString& aMimeTypeGuess,
nsIURI* aOriginalURIIfRedirect,
bool aSendViolationReports,
int16_t* outDecision)
{
if (CSPCONTEXTLOGENABLED()) {
@ -182,7 +183,7 @@ nsCSPContext::ShouldLoad(nsContentPolicyType aContentType,
nonce,
isPreload,
false, // allow fallback to default-src
true, // send violation reports
aSendViolationReports,
true, // send blocked URI in violation reports
parserCreated);

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

@ -188,6 +188,7 @@ CSPService::ShouldLoad(nsIURI *aContentLocation,
requestContext,
aMimeTypeGuess,
nullptr, // no redirect, aOriginal URL is null.
aLoadInfo->GetSendCSPViolationEvents(),
aDecision);
NS_ENSURE_SUCCESS(rv, rv);
@ -212,6 +213,7 @@ CSPService::ShouldLoad(nsIURI *aContentLocation,
requestContext,
aMimeTypeGuess,
nullptr, // no redirect, aOriginal URL is null.
aLoadInfo->GetSendCSPViolationEvents(),
aDecision);
NS_ENSURE_SUCCESS(rv, rv);
}
@ -324,6 +326,7 @@ CSPService::AsyncOnChannelRedirect(nsIChannel *oldChannel,
requestContext, // nsISupports
EmptyCString(), // ACString - MIME guess
originalUri, // Original nsIURI
true, // aSendViolationReports
&aDecision);
// if the preload policy already denied the load, then there
@ -348,6 +351,7 @@ CSPService::AsyncOnChannelRedirect(nsIChannel *oldChannel,
requestContext, // nsISupports
EmptyCString(), // ACString - MIME guess
originalUri, // Original nsIURI
true, // aSendViolationReports
&aDecision);
}

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

@ -152,7 +152,7 @@ function run_test() {
// shouldLoad creates and sends out the report here.
csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT,
NetUtil.newURI("http://blocked.test/foo.js"),
null, null, null, null);
null, null, null, null, true);
});
// test that inline script violations cause a report in report-only policy
@ -202,7 +202,7 @@ function run_test() {
// shouldLoad creates and sends out the report here.
csp.shouldLoad(Ci.nsIContentPolicy.TYPE_IMAGE,
NetUtil.newURI("data:image/png;base64," + base64data),
null, null, null, null);
null, null, null, null, true);
});
// test that only the uri's scheme is reported for globally unique identifiers
@ -211,7 +211,7 @@ function run_test() {
// shouldLoad creates and sends out the report here.
csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SUBDOCUMENT,
NetUtil.newURI("intent://mymaps.com/maps?um=1&ie=UTF-8&fb=1&sll"),
null, null, null, null);
null, null, null, null, true);
});
// test fragment removal
@ -222,7 +222,7 @@ function run_test() {
// shouldLoad creates and sends out the report here.
csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT,
NetUtil.newURI(selfSpec + "#bar"),
null, null, null, null);
null, null, null, null, true);
});
// test scheme of ftp:
@ -231,6 +231,6 @@ function run_test() {
// shouldLoad creates and sends out the report here.
csp.shouldLoad(Ci.nsIContentPolicy.TYPE_SCRIPT,
NetUtil.newURI("ftp://blocked.test/profile.png"),
null, null, null, null);
null, null, null, null, true);
});
}

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

@ -616,7 +616,8 @@ static bool
ShouldLoadCachedImage(imgRequest* aImgRequest,
nsISupports* aLoadingContext,
nsIPrincipal* aTriggeringPrincipal,
nsContentPolicyType aPolicyType)
nsContentPolicyType aPolicyType,
bool aSendCSPViolationReports)
{
/* Call content policies on cached images - Bug 1082837
* Cached images are keyed off of the first uri in a redirect chain.
@ -650,6 +651,8 @@ ShouldLoadCachedImage(imgRequest* aImgRequest,
nsILoadInfo::SEC_ONLY_FOR_EXPLICIT_CONTENTSEC_CHECK,
aPolicyType);
secCheckLoadInfo->SetSendCSPViolationEvents(aSendCSPViolationReports);
int16_t decision = nsIContentPolicy::REJECT_REQUEST;
rv = NS_CheckContentLoadPolicy(contentLocation,
secCheckLoadInfo,
@ -746,7 +749,8 @@ ValidateSecurityInfo(imgRequest* request, bool forcePrincipalCheck,
}
// Content Policy Check on Cached Images
return ShouldLoadCachedImage(request, aCX, triggeringPrincipal, aPolicyType);
return ShouldLoadCachedImage(request, aCX, triggeringPrincipal, aPolicyType,
/* aSendCSPViolationReports */ false);
}
static nsresult
@ -1797,7 +1801,8 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request,
nsContentPolicyType aLoadPolicyType,
imgRequestProxy** aProxyRequest,
nsIPrincipal* aTriggeringPrincipal,
int32_t aCORSMode)
int32_t aCORSMode,
bool* aNewChannelCreated)
{
// now we need to insert a new channel request object inbetween the real
// request and the proxy that basically delays loading the image until it
@ -1853,6 +1858,10 @@ imgLoader::ValidateRequestWithNewChannel(imgRequest* request,
return false;
}
if (aNewChannelCreated) {
*aNewChannelCreated = true;
}
RefPtr<imgRequestProxy> req;
rv = CreateNewProxyForRequest(request, aLoadGroup, aLoadingDocument,
aObserver, aLoadFlags, getter_AddRefs(req));
@ -1917,6 +1926,7 @@ imgLoader::ValidateEntry(imgCacheEntry* aEntry,
nsLoadFlags aLoadFlags,
nsContentPolicyType aLoadPolicyType,
bool aCanMakeNewChannel,
bool* aNewChannelCreated,
imgRequestProxy** aProxyRequest,
nsIPrincipal* aTriggeringPrincipal,
int32_t aCORSMode)
@ -2036,7 +2046,7 @@ imgLoader::ValidateEntry(imgCacheEntry* aEntry,
aCX, aLoadingDocument,
aLoadFlags, aLoadPolicyType,
aProxyRequest, aTriggeringPrincipal,
aCORSMode);
aCORSMode, aNewChannelCreated);
}
return !validateRequest;
@ -2341,10 +2351,12 @@ imgLoader::LoadImage(nsIURI* aURI,
imgCacheTable& cache = GetCache(key);
if (cache.Get(key, getter_AddRefs(entry)) && entry) {
bool newChannelCreated = false;
if (ValidateEntry(entry, aURI, aInitialDocumentURI, aReferrerURI,
aReferrerPolicy, aLoadGroup, aObserver, aLoadingDocument,
aLoadingDocument, requestFlags, aContentPolicyType, true,
_retval, aTriggeringPrincipal, corsmode)) {
&newChannelCreated, _retval, aTriggeringPrincipal,
corsmode)) {
request = entry->GetRequest();
// If this entry has no proxies, its request has no reference to the
@ -2363,6 +2375,18 @@ imgLoader::LoadImage(nsIURI* aURI,
entry->Touch();
if (!newChannelCreated) {
// This is ugly but it's needed to report CSP violations. We have 3
// scenarios:
// - we don't have cache. We are not in this if() stmt. A new channel is
// created and that triggers the CSP checks.
// - We have a cache entry and this is blocked by CSP directives.
DebugOnly<bool> shouldLoad =
ShouldLoadCachedImage(request, aLoadingDocument, aTriggeringPrincipal,
aContentPolicyType,
/* aSendCSPViolationReports */ true);
MOZ_ASSERT(shouldLoad);
}
} else {
// We can't use this entry. We'll try to load it off the network, and if
// successful, overwrite the old entry in the cache with a new one.
@ -2613,7 +2637,7 @@ imgLoader::LoadImageWithChannel(nsIChannel* channel,
if (ValidateEntry(entry, uri, nullptr, nullptr, RP_Unset,
nullptr, aObserver, aCX, doc, requestFlags,
policyType, false, nullptr,
policyType, false, nullptr, nullptr,
nullptr, imgIRequest::CORS_NONE)) {
request = entry->GetRequest();
} else {

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

@ -413,6 +413,7 @@ private: // methods
nsLoadFlags aLoadFlags,
nsContentPolicyType aContentPolicyType,
bool aCanMakeNewChannel,
bool* aNewChannelCreated,
imgRequestProxy** aProxyRequest,
nsIPrincipal* aLoadingPrincipal,
int32_t aCORSMode);
@ -429,7 +430,8 @@ private: // methods
nsContentPolicyType aContentPolicyType,
imgRequestProxy** aProxyRequest,
nsIPrincipal* aLoadingPrincipal,
int32_t aCORSMode);
int32_t aCORSMode,
bool* aNewChannelCreated);
nsresult CreateNewProxyForRequest(imgRequest* aRequest,
nsILoadGroup* aLoadGroup,

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

@ -431,6 +431,7 @@ LoadInfoToLoadInfoArgs(nsILoadInfo *aLoadInfo,
aLoadInfo->GetInitialSecurityCheckDone(),
aLoadInfo->GetIsInThirdPartyContext(),
aLoadInfo->GetIsDocshellReload(),
aLoadInfo->GetSendCSPViolationEvents(),
aLoadInfo->GetOriginAttributes(),
redirectChainIncludingInternalRedirects,
redirectChain,
@ -587,6 +588,7 @@ LoadInfoArgsToLoadInfo(const OptionalLoadInfoArgs& aOptionalLoadInfoArgs,
loadInfoArgs.initialSecurityCheckDone(),
loadInfoArgs.isInThirdPartyContext(),
loadInfoArgs.isDocshellReload(),
loadInfoArgs.sendCSPViolationEvents(),
loadInfoArgs.originAttributes(),
redirectChainIncludingInternalRedirects,
redirectChain,

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

@ -82,6 +82,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mInitialSecurityCheckDone(false)
, mIsThirdPartyContext(false)
, mIsDocshellReload(false)
, mSendCSPViolationEvents(true)
, mForcePreflight(false)
, mIsPreflight(false)
, mLoadTriggeredFromExternal(false)
@ -315,6 +316,7 @@ LoadInfo::LoadInfo(nsPIDOMWindowOuter* aOuterWindow,
, mInitialSecurityCheckDone(false)
, mIsThirdPartyContext(false) // NB: TYPE_DOCUMENT implies not third-party.
, mIsDocshellReload(false)
, mSendCSPViolationEvents(true)
, mForcePreflight(false)
, mIsPreflight(false)
, mLoadTriggeredFromExternal(false)
@ -401,6 +403,7 @@ LoadInfo::LoadInfo(const LoadInfo& rhs)
, mInitialSecurityCheckDone(rhs.mInitialSecurityCheckDone)
, mIsThirdPartyContext(rhs.mIsThirdPartyContext)
, mIsDocshellReload(rhs.mIsDocshellReload)
, mSendCSPViolationEvents(rhs.mSendCSPViolationEvents)
, mOriginAttributes(rhs.mOriginAttributes)
, mRedirectChainIncludingInternalRedirects(
rhs.mRedirectChainIncludingInternalRedirects)
@ -447,6 +450,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
bool aInitialSecurityCheckDone,
bool aIsThirdPartyContext,
bool aIsDocshellReload,
bool aSendCSPViolationEvents,
const OriginAttributes& aOriginAttributes,
RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
RedirectHistoryArray& aRedirectChain,
@ -488,6 +492,7 @@ LoadInfo::LoadInfo(nsIPrincipal* aLoadingPrincipal,
, mInitialSecurityCheckDone(aInitialSecurityCheckDone)
, mIsThirdPartyContext(aIsThirdPartyContext)
, mIsDocshellReload(aIsDocshellReload)
, mSendCSPViolationEvents(aSendCSPViolationEvents)
, mOriginAttributes(aOriginAttributes)
, mAncestorPrincipals(std::move(aAncestorPrincipals))
, mAncestorOuterWindowIDs(aAncestorOuterWindowIDs)
@ -839,6 +844,20 @@ LoadInfo::SetIsDocshellReload(bool aValue)
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetSendCSPViolationEvents(bool* aResult)
{
*aResult = mSendCSPViolationEvents;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::SetSendCSPViolationEvents(bool aValue)
{
mSendCSPViolationEvents = aValue;
return NS_OK;
}
NS_IMETHODIMP
LoadInfo::GetExternalContentPolicyType(nsContentPolicyType* aResult)
{

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

@ -124,6 +124,7 @@ private:
bool aInitialSecurityCheckDone,
bool aIsThirdPartyRequest,
bool aIsDocshellReload,
bool aSendCSPViolationEvents,
const OriginAttributes& aOriginAttributes,
RedirectHistoryArray& aRedirectChainIncludingInternalRedirects,
RedirectHistoryArray& aRedirectChain,
@ -194,6 +195,7 @@ private:
bool mInitialSecurityCheckDone;
bool mIsThirdPartyContext;
bool mIsDocshellReload;
bool mSendCSPViolationEvents;
OriginAttributes mOriginAttributes;
RedirectHistoryArray mRedirectChainIncludingInternalRedirects;
RedirectHistoryArray mRedirectChain;

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

@ -502,6 +502,12 @@ interface nsILoadInfo : nsISupports
*/
readonly attribute nsContentPolicyType externalContentPolicyType;
/**
* CSP uses this parameter to send or not CSP violation events.
* Default value: true.
*/
[infallible] attribute boolean sendCSPViolationEvents;
%{ C++
inline nsContentPolicyType GetExternalContentPolicyType()
{

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

@ -65,6 +65,7 @@ struct LoadInfoArgs
bool initialSecurityCheckDone;
bool isInThirdPartyContext;
bool isDocshellReload;
bool sendCSPViolationEvents;
OriginAttributes originAttributes;
RedirectHistoryEntryInfo[] redirectChainIncludingInternalRedirects;
RedirectHistoryEntryInfo[] redirectChain;

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

@ -1,5 +0,0 @@
[media-src-7_1_2.sub.html]
expected: TIMEOUT
[Test that securitypolicyviolation events are fired]
expected: TIMEOUT

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

@ -1,5 +0,0 @@
[media-src-7_2_2.sub.html]
expected: TIMEOUT
[Test that securitypolicyviolation events are fired]
expected: TIMEOUT

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

@ -1,5 +0,0 @@
[media-src-blocked.sub.html]
expected: TIMEOUT
[Test that securitypolicyviolation events are fired]
expected: TIMEOUT

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

@ -0,0 +1,3 @@
[fetch-csp.https.html]
[Verify CSP control of fetch() in a Service Worker]
expected: FAIL

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

@ -2,6 +2,3 @@
[Script: Ed25519-with-CSP, passes, valid key, valid signature.]
expected: FAIL
[Script: Ed25519-with-CSP, fails, valid key, valid signature, key not in CSP.]
expected: FAIL