From 26a029d407be480d791972afb5975cf62c9360a6 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Fri, 19 Apr 2024 02:47:55 +0200 Subject: Adding upstream version 124.0.1. Signed-off-by: Daniel Baumann --- dom/security/featurepolicy/FeaturePolicyParser.cpp | 157 +++++++++++++++++++++ 1 file changed, 157 insertions(+) create mode 100644 dom/security/featurepolicy/FeaturePolicyParser.cpp (limited to 'dom/security/featurepolicy/FeaturePolicyParser.cpp') diff --git a/dom/security/featurepolicy/FeaturePolicyParser.cpp b/dom/security/featurepolicy/FeaturePolicyParser.cpp new file mode 100644 index 0000000000..8ab95420aa --- /dev/null +++ b/dom/security/featurepolicy/FeaturePolicyParser.cpp @@ -0,0 +1,157 @@ +/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ +/* vim: set ts=8 sts=2 et sw=2 tw=80: */ +/* 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 "FeaturePolicyParser.h" + +#include "mozilla/BasePrincipal.h" +#include "mozilla/dom/Feature.h" +#include "mozilla/dom/FeaturePolicyUtils.h" +#include "mozilla/dom/PolicyTokenizer.h" +#include "nsIScriptError.h" +#include "nsIURI.h" +#include "nsNetUtil.h" + +namespace mozilla::dom { + +namespace { + +void ReportToConsoleUnsupportedFeature(Document* aDocument, + const nsString& aFeatureName) { + if (!aDocument) { + return; + } + + AutoTArray params = {aFeatureName}; + + nsContentUtils::ReportToConsole( + nsIScriptError::warningFlag, "Feature Policy"_ns, aDocument, + nsContentUtils::eSECURITY_PROPERTIES, + "FeaturePolicyUnsupportedFeatureName", params); +} + +void ReportToConsoleInvalidEmptyAllowValue(Document* aDocument, + const nsString& aFeatureName) { + if (!aDocument) { + return; + } + + AutoTArray params = {aFeatureName}; + + nsContentUtils::ReportToConsole( + nsIScriptError::warningFlag, "Feature Policy"_ns, aDocument, + nsContentUtils::eSECURITY_PROPERTIES, + "FeaturePolicyInvalidEmptyAllowValue", params); +} + +void ReportToConsoleInvalidAllowValue(Document* aDocument, + const nsString& aValue) { + if (!aDocument) { + return; + } + + AutoTArray params = {aValue}; + + nsContentUtils::ReportToConsole(nsIScriptError::warningFlag, + "Feature Policy"_ns, aDocument, + nsContentUtils::eSECURITY_PROPERTIES, + "FeaturePolicyInvalidAllowValue", params); +} + +} // namespace + +/* static */ +bool FeaturePolicyParser::ParseString(const nsAString& aPolicy, + Document* aDocument, + nsIPrincipal* aSelfOrigin, + nsIPrincipal* aSrcOrigin, + nsTArray& aParsedFeatures) { + MOZ_ASSERT(aSelfOrigin); + + nsTArray> tokens; + PolicyTokenizer::tokenizePolicy(aPolicy, tokens); + + nsTArray parsedFeatures; + + for (const nsTArray& featureTokens : tokens) { + if (featureTokens.IsEmpty()) { + continue; + } + + if (!FeaturePolicyUtils::IsSupportedFeature(featureTokens[0])) { + ReportToConsoleUnsupportedFeature(aDocument, featureTokens[0]); + continue; + } + + Feature feature(featureTokens[0]); + + if (featureTokens.Length() == 1) { + if (aSrcOrigin) { + feature.AppendToAllowList(aSrcOrigin); + } else { + ReportToConsoleInvalidEmptyAllowValue(aDocument, featureTokens[0]); + continue; + } + } else { + // we gotta start at 1 here + for (uint32_t i = 1; i < featureTokens.Length(); ++i) { + const nsString& curVal = featureTokens[i]; + if (curVal.LowerCaseEqualsASCII("'none'")) { + feature.SetAllowsNone(); + break; + } + + if (curVal.EqualsLiteral("*")) { + feature.SetAllowsAll(); + break; + } + + if (curVal.LowerCaseEqualsASCII("'self'")) { + feature.AppendToAllowList(aSelfOrigin); + continue; + } + + if (aSrcOrigin && curVal.LowerCaseEqualsASCII("'src'")) { + feature.AppendToAllowList(aSrcOrigin); + continue; + } + + nsCOMPtr uri; + nsresult rv = NS_NewURI(getter_AddRefs(uri), curVal); + if (NS_FAILED(rv)) { + ReportToConsoleInvalidAllowValue(aDocument, curVal); + continue; + } + + nsCOMPtr origin = BasePrincipal::CreateContentPrincipal( + uri, BasePrincipal::Cast(aSelfOrigin)->OriginAttributesRef()); + if (NS_WARN_IF(!origin)) { + ReportToConsoleInvalidAllowValue(aDocument, curVal); + continue; + } + + feature.AppendToAllowList(origin); + } + } + + // No duplicate! + bool found = false; + for (const Feature& parsedFeature : parsedFeatures) { + if (parsedFeature.Name() == feature.Name()) { + found = true; + break; + } + } + + if (!found) { + parsedFeatures.AppendElement(feature); + } + } + + aParsedFeatures = std::move(parsedFeatures); + return true; +} + +} // namespace mozilla::dom -- cgit v1.2.3