mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-23 21:01:08 +00:00
Bug 1834786 - Don't return cached stylesheets if the sheet principal doesn't match. r=dholbert
Otherwise stuff accessing stylesheets from a sandbox and content might conflict, and we might incorrectly deny giving access to a CSSStyleSheet's rules. Differential Revision: https://phabricator.services.mozilla.com/D178971
This commit is contained in:
parent
2d68c1a7db
commit
216d1c4ccc
@ -1688,18 +1688,25 @@ void Loader::MarkLoadTreeFailed(SheetLoadData& aLoadData,
|
||||
} while (data);
|
||||
}
|
||||
|
||||
RefPtr<StyleSheet> Loader::LookupInlineSheetInCache(const nsAString& aBuffer) {
|
||||
RefPtr<StyleSheet> Loader::LookupInlineSheetInCache(
|
||||
const nsAString& aBuffer, nsIPrincipal* aSheetPrincipal) {
|
||||
auto result = mInlineSheets.Lookup(aBuffer);
|
||||
if (!result) {
|
||||
return nullptr;
|
||||
}
|
||||
if (result.Data()->HasModifiedRules()) {
|
||||
StyleSheet* sheet = result.Data();
|
||||
if (NS_WARN_IF(sheet->HasModifiedRules())) {
|
||||
// Remove it now that we know that we're never going to use this stylesheet
|
||||
// again.
|
||||
result.Remove();
|
||||
return nullptr;
|
||||
}
|
||||
return result.Data()->Clone(nullptr, nullptr);
|
||||
if (NS_WARN_IF(!sheet->Principal()->Equals(aSheetPrincipal))) {
|
||||
// If the sheet is going to have different access rights, don't return it
|
||||
// from the cache.
|
||||
return nullptr;
|
||||
}
|
||||
return sheet->Clone(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void Loader::MaybeNotifyPreloadUsed(SheetLoadData& aData) {
|
||||
@ -1748,11 +1755,23 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadInlineStyle(
|
||||
nsIURI* originalURI = nullptr;
|
||||
|
||||
MOZ_ASSERT(aInfo.mIntegrity.IsEmpty());
|
||||
|
||||
nsIPrincipal* loadingPrincipal = LoaderPrincipal();
|
||||
nsIPrincipal* principal = aInfo.mTriggeringPrincipal
|
||||
? aInfo.mTriggeringPrincipal.get()
|
||||
: loadingPrincipal;
|
||||
nsIPrincipal* sheetPrincipal = [&] {
|
||||
// The triggering principal may be an expanded principal, which is safe to
|
||||
// use for URL security checks, but not as the loader principal for a
|
||||
// stylesheet. So treat this as principal inheritance, and downgrade if
|
||||
// necessary.
|
||||
//
|
||||
// FIXME(emilio): Why doing this for inline sheets but not for links?
|
||||
if (aInfo.mTriggeringPrincipal) {
|
||||
return BasePrincipal::Cast(aInfo.mTriggeringPrincipal)
|
||||
->PrincipalToInherit();
|
||||
}
|
||||
return LoaderPrincipal();
|
||||
}();
|
||||
|
||||
// We only cache sheets if in shadow trees, since regular document sheets are
|
||||
// likely to be unique.
|
||||
@ -1761,7 +1780,7 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadInlineStyle(
|
||||
aInfo.mContent->IsInShadowTree();
|
||||
RefPtr<StyleSheet> sheet;
|
||||
if (isWorthCaching) {
|
||||
sheet = LookupInlineSheetInCache(aBuffer);
|
||||
sheet = LookupInlineSheetInCache(aBuffer, sheetPrincipal);
|
||||
}
|
||||
const bool sheetFromCache = !!sheet;
|
||||
if (!sheet) {
|
||||
@ -1771,18 +1790,7 @@ Result<Loader::LoadSheetResult, nsresult> Loader::LoadInlineStyle(
|
||||
nsIReferrerInfo* referrerInfo =
|
||||
aInfo.mContent->OwnerDoc()->ReferrerInfoForInternalCSSAndSVGResources();
|
||||
sheet->SetReferrerInfo(referrerInfo);
|
||||
|
||||
nsIPrincipal* sheetPrincipal = principal;
|
||||
if (aInfo.mTriggeringPrincipal) {
|
||||
// The triggering principal may be an expanded principal, which is safe to
|
||||
// use for URL security checks, but not as the loader principal for a
|
||||
// stylesheet. So treat this as principal inheritance, and downgrade if
|
||||
// necessary.
|
||||
sheetPrincipal =
|
||||
BasePrincipal::Cast(aInfo.mTriggeringPrincipal)->PrincipalToInherit();
|
||||
}
|
||||
|
||||
// We never actually load this, so just set its principal directly
|
||||
// We never actually load this, so just set its principal directly.
|
||||
sheet->SetPrincipal(sheetPrincipal);
|
||||
}
|
||||
|
||||
|
@ -544,7 +544,7 @@ class Loader final {
|
||||
CORSMode aCORSMode, const nsAString& aIntegrity,
|
||||
uint64_t aEarlyHintPreloaderId);
|
||||
|
||||
RefPtr<StyleSheet> LookupInlineSheetInCache(const nsAString&);
|
||||
RefPtr<StyleSheet> LookupInlineSheetInCache(const nsAString&, nsIPrincipal*);
|
||||
|
||||
// Post a load event for aObserver to be notified about aSheet. The
|
||||
// notification will be sent with status NS_OK unless the load event is
|
||||
|
@ -366,12 +366,7 @@ StyleSheetInfo::StyleSheetInfo(CORSMode aCORSMode,
|
||||
mReferrerInfo(new ReferrerInfo(nullptr)),
|
||||
mIntegrity(aIntegrity),
|
||||
mContents(Servo_StyleSheet_Empty(aParsingMode).Consume()),
|
||||
mURLData(URLExtraData::Dummy())
|
||||
#ifdef DEBUG
|
||||
,
|
||||
mPrincipalSet(false)
|
||||
#endif
|
||||
{
|
||||
mURLData(URLExtraData::Dummy()) {
|
||||
if (!mPrincipal) {
|
||||
MOZ_CRASH("NullPrincipal::Init failed");
|
||||
}
|
||||
|
@ -26,7 +26,7 @@ struct URLExtraData;
|
||||
* Struct for data common to CSSStyleSheetInner and ServoStyleSheet.
|
||||
*/
|
||||
struct StyleSheetInfo final {
|
||||
typedef dom::ReferrerPolicy ReferrerPolicy;
|
||||
using ReferrerPolicy = dom::ReferrerPolicy;
|
||||
|
||||
StyleSheetInfo(CORSMode aCORSMode, const dom::SRIMetadata& aIntegrity,
|
||||
css::SheetParsingMode aParsingMode);
|
||||
@ -49,7 +49,7 @@ struct StyleSheetInfo final {
|
||||
nsCOMPtr<nsIURI> mOriginalSheetURI; // for GetHref. Can be null.
|
||||
nsCOMPtr<nsIURI> mBaseURI; // for resolving relative URIs
|
||||
nsCOMPtr<nsIPrincipal> mPrincipal;
|
||||
CORSMode mCORSMode;
|
||||
const CORSMode mCORSMode;
|
||||
// The ReferrerInfo of a stylesheet is used for its child sheets and loads
|
||||
// come from this stylesheet, so it is stored here.
|
||||
nsCOMPtr<nsIReferrerInfo> mReferrerInfo;
|
||||
@ -91,7 +91,7 @@ struct StyleSheetInfo final {
|
||||
RefPtr<URLExtraData> mURLData;
|
||||
|
||||
#ifdef DEBUG
|
||||
bool mPrincipalSet;
|
||||
bool mPrincipalSet = false;
|
||||
#endif
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user