Bug 1407056: Part 2 - Override page CSP for loads by expanded principals. r=bz,krizsa

Per the CSP specification, content injected by extensions is meant to be
exempt from page CSP. This patch takes care of the most common case of content
injected by extension content scripts, which always have expanded principals
which inherit from the page principal.

In a follow-up, we'll probably need to extend the exemption to stylesheet
content loaded by extension codebase principals.

MozReview-Commit-ID: GlY887QAb5V

--HG--
extra : rebase_source : 1371b4e4e7f330b7f7721d4aa169fcb52a7622d0
This commit is contained in:
Kris Maglione 2017-10-07 14:53:30 -07:00
Родитель 5fdcb5a5d2
Коммит 84fb189b82
2 изменённых файлов: 21 добавлений и 5 удалений

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

@ -125,6 +125,16 @@ public:
inline bool FastSubsumesConsideringDomain(nsIPrincipal* aOther);
inline bool FastSubsumesConsideringDomainIgnoringFPD(nsIPrincipal* aOther);
/**
* Returns true if this principal's CSP should override a document's CSP for
* loads that it triggers. Currently true only for expanded principals which
* subsume the document principal.
*/
bool OverridesCSP(nsIPrincipal* aDocumentPrincipal)
{
return mKind == eExpandedPrincipal && FastSubsumes(aDocumentPrincipal);
}
protected:
virtual ~BasePrincipal();

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

@ -132,12 +132,18 @@ CSPService::ShouldLoad(uint32_t aContentType,
return NS_OK;
}
// query the principal of the document; if no document is passed, then
// fall back to using the requestPrincipal (e.g. service workers do not
// pass a document).
// Find a principal to retrieve the CSP from. If we don't have a context node
// (because, for instance, the load originates in a service worker), or the
// requesting principal's CSP overrides our document CSP, use the request
// principal. Otherwise, use the document principal.
nsCOMPtr<nsINode> node(do_QueryInterface(aRequestContext));
nsCOMPtr<nsIPrincipal> principal = node ? node->NodePrincipal()
: aRequestPrincipal;
nsCOMPtr<nsIPrincipal> principal;
if (!node || (aRequestPrincipal &&
BasePrincipal::Cast(aRequestPrincipal)->OverridesCSP(node->NodePrincipal()))) {
principal = aRequestPrincipal;
} else {
principal = node->NodePrincipal();
}
if (!principal) {
// if we can't query a principal, then there is nothing to do.
return NS_OK;