Bug 1496034 - Apply bz's comments to FeaturePolicy, r=bz
This commit is contained in:
@@ -3024,27 +3024,19 @@ nsIDocument::InitFeaturePolicy(nsIChannel* aChannel)
|
|||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString origin;
|
mFeaturePolicy->SetDefaultOrigin(NodePrincipal());
|
||||||
nsresult rv = nsContentUtils::GetUTFOrigin(NodePrincipal(), origin);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
mFeaturePolicy->SetDefaultOrigin(origin);
|
|
||||||
|
|
||||||
RefPtr<FeaturePolicy> parentPolicy = nullptr;
|
RefPtr<FeaturePolicy> parentPolicy = nullptr;
|
||||||
if (mDocumentContainer) {
|
if (mDocumentContainer) {
|
||||||
nsPIDOMWindowOuter* containerWindow = mDocumentContainer->GetWindow();
|
nsPIDOMWindowOuter* containerWindow = mDocumentContainer->GetWindow();
|
||||||
if (containerWindow) {
|
if (containerWindow) {
|
||||||
nsCOMPtr<nsINode> node = containerWindow->GetFrameElementInternal();
|
nsCOMPtr<nsINode> node = containerWindow->GetFrameElementInternal();
|
||||||
if (node) {
|
HTMLIFrameElement* iframe = HTMLIFrameElement::FromNodeOrNull(node);
|
||||||
HTMLIFrameElement* iframe = HTMLIFrameElement::FromNode(node);
|
|
||||||
if (iframe) {
|
if (iframe) {
|
||||||
parentPolicy = iframe->Policy();
|
parentPolicy = iframe->Policy();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
if (parentPolicy) {
|
if (parentPolicy) {
|
||||||
// Let's inherit the policy from the parent HTMLIFrameElement if it exists.
|
// Let's inherit the policy from the parent HTMLIFrameElement if it exists.
|
||||||
@@ -3052,7 +3044,7 @@ nsIDocument::InitFeaturePolicy(nsIChannel* aChannel)
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsCOMPtr<nsIHttpChannel> httpChannel;
|
nsCOMPtr<nsIHttpChannel> httpChannel;
|
||||||
rv = GetHttpChannelHelper(aChannel, getter_AddRefs(httpChannel));
|
nsresult rv = GetHttpChannelHelper(aChannel, getter_AddRefs(httpChannel));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
@@ -3067,8 +3059,7 @@ nsIDocument::InitFeaturePolicy(nsIChannel* aChannel)
|
|||||||
value);
|
value);
|
||||||
if (NS_SUCCEEDED(rv)) {
|
if (NS_SUCCEEDED(rv)) {
|
||||||
mFeaturePolicy->SetDeclaredPolicy(this, NS_ConvertUTF8toUTF16(value),
|
mFeaturePolicy->SetDeclaredPolicy(this, NS_ConvertUTF8toUTF16(value),
|
||||||
origin, EmptyString(),
|
NodePrincipal(), nullptr);
|
||||||
false /* 'src' enabled */);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
@@ -10231,7 +10222,8 @@ nsIDocument::Policy() const
|
|||||||
MOZ_ASSERT(StaticPrefs::dom_security_featurePolicy_enabled());
|
MOZ_ASSERT(StaticPrefs::dom_security_featurePolicy_enabled());
|
||||||
|
|
||||||
// The policy is created when the document is initialized. We _must_ have a
|
// The policy is created when the document is initialized. We _must_ have a
|
||||||
// policy here.
|
// policy here even if the featurePolicy pref is off. If this assertion fails,
|
||||||
|
// it means that ::Policy() is called before ::StartDocumentLoad().
|
||||||
MOZ_ASSERT(mFeaturePolicy);
|
MOZ_ASSERT(mFeaturePolicy);
|
||||||
return mFeaturePolicy;
|
return mFeaturePolicy;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#include "mozilla/dom/HTMLIFrameElementBinding.h"
|
#include "mozilla/dom/HTMLIFrameElementBinding.h"
|
||||||
#include "mozilla/dom/FeaturePolicy.h"
|
#include "mozilla/dom/FeaturePolicy.h"
|
||||||
#include "mozilla/MappedDeclarations.h"
|
#include "mozilla/MappedDeclarations.h"
|
||||||
|
#include "mozilla/NullPrincipal.h"
|
||||||
#include "mozilla/StaticPrefs.h"
|
#include "mozilla/StaticPrefs.h"
|
||||||
#include "nsMappedAttributes.h"
|
#include "nsMappedAttributes.h"
|
||||||
#include "nsAttrValueInlines.h"
|
#include "nsAttrValueInlines.h"
|
||||||
@@ -22,6 +23,24 @@ NS_IMPL_NS_NEW_HTML_ELEMENT_CHECK_PARSER(IFrame)
|
|||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_CLASS(HTMLIFrameElement)
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(HTMLIFrameElement,
|
||||||
|
nsGenericHTMLFrameElement)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFeaturePolicy)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(HTMLIFrameElement,
|
||||||
|
nsGenericHTMLFrameElement)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFeaturePolicy)
|
||||||
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
|
NS_IMPL_ADDREF_INHERITED(HTMLIFrameElement, nsGenericHTMLFrameElement)
|
||||||
|
NS_IMPL_RELEASE_INHERITED(HTMLIFrameElement, nsGenericHTMLFrameElement)
|
||||||
|
|
||||||
|
NS_INTERFACE_MAP_BEGIN_CYCLE_COLLECTION(HTMLIFrameElement)
|
||||||
|
NS_INTERFACE_MAP_END_INHERITING(nsGenericHTMLFrameElement)
|
||||||
|
|
||||||
// static
|
// static
|
||||||
const DOMTokenListSupportedToken HTMLIFrameElement::sSupportedSandboxTokens[] = {
|
const DOMTokenListSupportedToken HTMLIFrameElement::sSupportedSandboxTokens[] = {
|
||||||
#define SANDBOX_KEYWORD(string, atom, flags) string,
|
#define SANDBOX_KEYWORD(string, atom, flags) string,
|
||||||
@@ -34,10 +53,9 @@ HTMLIFrameElement::HTMLIFrameElement(already_AddRefed<mozilla::dom::NodeInfo>&&
|
|||||||
FromParser aFromParser)
|
FromParser aFromParser)
|
||||||
: nsGenericHTMLFrameElement(std::move(aNodeInfo), aFromParser)
|
: nsGenericHTMLFrameElement(std::move(aNodeInfo), aFromParser)
|
||||||
{
|
{
|
||||||
if (StaticPrefs::dom_security_featurePolicy_enabled()) {
|
// We always need a featurePolicy, even if not exposed.
|
||||||
mFeaturePolicy = new FeaturePolicy(this);
|
mFeaturePolicy = new FeaturePolicy(this);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
HTMLIFrameElement::~HTMLIFrameElement()
|
HTMLIFrameElement::~HTMLIFrameElement()
|
||||||
{
|
{
|
||||||
@@ -174,6 +192,7 @@ HTMLIFrameElement::AfterSetAttr(int32_t aNameSpaceID, nsAtom* aName,
|
|||||||
}
|
}
|
||||||
if ((aName == nsGkAtoms::allow ||
|
if ((aName == nsGkAtoms::allow ||
|
||||||
aName == nsGkAtoms::src ||
|
aName == nsGkAtoms::src ||
|
||||||
|
aName == nsGkAtoms::srcdoc ||
|
||||||
aName == nsGkAtoms::sandbox ||
|
aName == nsGkAtoms::sandbox ||
|
||||||
aName == nsGkAtoms::allowpaymentrequest) &&
|
aName == nsGkAtoms::allowpaymentrequest) &&
|
||||||
StaticPrefs::dom_security_featurePolicy_enabled()) {
|
StaticPrefs::dom_security_featurePolicy_enabled()) {
|
||||||
@@ -236,41 +255,29 @@ HTMLIFrameElement::Policy() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
nsresult
|
nsresult
|
||||||
HTMLIFrameElement::GetFeaturePolicyDefaultOrigin(nsAString& aDefaultOrigin) const
|
HTMLIFrameElement::GetFeaturePolicyDefaultOrigin(nsIPrincipal** aPrincipal) const
|
||||||
{
|
{
|
||||||
aDefaultOrigin.Truncate();
|
nsCOMPtr<nsIPrincipal> principal;
|
||||||
|
|
||||||
nsresult rv;
|
if (HasAttr(kNameSpaceID_None, nsGkAtoms::srcdoc)) {
|
||||||
nsAutoString src;
|
principal = NodePrincipal();
|
||||||
GetURIAttr(nsGkAtoms::src, nullptr, src);
|
}
|
||||||
|
|
||||||
|
if (!principal) {
|
||||||
nsCOMPtr<nsIURI> nodeURI;
|
nsCOMPtr<nsIURI> nodeURI;
|
||||||
if (!src.IsEmpty()) {
|
if (GetURIAttr(nsGkAtoms::src, nullptr, getter_AddRefs(nodeURI)) &&
|
||||||
nsCOMPtr<nsIURI> baseURI = OwnerDoc()->GetBaseURI();
|
nodeURI) {
|
||||||
|
principal =
|
||||||
rv = NS_NewURI(getter_AddRefs(nodeURI), src,
|
BasePrincipal::CreateCodebasePrincipal(nodeURI,
|
||||||
OwnerDoc()->GetDocumentCharacterSet(),
|
BasePrincipal::Cast(NodePrincipal())->OriginAttributesRef());
|
||||||
baseURI);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
nodeURI = nullptr;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!nodeURI) {
|
if (!principal) {
|
||||||
if (OwnerDoc()->GetSandboxFlags() & SANDBOXED_ORIGIN) {
|
principal = NodePrincipal();
|
||||||
return NS_OK;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
nodeURI = OwnerDoc()->GetDocumentURI();
|
principal.forget(aPrincipal);
|
||||||
}
|
|
||||||
|
|
||||||
nsAutoString origin;
|
|
||||||
rv = nsContentUtils::GetUTFOrigin(nodeURI, origin);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return rv;
|
|
||||||
}
|
|
||||||
|
|
||||||
aDefaultOrigin.Assign(origin);
|
|
||||||
return NS_OK;
|
return NS_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -281,29 +288,22 @@ HTMLIFrameElement::RefreshFeaturePolicy()
|
|||||||
mFeaturePolicy->ResetDeclaredPolicy();
|
mFeaturePolicy->ResetDeclaredPolicy();
|
||||||
|
|
||||||
// The origin can change if 'src' attribute changes.
|
// The origin can change if 'src' attribute changes.
|
||||||
nsAutoString origin;
|
nsCOMPtr<nsIPrincipal> origin;
|
||||||
nsresult rv = GetFeaturePolicyDefaultOrigin(origin);
|
nsresult rv = GetFeaturePolicyDefaultOrigin(getter_AddRefs(origin));
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
MOZ_ASSERT(origin);
|
||||||
mFeaturePolicy->SetDefaultOrigin(origin);
|
mFeaturePolicy->SetDefaultOrigin(origin);
|
||||||
|
|
||||||
nsAutoString allow;
|
nsAutoString allow;
|
||||||
GetAttr(nsGkAtoms::allow, allow);
|
GetAttr(nsGkAtoms::allow, allow);
|
||||||
|
|
||||||
if (!allow.IsEmpty()) {
|
if (!allow.IsEmpty()) {
|
||||||
nsAutoString documentOrigin;
|
|
||||||
if (OwnerDoc()->GetSandboxFlags() ^ SANDBOXED_ORIGIN) {
|
|
||||||
nsresult rv = nsContentUtils::GetUTFOrigin(NodePrincipal(), documentOrigin);
|
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Set or reset the FeaturePolicy directives.
|
// Set or reset the FeaturePolicy directives.
|
||||||
mFeaturePolicy->SetDeclaredPolicy(OwnerDoc(), allow, documentOrigin,
|
mFeaturePolicy->SetDeclaredPolicy(OwnerDoc(), allow, NodePrincipal(),
|
||||||
origin, true /* 'src' enabled */);
|
origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
mFeaturePolicy->InheritPolicy(OwnerDoc()->Policy());
|
mFeaturePolicy->InheritPolicy(OwnerDoc()->Policy());
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
#define mozilla_dom_HTMLIFrameElement_h
|
#define mozilla_dom_HTMLIFrameElement_h
|
||||||
|
|
||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
|
#include "mozilla/dom/FeaturePolicy.h"
|
||||||
#include "nsGenericHTMLFrameElement.h"
|
#include "nsGenericHTMLFrameElement.h"
|
||||||
#include "nsDOMTokenList.h"
|
#include "nsDOMTokenList.h"
|
||||||
|
|
||||||
@@ -23,7 +24,8 @@ public:
|
|||||||
NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLIFrameElement, iframe)
|
NS_IMPL_FROMNODE_HTML_WITH_TAG(HTMLIFrameElement, iframe)
|
||||||
|
|
||||||
// nsISupports
|
// nsISupports
|
||||||
NS_INLINE_DECL_REFCOUNTING_INHERITED(HTMLIFrameElement,
|
NS_DECL_ISUPPORTS_INHERITED
|
||||||
|
NS_DECL_CYCLE_COLLECTION_CLASS_INHERITED(HTMLIFrameElement,
|
||||||
nsGenericHTMLFrameElement)
|
nsGenericHTMLFrameElement)
|
||||||
|
|
||||||
// Element
|
// Element
|
||||||
@@ -223,8 +225,13 @@ private:
|
|||||||
|
|
||||||
void RefreshFeaturePolicy();
|
void RefreshFeaturePolicy();
|
||||||
|
|
||||||
|
// Implements the declared-origin algorithm as described in Feature-Policy
|
||||||
|
// spec: https://wicg.github.io/feature-policy/#declared-origin
|
||||||
|
// If this iframe has a 'src' attribute, the origin will be the parsing of its
|
||||||
|
// value as URL. If the URL is invalid, or 'src' attribute doesn't exist, the
|
||||||
|
// origin will be the document's origin.
|
||||||
nsresult
|
nsresult
|
||||||
GetFeaturePolicyDefaultOrigin(nsAString& aDefaultOrigin) const;
|
GetFeaturePolicyDefaultOrigin(nsIPrincipal** aDefaultOrigin) const;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
* This function is called by AfterSetAttr and OnAttrSetButNotChanged.
|
||||||
@@ -236,6 +243,8 @@ private:
|
|||||||
* @param aNotify Whether we plan to notify document observers.
|
* @param aNotify Whether we plan to notify document observers.
|
||||||
*/
|
*/
|
||||||
void AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName, bool aNotify);
|
void AfterMaybeChangeAttr(int32_t aNamespaceID, nsAtom* aName, bool aNotify);
|
||||||
|
|
||||||
|
RefPtr<mozilla::dom::FeaturePolicy> mFeaturePolicy;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace dom
|
} // namespace dom
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ NS_IMPL_CYCLE_COLLECTION_TRAVERSE_BEGIN_INHERITED(nsGenericHTMLFrameElement,
|
|||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFrameLoader)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenerWindow)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mOpenerWindow)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAPI)
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mBrowserElementAPI)
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE(mFeaturePolicy)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
NS_IMPL_CYCLE_COLLECTION_TRAVERSE_END
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGenericHTMLFrameElement,
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGenericHTMLFrameElement,
|
||||||
@@ -47,7 +46,6 @@ NS_IMPL_CYCLE_COLLECTION_UNLINK_BEGIN_INHERITED(nsGenericHTMLFrameElement,
|
|||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFrameLoader)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenerWindow)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mOpenerWindow)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserElementAPI)
|
NS_IMPL_CYCLE_COLLECTION_UNLINK(mBrowserElementAPI)
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK(mFeaturePolicy)
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
NS_IMPL_CYCLE_COLLECTION_UNLINK_END
|
||||||
|
|
||||||
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(nsGenericHTMLFrameElement,
|
NS_IMPL_ISUPPORTS_CYCLE_COLLECTION_INHERITED(nsGenericHTMLFrameElement,
|
||||||
|
|||||||
@@ -10,7 +10,6 @@
|
|||||||
#include "mozilla/Attributes.h"
|
#include "mozilla/Attributes.h"
|
||||||
#include "mozilla/ErrorResult.h"
|
#include "mozilla/ErrorResult.h"
|
||||||
#include "mozilla/dom/nsBrowserElement.h"
|
#include "mozilla/dom/nsBrowserElement.h"
|
||||||
#include "mozilla/dom/FeaturePolicy.h"
|
|
||||||
|
|
||||||
#include "nsFrameLoader.h"
|
#include "nsFrameLoader.h"
|
||||||
#include "nsGenericHTMLElement.h"
|
#include "nsGenericHTMLElement.h"
|
||||||
@@ -128,9 +127,6 @@ protected:
|
|||||||
|
|
||||||
nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
|
nsCOMPtr<nsIPrincipal> mSrcTriggeringPrincipal;
|
||||||
|
|
||||||
// Used by <iframe> only.
|
|
||||||
RefPtr<mozilla::dom::FeaturePolicy> mFeaturePolicy;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* True if we have already loaded the frame's original src
|
* True if we have already loaded the frame's original src
|
||||||
*/
|
*/
|
||||||
|
|||||||
@@ -5,18 +5,20 @@
|
|||||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "Feature.h"
|
#include "Feature.h"
|
||||||
|
#include "mozilla/BasePrincipal.h"
|
||||||
|
|
||||||
using namespace mozilla::dom;
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
void
|
void
|
||||||
Feature::GetWhiteListedOrigins(nsTArray<nsString>& aList) const
|
Feature::GetAllowList(nsTArray<nsCOMPtr<nsIPrincipal>>& aList) const
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(mPolicy == eWhiteList);
|
MOZ_ASSERT(mPolicy == eAllowList);
|
||||||
aList.AppendElements(mWhiteListedOrigins);
|
aList.AppendElements(mAllowList);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Feature::Allows(const nsAString& aOrigin) const
|
Feature::Allows(nsIPrincipal* aPrincipal) const
|
||||||
{
|
{
|
||||||
if (mPolicy == eNone) {
|
if (mPolicy == eNone) {
|
||||||
return false;
|
return false;
|
||||||
@@ -26,18 +28,12 @@ Feature::Allows(const nsAString& aOrigin) const
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const nsString& whiteListedOrigin : mWhiteListedOrigins) {
|
return AllowListContains(aPrincipal);
|
||||||
if (whiteListedOrigin.Equals(aOrigin)) {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Feature::Feature(const nsAString& aFeatureName)
|
Feature::Feature(const nsAString& aFeatureName)
|
||||||
: mFeatureName(aFeatureName)
|
: mFeatureName(aFeatureName)
|
||||||
, mPolicy(eWhiteList)
|
, mPolicy(eAllowList)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
Feature::~Feature() = default;
|
Feature::~Feature() = default;
|
||||||
@@ -52,7 +48,7 @@ void
|
|||||||
Feature::SetAllowsNone()
|
Feature::SetAllowsNone()
|
||||||
{
|
{
|
||||||
mPolicy = eNone;
|
mPolicy = eNone;
|
||||||
mWhiteListedOrigins.Clear();
|
mAllowList.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -65,7 +61,7 @@ void
|
|||||||
Feature::SetAllowsAll()
|
Feature::SetAllowsAll()
|
||||||
{
|
{
|
||||||
mPolicy = eAll;
|
mPolicy = eAll;
|
||||||
mWhiteListedOrigins.Clear();
|
mAllowList.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
@@ -75,24 +71,38 @@ Feature::AllowsAll() const
|
|||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
Feature::AppendOriginToWhiteList(const nsAString& aOrigin)
|
Feature::AppendToAllowList(nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
mPolicy = eWhiteList;
|
MOZ_ASSERT(aPrincipal);
|
||||||
mWhiteListedOrigins.AppendElement(aOrigin);
|
|
||||||
|
mPolicy = eAllowList;
|
||||||
|
mAllowList.AppendElement(aPrincipal);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Feature::WhiteListContains(const nsAString& aOrigin) const
|
Feature::AllowListContains(nsIPrincipal* aPrincipal) const
|
||||||
{
|
{
|
||||||
if (!IsWhiteList()) {
|
MOZ_ASSERT(aPrincipal);
|
||||||
|
|
||||||
|
if (!HasAllowList()) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return mWhiteListedOrigins.Contains(aOrigin);
|
for (nsIPrincipal* principal : mAllowList) {
|
||||||
|
if (BasePrincipal::Cast(principal)->Subsumes(aPrincipal,
|
||||||
|
BasePrincipal::ConsiderDocumentDomain)) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Feature::IsWhiteList() const
|
Feature::HasAllowList() const
|
||||||
{
|
{
|
||||||
return mPolicy == eWhiteList;
|
return mPolicy == eAllowList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
|
|||||||
@@ -11,6 +11,8 @@
|
|||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
#include "nsCOMPtr.h"
|
#include "nsCOMPtr.h"
|
||||||
|
|
||||||
|
class nsIPrincipal;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
|
|
||||||
@@ -37,19 +39,19 @@ public:
|
|||||||
AllowsAll() const;
|
AllowsAll() const;
|
||||||
|
|
||||||
void
|
void
|
||||||
AppendOriginToWhiteList(const nsAString& aOrigin);
|
AppendToAllowList(nsIPrincipal* aPrincipal);
|
||||||
|
|
||||||
void
|
void
|
||||||
GetWhiteListedOrigins(nsTArray<nsString>& aList) const;
|
GetAllowList(nsTArray<nsCOMPtr<nsIPrincipal>>& aList) const;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
WhiteListContains(const nsAString& aOrigin) const;
|
AllowListContains(nsIPrincipal* aPrincipal) const;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
IsWhiteList() const;
|
HasAllowList() const;
|
||||||
|
|
||||||
bool
|
bool
|
||||||
Allows(const nsAString& aOrigin) const;
|
Allows(nsIPrincipal* aPrincipal) const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nsString mFeatureName;
|
nsString mFeatureName;
|
||||||
@@ -62,12 +64,12 @@ private:
|
|||||||
eAll,
|
eAll,
|
||||||
|
|
||||||
// denotes a policy of "feature bar.com foo.com"
|
// denotes a policy of "feature bar.com foo.com"
|
||||||
eWhiteList,
|
eAllowList,
|
||||||
};
|
};
|
||||||
|
|
||||||
Policy mPolicy;
|
Policy mPolicy;
|
||||||
|
|
||||||
nsTArray<nsString> mWhiteListedOrigins;
|
nsTArray<nsCOMPtr<nsIPrincipal>> mAllowList;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // dom namespace
|
} // dom namespace
|
||||||
|
|||||||
@@ -9,8 +9,10 @@
|
|||||||
#include "mozilla/dom/FeaturePolicyParser.h"
|
#include "mozilla/dom/FeaturePolicyParser.h"
|
||||||
#include "mozilla/dom/FeaturePolicyUtils.h"
|
#include "mozilla/dom/FeaturePolicyUtils.h"
|
||||||
#include "nsContentUtils.h"
|
#include "nsContentUtils.h"
|
||||||
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
using namespace mozilla::dom;
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FeaturePolicy, mParentNode)
|
NS_IMPL_CYCLE_COLLECTION_WRAPPERCACHE(FeaturePolicy, mParentNode)
|
||||||
NS_IMPL_CYCLE_COLLECTING_ADDREF(FeaturePolicy)
|
NS_IMPL_CYCLE_COLLECTING_ADDREF(FeaturePolicy)
|
||||||
@@ -34,7 +36,7 @@ FeaturePolicy::InheritPolicy(FeaturePolicy* aParentPolicy)
|
|||||||
|
|
||||||
RefPtr<FeaturePolicy> dest = this;
|
RefPtr<FeaturePolicy> dest = this;
|
||||||
RefPtr<FeaturePolicy> src = aParentPolicy;
|
RefPtr<FeaturePolicy> src = aParentPolicy;
|
||||||
nsString origin = mDefaultOrigin;
|
nsCOMPtr<nsIPrincipal> origin = mDefaultOrigin;
|
||||||
FeaturePolicyUtils::ForEachFeature([dest, src, origin](const char* aFeatureName) {
|
FeaturePolicyUtils::ForEachFeature([dest, src, origin](const char* aFeatureName) {
|
||||||
nsString featureName;
|
nsString featureName;
|
||||||
featureName.AppendASCII(aFeatureName);
|
featureName.AppendASCII(aFeatureName);
|
||||||
@@ -86,9 +88,8 @@ FeaturePolicy::HasDeclaredFeature(const nsAString& aFeatureName) const
|
|||||||
void
|
void
|
||||||
FeaturePolicy::SetDeclaredPolicy(nsIDocument* aDocument,
|
FeaturePolicy::SetDeclaredPolicy(nsIDocument* aDocument,
|
||||||
const nsAString& aPolicyString,
|
const nsAString& aPolicyString,
|
||||||
const nsAString& aSelfOrigin,
|
nsIPrincipal* aSelfOrigin,
|
||||||
const nsAString& aSrcOrigin,
|
nsIPrincipal* aSrcOrigin)
|
||||||
bool aSrcEnabled)
|
|
||||||
{
|
{
|
||||||
ResetDeclaredPolicy();
|
ResetDeclaredPolicy();
|
||||||
|
|
||||||
@@ -96,7 +97,6 @@ FeaturePolicy::SetDeclaredPolicy(nsIDocument* aDocument,
|
|||||||
aDocument,
|
aDocument,
|
||||||
aSelfOrigin,
|
aSelfOrigin,
|
||||||
aSrcOrigin,
|
aSrcOrigin,
|
||||||
aSrcEnabled,
|
|
||||||
mFeatures));
|
mFeatures));
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -116,16 +116,32 @@ bool
|
|||||||
FeaturePolicy::AllowsFeature(const nsAString& aFeatureName,
|
FeaturePolicy::AllowsFeature(const nsAString& aFeatureName,
|
||||||
const Optional<nsAString>& aOrigin) const
|
const Optional<nsAString>& aOrigin) const
|
||||||
{
|
{
|
||||||
return AllowsFeatureInternal(aFeatureName,
|
nsCOMPtr<nsIPrincipal> origin;
|
||||||
aOrigin.WasPassed()
|
if (aOrigin.WasPassed()) {
|
||||||
? aOrigin.Value()
|
nsCOMPtr<nsIURI> uri;
|
||||||
: mDefaultOrigin);
|
nsresult rv = NS_NewURI(getter_AddRefs(uri), aOrigin.Value());
|
||||||
|
if (NS_FAILED(rv)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
origin = BasePrincipal::CreateCodebasePrincipal(uri,
|
||||||
|
BasePrincipal::Cast(mDefaultOrigin)->OriginAttributesRef());
|
||||||
|
} else {
|
||||||
|
origin = mDefaultOrigin;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (NS_WARN_IF(!origin)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return AllowsFeatureInternal(aFeatureName, origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
FeaturePolicy::AllowsFeatureInternal(const nsAString& aFeatureName,
|
FeaturePolicy::AllowsFeatureInternal(const nsAString& aFeatureName,
|
||||||
const nsAString& aOrigin) const
|
nsIPrincipal* aOrigin) const
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aOrigin);
|
||||||
|
|
||||||
// Let's see if have to disable this feature because inherited policy.
|
// Let's see if have to disable this feature because inherited policy.
|
||||||
if (HasInheritedDeniedFeature(aFeatureName)) {
|
if (HasInheritedDeniedFeature(aFeatureName)) {
|
||||||
return false;
|
return false;
|
||||||
@@ -137,8 +153,22 @@ FeaturePolicy::AllowsFeatureInternal(const nsAString& aFeatureName,
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return FeaturePolicyUtils::AllowDefaultFeature(aFeatureName, mDefaultOrigin,
|
switch (FeaturePolicyUtils::DefaultAllowListFeature(aFeatureName)) {
|
||||||
aOrigin);
|
case FeaturePolicyUtils::FeaturePolicyValue::eAll:
|
||||||
|
return true;
|
||||||
|
|
||||||
|
case FeaturePolicyUtils::FeaturePolicyValue::eSelf:
|
||||||
|
return BasePrincipal::Cast(mDefaultOrigin)->Subsumes(aOrigin,
|
||||||
|
BasePrincipal::ConsiderDocumentDomain);
|
||||||
|
|
||||||
|
case FeaturePolicyUtils::FeaturePolicyValue::eNone:
|
||||||
|
return false;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Unknown default value");
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@@ -170,16 +200,44 @@ FeaturePolicy::GetAllowlistForFeature(const nsAString& aFeatureName,
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
feature.GetWhiteListedOrigins(aList);
|
nsTArray<nsCOMPtr<nsIPrincipal>> list;
|
||||||
|
feature.GetAllowList(list);
|
||||||
|
|
||||||
|
for (nsIPrincipal* principal : list) {
|
||||||
|
nsAutoCString originNoSuffix;
|
||||||
|
nsresult rv = principal->GetOriginNoSuffix(originNoSuffix);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aList.AppendElement(NS_ConvertUTF8toUTF16(originNoSuffix));
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
nsString defaultAllowList;
|
switch (FeaturePolicyUtils::DefaultAllowListFeature(aFeatureName)) {
|
||||||
FeaturePolicyUtils::DefaultAllowListFeature(aFeatureName, mDefaultOrigin,
|
case FeaturePolicyUtils::FeaturePolicyValue::eAll:
|
||||||
defaultAllowList);
|
aList.AppendElement(NS_LITERAL_STRING("*"));
|
||||||
if (!defaultAllowList.IsEmpty()) {
|
return;
|
||||||
aList.AppendElement(defaultAllowList);
|
|
||||||
|
case FeaturePolicyUtils::FeaturePolicyValue::eSelf:
|
||||||
|
{
|
||||||
|
nsAutoCString originNoSuffix;
|
||||||
|
nsresult rv = mDefaultOrigin->GetOriginNoSuffix(originNoSuffix);
|
||||||
|
if (NS_WARN_IF(NS_FAILED(rv))) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
aList.AppendElement(NS_ConvertUTF8toUTF16(originNoSuffix));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FeaturePolicyUtils::FeaturePolicyValue::eNone:
|
||||||
|
return;
|
||||||
|
|
||||||
|
default:
|
||||||
|
MOZ_CRASH("Unknown default value");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -197,3 +255,6 @@ FeaturePolicy::MaybeSetAllowedPolicy(const nsAString& aFeatureName)
|
|||||||
|
|
||||||
mFeatures.AppendElement(feature);
|
mFeatures.AppendElement(feature);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
|
|||||||
@@ -30,12 +30,12 @@
|
|||||||
* these policies:
|
* these policies:
|
||||||
* - eNone - the feature is fully disabled.
|
* - eNone - the feature is fully disabled.
|
||||||
* - eAll - the feature is allowed.
|
* - eAll - the feature is allowed.
|
||||||
* - eWhitelist - the feature is allowed for a list of origins.
|
* - eAllowList - the feature is allowed for a list of origins.
|
||||||
*
|
*
|
||||||
* An interesting element of FeaturePolicy is the inheritance: each context
|
* An interesting element of FeaturePolicy is the inheritance: each context
|
||||||
* inherits the feature-policy directives from the parent context, if it exists.
|
* inherits the feature-policy directives from the parent context, if it exists.
|
||||||
* When a context inherits a policy for feature X, it only knows if that feature
|
* When a context inherits a policy for feature X, it only knows if that feature
|
||||||
* is allowed or denied (it ignores the list of whitelist origins for instance).
|
* is allowed or denied (it ignores the list of allowed origins for instance).
|
||||||
* This information is stored in an array of inherited feature strings because
|
* This information is stored in an array of inherited feature strings because
|
||||||
* we care only to know when they are denied.
|
* we care only to know when they are denied.
|
||||||
*
|
*
|
||||||
@@ -72,19 +72,17 @@ public:
|
|||||||
|
|
||||||
explicit FeaturePolicy(nsINode* aNode);
|
explicit FeaturePolicy(nsINode* aNode);
|
||||||
|
|
||||||
// A FeaturePolicy must have a default origin, if not in a sandboxed context.
|
// A FeaturePolicy must have a default origin.
|
||||||
// This method must be called before any other exposed WebIDL method or before
|
// This method must be called before any other exposed WebIDL method or before
|
||||||
// checking if a feature is allowed.
|
// checking if a feature is allowed.
|
||||||
void
|
void
|
||||||
SetDefaultOrigin(const nsAString& aOrigin)
|
SetDefaultOrigin(nsIPrincipal* aPrincipal)
|
||||||
{
|
{
|
||||||
// aOrigin can be an empty string if this is a opaque origin.
|
mDefaultOrigin = aPrincipal;
|
||||||
mDefaultOrigin = aOrigin;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const nsAString& DefaultOrigin() const
|
nsIPrincipal* DefaultOrigin() const
|
||||||
{
|
{
|
||||||
// Returns an empty string if this is an opaque origin.
|
|
||||||
return mDefaultOrigin;
|
return mDefaultOrigin;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -97,9 +95,8 @@ public:
|
|||||||
void
|
void
|
||||||
SetDeclaredPolicy(nsIDocument* aDocument,
|
SetDeclaredPolicy(nsIDocument* aDocument,
|
||||||
const nsAString& aPolicyString,
|
const nsAString& aPolicyString,
|
||||||
const nsAString& aSelfOrigin,
|
nsIPrincipal* aSelfOrigin,
|
||||||
const nsAString& aSrcOrigin,
|
nsIPrincipal* aSrcOrigin);
|
||||||
bool aSrcEnabled);
|
|
||||||
|
|
||||||
// This method creates a policy for aFeatureName allowing it to '*' if it
|
// This method creates a policy for aFeatureName allowing it to '*' if it
|
||||||
// doesn't exist yet. It's used by HTMLIFrameElement to enable features by
|
// doesn't exist yet. It's used by HTMLIFrameElement to enable features by
|
||||||
@@ -140,9 +137,12 @@ public:
|
|||||||
private:
|
private:
|
||||||
~FeaturePolicy() = default;
|
~FeaturePolicy() = default;
|
||||||
|
|
||||||
|
// This method returns true if the aFeatureName is allowed for aOrigin,
|
||||||
|
// following the feature-policy directives. See the comment at the top of this
|
||||||
|
// file.
|
||||||
bool
|
bool
|
||||||
AllowsFeatureInternal(const nsAString& aFeatureName,
|
AllowsFeatureInternal(const nsAString& aFeatureName,
|
||||||
const nsAString& aOrigin) const;
|
nsIPrincipal* aOrigin) const;
|
||||||
|
|
||||||
// Inherits a single denied feature from the parent context.
|
// Inherits a single denied feature from the parent context.
|
||||||
void
|
void
|
||||||
@@ -151,6 +151,7 @@ private:
|
|||||||
bool
|
bool
|
||||||
HasInheritedDeniedFeature(const nsAString& aFeatureName) const;
|
HasInheritedDeniedFeature(const nsAString& aFeatureName) const;
|
||||||
|
|
||||||
|
// This returns true if we have a declared feature policy for aFeatureName.
|
||||||
bool
|
bool
|
||||||
HasDeclaredFeature(const nsAString& aFeatureName) const;
|
HasDeclaredFeature(const nsAString& aFeatureName) const;
|
||||||
|
|
||||||
@@ -163,7 +164,7 @@ private:
|
|||||||
// Feature policy for the current context.
|
// Feature policy for the current context.
|
||||||
nsTArray<Feature> mFeatures;
|
nsTArray<Feature> mFeatures;
|
||||||
|
|
||||||
nsString mDefaultOrigin;
|
nsCOMPtr<nsIPrincipal> mDefaultOrigin;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // dom namespace
|
} // dom namespace
|
||||||
|
|||||||
@@ -13,8 +13,8 @@
|
|||||||
#include "nsIURI.h"
|
#include "nsIURI.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
|
|
||||||
using namespace mozilla;
|
namespace mozilla {
|
||||||
using namespace mozilla::dom;
|
namespace dom {
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
||||||
@@ -65,11 +65,12 @@ ReportToConsoleInvalidAllowValue(nsIDocument* aDocument,
|
|||||||
/* static */ bool
|
/* static */ bool
|
||||||
FeaturePolicyParser::ParseString(const nsAString& aPolicy,
|
FeaturePolicyParser::ParseString(const nsAString& aPolicy,
|
||||||
nsIDocument* aDocument,
|
nsIDocument* aDocument,
|
||||||
const nsAString& aSelfOrigin,
|
nsIPrincipal* aSelfOrigin,
|
||||||
const nsAString& aSrcOrigin,
|
nsIPrincipal* aSrcOrigin,
|
||||||
bool aSrcEnabled,
|
|
||||||
nsTArray<Feature>& aParsedFeatures)
|
nsTArray<Feature>& aParsedFeatures)
|
||||||
{
|
{
|
||||||
|
MOZ_ASSERT(aSelfOrigin);
|
||||||
|
|
||||||
nsTArray<nsTArray<nsString>> tokens;
|
nsTArray<nsTArray<nsString>> tokens;
|
||||||
PolicyTokenizer::tokenizePolicy(aPolicy, tokens);
|
PolicyTokenizer::tokenizePolicy(aPolicy, tokens);
|
||||||
|
|
||||||
@@ -88,9 +89,8 @@ FeaturePolicyParser::ParseString(const nsAString& aPolicy,
|
|||||||
Feature feature(featureTokens[0]);
|
Feature feature(featureTokens[0]);
|
||||||
|
|
||||||
if (featureTokens.Length() == 1) {
|
if (featureTokens.Length() == 1) {
|
||||||
if (aSrcEnabled) {
|
if (aSrcOrigin) {
|
||||||
// Note that this src origin can be empty if opaque.
|
feature.AppendToAllowList(aSrcOrigin);
|
||||||
feature.AppendOriginToWhiteList(aSrcOrigin);
|
|
||||||
} else {
|
} else {
|
||||||
ReportToConsoleInvalidEmptyAllowValue(aDocument, featureTokens[0]);
|
ReportToConsoleInvalidEmptyAllowValue(aDocument, featureTokens[0]);
|
||||||
continue;
|
continue;
|
||||||
@@ -110,18 +110,12 @@ FeaturePolicyParser::ParseString(const nsAString& aPolicy,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (curVal.LowerCaseEqualsASCII("'self'")) {
|
if (curVal.LowerCaseEqualsASCII("'self'")) {
|
||||||
// Opaque origins are passed as empty string.
|
feature.AppendToAllowList(aSelfOrigin);
|
||||||
if (!aSelfOrigin.IsEmpty()) {
|
|
||||||
feature.AppendOriginToWhiteList(aSelfOrigin);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (aSrcEnabled && curVal.LowerCaseEqualsASCII("'src'")) {
|
if (aSrcOrigin && curVal.LowerCaseEqualsASCII("'src'")) {
|
||||||
// Opaque origins are passed as empty string.
|
feature.AppendToAllowList(aSrcOrigin);
|
||||||
if (!aSrcOrigin.IsEmpty()) {
|
|
||||||
feature.AppendOriginToWhiteList(aSrcOrigin);
|
|
||||||
}
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -132,14 +126,15 @@ FeaturePolicyParser::ParseString(const nsAString& aPolicy,
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
nsAutoString origin;
|
nsCOMPtr<nsIPrincipal> origin =
|
||||||
rv = nsContentUtils::GetUTFOrigin(uri, origin);
|
BasePrincipal::CreateCodebasePrincipal(uri,
|
||||||
if (NS_WARN_IF(NS_FAILED(rv))) {
|
BasePrincipal::Cast(aSelfOrigin)->OriginAttributesRef());
|
||||||
|
if (NS_WARN_IF(!origin)) {
|
||||||
ReportToConsoleInvalidAllowValue(aDocument, curVal);
|
ReportToConsoleInvalidAllowValue(aDocument, curVal);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
feature.AppendOriginToWhiteList(origin);
|
feature.AppendToAllowList(origin);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -160,3 +155,6 @@ FeaturePolicyParser::ParseString(const nsAString& aPolicy,
|
|||||||
aParsedFeatures.SwapElements(parsedFeatures);
|
aParsedFeatures.SwapElements(parsedFeatures);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
|
|||||||
@@ -10,7 +10,7 @@
|
|||||||
#include "nsString.h"
|
#include "nsString.h"
|
||||||
|
|
||||||
class nsIDocument;
|
class nsIDocument;
|
||||||
class nsIURI;
|
class nsIPrincipal;
|
||||||
|
|
||||||
namespace mozilla {
|
namespace mozilla {
|
||||||
namespace dom {
|
namespace dom {
|
||||||
@@ -20,14 +20,13 @@ class Feature;
|
|||||||
class FeaturePolicyParser final
|
class FeaturePolicyParser final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
// aSelfOrigin must not be empty. if aSrcOrigin is empty, the parsing will not
|
// aSelfOrigin must not be null. if aSrcOrigin is null, the parsing will not
|
||||||
// support 'src' as valid allow directive value.
|
// support 'src' as valid allow directive value.
|
||||||
static bool
|
static bool
|
||||||
ParseString(const nsAString& aPolicy,
|
ParseString(const nsAString& aPolicy,
|
||||||
nsIDocument* aDocument,
|
nsIDocument* aDocument,
|
||||||
const nsAString& aSelfOrigin,
|
nsIPrincipal* aSelfOrigin,
|
||||||
const nsAString& aSrcOrigin,
|
nsIPrincipal* aSrcOrigin,
|
||||||
bool aSrcEnabled,
|
|
||||||
nsTArray<Feature>& aParsedFeatures);
|
nsTArray<Feature>& aParsedFeatures);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -9,15 +9,12 @@
|
|||||||
#include "mozilla/StaticPrefs.h"
|
#include "mozilla/StaticPrefs.h"
|
||||||
#include "nsIDocument.h"
|
#include "nsIDocument.h"
|
||||||
|
|
||||||
using namespace mozilla::dom;
|
namespace mozilla {
|
||||||
|
namespace dom {
|
||||||
|
|
||||||
struct FeatureMap {
|
struct FeatureMap {
|
||||||
const char* mFeatureName;
|
const char* mFeatureName;
|
||||||
|
FeaturePolicyUtils::FeaturePolicyValue mDefaultAllowList;
|
||||||
enum {
|
|
||||||
eAll,
|
|
||||||
eSelf,
|
|
||||||
} mDefaultAllowList;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -25,17 +22,17 @@ struct FeatureMap {
|
|||||||
* DOM Security peer!
|
* DOM Security peer!
|
||||||
*/
|
*/
|
||||||
static FeatureMap sSupportedFeatures[] = {
|
static FeatureMap sSupportedFeatures[] = {
|
||||||
{ "autoplay", FeatureMap::eAll },
|
{ "autoplay", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
{ "camera", FeatureMap::eAll },
|
{ "camera", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
{ "encrypted-media", FeatureMap::eAll },
|
{ "encrypted-media", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
{ "fullscreen", FeatureMap::eAll },
|
{ "fullscreen", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
{ "geolocation", FeatureMap::eAll },
|
{ "geolocation", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
{ "microphone", FeatureMap::eAll },
|
{ "microphone", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
{ "midi", FeatureMap::eAll },
|
{ "midi", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
{ "payment", FeatureMap::eAll },
|
{ "payment", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
// TODO: not supported yet!!!
|
// TODO: not supported yet!!!
|
||||||
{ "speaker", FeatureMap::eAll },
|
{ "speaker", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
{ "vr", FeatureMap::eAll },
|
{ "vr", FeaturePolicyUtils::FeaturePolicyValue::eAll },
|
||||||
};
|
};
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
@@ -59,51 +56,17 @@ FeaturePolicyUtils::ForEachFeature(const std::function<void(const char*)>& aCall
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ void
|
/* static */ FeaturePolicyUtils::FeaturePolicyValue
|
||||||
FeaturePolicyUtils::DefaultAllowListFeature(const nsAString& aFeatureName,
|
FeaturePolicyUtils::DefaultAllowListFeature(const nsAString& aFeatureName)
|
||||||
const nsAString& aDefaultOrigin,
|
|
||||||
nsAString& aDefaultAllowList)
|
|
||||||
{
|
{
|
||||||
uint32_t numFeatures = (sizeof(sSupportedFeatures) / sizeof(sSupportedFeatures[0]));
|
uint32_t numFeatures = (sizeof(sSupportedFeatures) / sizeof(sSupportedFeatures[0]));
|
||||||
for (uint32_t i = 0; i < numFeatures; ++i) {
|
for (uint32_t i = 0; i < numFeatures; ++i) {
|
||||||
if (aFeatureName.LowerCaseEqualsASCII(sSupportedFeatures[i].mFeatureName)) {
|
if (aFeatureName.LowerCaseEqualsASCII(sSupportedFeatures[i].mFeatureName)) {
|
||||||
switch (sSupportedFeatures[i].mDefaultAllowList) {
|
return sSupportedFeatures[i].mDefaultAllowList;
|
||||||
case FeatureMap::eAll:
|
|
||||||
aDefaultAllowList.AppendASCII("*");
|
|
||||||
return;
|
|
||||||
|
|
||||||
case FeatureMap::eSelf:
|
|
||||||
aDefaultAllowList = aDefaultOrigin;
|
|
||||||
return;
|
|
||||||
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Unknown default value");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool
|
return FeaturePolicyValue::eNone;
|
||||||
FeaturePolicyUtils::AllowDefaultFeature(const nsAString& aFeatureName,
|
|
||||||
const nsAString& aDefaultOrigin,
|
|
||||||
const nsAString& aOrigin)
|
|
||||||
{
|
|
||||||
uint32_t numFeatures = (sizeof(sSupportedFeatures) / sizeof(sSupportedFeatures[0]));
|
|
||||||
for (uint32_t i = 0; i < numFeatures; ++i) {
|
|
||||||
if (aFeatureName.LowerCaseEqualsASCII(sSupportedFeatures[i].mFeatureName)) {
|
|
||||||
switch (sSupportedFeatures[i].mDefaultAllowList) {
|
|
||||||
case FeatureMap::eAll:
|
|
||||||
return true;
|
|
||||||
case FeatureMap::eSelf:
|
|
||||||
return aDefaultOrigin == aOrigin;
|
|
||||||
default:
|
|
||||||
MOZ_CRASH("Unknown default value");
|
|
||||||
}
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static */ bool
|
/* static */ bool
|
||||||
@@ -125,3 +88,6 @@ FeaturePolicyUtils::IsFeatureAllowed(nsIDocument* aDocument,
|
|||||||
|
|
||||||
return policy->AllowsFeatureInternal(aFeatureName, policy->DefaultOrigin());
|
return policy->AllowsFeatureInternal(aFeatureName, policy->DefaultOrigin());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
} // dom namespace
|
||||||
|
} // mozilla namespace
|
||||||
|
|||||||
@@ -18,25 +18,36 @@ namespace dom {
|
|||||||
class FeaturePolicyUtils final
|
class FeaturePolicyUtils final
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
enum FeaturePolicyValue
|
||||||
|
{
|
||||||
|
// Feature always allowed.
|
||||||
|
eAll,
|
||||||
|
|
||||||
|
// Feature allowed for documents that are same-origin with this one.
|
||||||
|
eSelf,
|
||||||
|
|
||||||
|
// Feature denied.
|
||||||
|
eNone,
|
||||||
|
};
|
||||||
|
|
||||||
|
// This method returns true if aFeatureName is allowed for aDocument.
|
||||||
|
// Use this method everywhere you need to check feature-policy directives.
|
||||||
static bool
|
static bool
|
||||||
IsFeatureAllowed(nsIDocument* aDocument,
|
IsFeatureAllowed(nsIDocument* aDocument,
|
||||||
const nsAString& aFeatureName);
|
const nsAString& aFeatureName);
|
||||||
|
|
||||||
|
// Returns true if aFeatureName is a known feature policy name.
|
||||||
static bool
|
static bool
|
||||||
IsSupportedFeature(const nsAString& aFeatureName);
|
IsSupportedFeature(const nsAString& aFeatureName);
|
||||||
|
|
||||||
|
// Runs aCallback for each known feature policy, with the feature name as
|
||||||
|
// argument.
|
||||||
static void
|
static void
|
||||||
ForEachFeature(const std::function<void(const char*)>& aCallback);
|
ForEachFeature(const std::function<void(const char*)>& aCallback);
|
||||||
|
|
||||||
static void
|
// Returns the default policy value for aFeatureName.
|
||||||
DefaultAllowListFeature(const nsAString& aFeatureName,
|
static FeaturePolicyValue
|
||||||
const nsAString& aDefaultOrigin,
|
DefaultAllowListFeature(const nsAString& aFeatureName);
|
||||||
nsAString& aDefaultAllowList);
|
|
||||||
|
|
||||||
static bool
|
|
||||||
AllowDefaultFeature(const nsAString& aFeatureName,
|
|
||||||
const nsAString& aDefaultOrigin,
|
|
||||||
const nsAString& aOrigin);
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // dom namespace
|
} // dom namespace
|
||||||
|
|||||||
@@ -5,27 +5,30 @@
|
|||||||
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
* You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||||
|
|
||||||
#include "gtest/gtest.h"
|
#include "gtest/gtest.h"
|
||||||
|
#include "mozilla/BasePrincipal.h"
|
||||||
#include "mozilla/dom/Feature.h"
|
#include "mozilla/dom/Feature.h"
|
||||||
#include "mozilla/dom/FeaturePolicyParser.h"
|
#include "mozilla/dom/FeaturePolicyParser.h"
|
||||||
#include "nsNetUtil.h"
|
#include "nsNetUtil.h"
|
||||||
#include "nsTArray.h"
|
#include "nsTArray.h"
|
||||||
|
|
||||||
|
using namespace mozilla;
|
||||||
using namespace mozilla::dom;
|
using namespace mozilla::dom;
|
||||||
|
|
||||||
#define URL_SELF NS_LITERAL_STRING("https://example.com")
|
#define URL_SELF NS_LITERAL_CSTRING("https://example.com")
|
||||||
#define URL_EXAMPLE_COM NS_LITERAL_STRING("http://example.com")
|
#define URL_EXAMPLE_COM NS_LITERAL_CSTRING("http://example.com")
|
||||||
#define URL_EXAMPLE_NET NS_LITERAL_STRING("http://example.net")
|
#define URL_EXAMPLE_NET NS_LITERAL_CSTRING("http://example.net")
|
||||||
|
|
||||||
void
|
void
|
||||||
CheckParser(const nsAString& aInput, bool aExpectedResults,
|
CheckParser(const nsAString& aInput, bool aExpectedResults,
|
||||||
uint32_t aExpectedFeatures, nsTArray<Feature>& aParsedFeatures)
|
uint32_t aExpectedFeatures, nsTArray<Feature>& aParsedFeatures)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIPrincipal> principal =
|
||||||
|
mozilla::BasePrincipal::CreateCodebasePrincipal(URL_SELF);
|
||||||
nsTArray<Feature> parsedFeatures;
|
nsTArray<Feature> parsedFeatures;
|
||||||
ASSERT_TRUE(FeaturePolicyParser::ParseString(aInput,
|
ASSERT_TRUE(FeaturePolicyParser::ParseString(aInput,
|
||||||
nullptr,
|
nullptr,
|
||||||
URL_SELF,
|
principal,
|
||||||
EmptyString(),
|
principal,
|
||||||
true, // 'src' enabled
|
|
||||||
parsedFeatures) == aExpectedResults);
|
parsedFeatures) == aExpectedResults);
|
||||||
ASSERT_TRUE(parsedFeatures.Length() == aExpectedFeatures);
|
ASSERT_TRUE(parsedFeatures.Length() == aExpectedFeatures);
|
||||||
|
|
||||||
@@ -34,6 +37,13 @@ CheckParser(const nsAString& aInput, bool aExpectedResults,
|
|||||||
|
|
||||||
TEST(FeaturePolicyParser, Basic)
|
TEST(FeaturePolicyParser, Basic)
|
||||||
{
|
{
|
||||||
|
nsCOMPtr<nsIPrincipal> selfPrincipal =
|
||||||
|
mozilla::BasePrincipal::CreateCodebasePrincipal(URL_SELF);
|
||||||
|
nsCOMPtr<nsIPrincipal> exampleComPrincipal =
|
||||||
|
mozilla::BasePrincipal::CreateCodebasePrincipal(URL_EXAMPLE_COM);
|
||||||
|
nsCOMPtr<nsIPrincipal> exampleNetPrincipal =
|
||||||
|
mozilla::BasePrincipal::CreateCodebasePrincipal(URL_EXAMPLE_NET);
|
||||||
|
|
||||||
nsTArray<Feature> parsedFeatures;
|
nsTArray<Feature> parsedFeatures;
|
||||||
|
|
||||||
// Empty string is a valid policy.
|
// Empty string is a valid policy.
|
||||||
@@ -50,70 +60,70 @@ TEST(FeaturePolicyParser, Basic)
|
|||||||
// Existing feature with no allowed values
|
// Existing feature with no allowed values
|
||||||
CheckParser(NS_LITERAL_STRING("camera"), true, 1, parsedFeatures);
|
CheckParser(NS_LITERAL_STRING("camera"), true, 1, parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[0].HasAllowList());
|
||||||
|
|
||||||
// Some spaces.
|
// Some spaces.
|
||||||
CheckParser(NS_LITERAL_STRING(" camera "), true, 1, parsedFeatures);
|
CheckParser(NS_LITERAL_STRING(" camera "), true, 1, parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[0].HasAllowList());
|
||||||
|
|
||||||
// A random ;
|
// A random ;
|
||||||
CheckParser(NS_LITERAL_STRING("camera;"), true, 1, parsedFeatures);
|
CheckParser(NS_LITERAL_STRING("camera;"), true, 1, parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[0].HasAllowList());
|
||||||
|
|
||||||
// Another random ;
|
// Another random ;
|
||||||
CheckParser(NS_LITERAL_STRING(";camera;"), true, 1, parsedFeatures);
|
CheckParser(NS_LITERAL_STRING(";camera;"), true, 1, parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[0].HasAllowList());
|
||||||
|
|
||||||
// 2 features
|
// 2 features
|
||||||
CheckParser(NS_LITERAL_STRING("camera;microphone"), true, 2, parsedFeatures);
|
CheckParser(NS_LITERAL_STRING("camera;microphone"), true, 2, parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[0].HasAllowList());
|
||||||
ASSERT_TRUE(parsedFeatures[1].Name().Equals(NS_LITERAL_STRING("microphone")));
|
ASSERT_TRUE(parsedFeatures[1].Name().Equals(NS_LITERAL_STRING("microphone")));
|
||||||
ASSERT_TRUE(parsedFeatures[1].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[1].HasAllowList());
|
||||||
|
|
||||||
// 2 features with spaces
|
// 2 features with spaces
|
||||||
CheckParser(NS_LITERAL_STRING(" camera ; microphone "), true, 2,
|
CheckParser(NS_LITERAL_STRING(" camera ; microphone "), true, 2,
|
||||||
parsedFeatures);
|
parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[0].HasAllowList());
|
||||||
ASSERT_TRUE(parsedFeatures[1].Name().Equals(NS_LITERAL_STRING("microphone")));
|
ASSERT_TRUE(parsedFeatures[1].Name().Equals(NS_LITERAL_STRING("microphone")));
|
||||||
ASSERT_TRUE(parsedFeatures[1].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[1].HasAllowList());
|
||||||
|
|
||||||
// 3 features, but only 2 exist.
|
// 3 features, but only 2 exist.
|
||||||
CheckParser(NS_LITERAL_STRING("camera;microphone;foobar"), true, 2,
|
CheckParser(NS_LITERAL_STRING("camera;microphone;foobar"), true, 2,
|
||||||
parsedFeatures);
|
parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[0].HasAllowList());
|
||||||
ASSERT_TRUE(parsedFeatures[1].Name().Equals(NS_LITERAL_STRING("microphone")));
|
ASSERT_TRUE(parsedFeatures[1].Name().Equals(NS_LITERAL_STRING("microphone")));
|
||||||
ASSERT_TRUE(parsedFeatures[1].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[1].HasAllowList());
|
||||||
|
|
||||||
// Multiple spaces around the value
|
// Multiple spaces around the value
|
||||||
CheckParser(NS_LITERAL_STRING("camera 'self'"), true, 1,
|
CheckParser(NS_LITERAL_STRING("camera 'self'"), true, 1,
|
||||||
parsedFeatures);
|
parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_SELF));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
|
||||||
|
|
||||||
// Multiple spaces around the value
|
// Multiple spaces around the value
|
||||||
CheckParser(NS_LITERAL_STRING("camera 'self' "), true, 1,
|
CheckParser(NS_LITERAL_STRING("camera 'self' "), true, 1,
|
||||||
parsedFeatures);
|
parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_SELF));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
|
||||||
|
|
||||||
// No final '
|
// No final '
|
||||||
CheckParser(NS_LITERAL_STRING("camera 'self"), true, 1,
|
CheckParser(NS_LITERAL_STRING("camera 'self"), true, 1,
|
||||||
parsedFeatures);
|
parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].IsWhiteList());
|
ASSERT_TRUE(parsedFeatures[0].HasAllowList());
|
||||||
ASSERT_TRUE(!parsedFeatures[0].WhiteListContains(URL_SELF));
|
ASSERT_TRUE(!parsedFeatures[0].AllowListContains(selfPrincipal));
|
||||||
|
|
||||||
// Lowercase/Uppercase
|
// Lowercase/Uppercase
|
||||||
CheckParser(NS_LITERAL_STRING("camera 'selF'"), true, 1,
|
CheckParser(NS_LITERAL_STRING("camera 'selF'"), true, 1,
|
||||||
parsedFeatures);
|
parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_SELF));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
|
||||||
|
|
||||||
// Lowercase/Uppercase
|
// Lowercase/Uppercase
|
||||||
CheckParser(NS_LITERAL_STRING("camera * 'self' none' a.com 123"), true, 1,
|
CheckParser(NS_LITERAL_STRING("camera * 'self' none' a.com 123"), true, 1,
|
||||||
@@ -136,23 +146,23 @@ TEST(FeaturePolicyParser, Basic)
|
|||||||
// 'self'
|
// 'self'
|
||||||
CheckParser(NS_LITERAL_STRING("camera 'self'"), true, 1, parsedFeatures);
|
CheckParser(NS_LITERAL_STRING("camera 'self'"), true, 1, parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_SELF));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
|
||||||
|
|
||||||
// A couple of URLs
|
// A couple of URLs
|
||||||
CheckParser(NS_LITERAL_STRING("camera http://example.com http://example.net"), true, 1,
|
CheckParser(NS_LITERAL_STRING("camera http://example.com http://example.net"), true, 1,
|
||||||
parsedFeatures);
|
parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(!parsedFeatures[0].WhiteListContains(URL_SELF));
|
ASSERT_TRUE(!parsedFeatures[0].AllowListContains(selfPrincipal));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_EXAMPLE_COM));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(exampleComPrincipal));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_EXAMPLE_NET));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(exampleNetPrincipal));
|
||||||
|
|
||||||
// A couple of URLs + self
|
// A couple of URLs + self
|
||||||
CheckParser(NS_LITERAL_STRING("camera http://example.com 'self' http://example.net"), true, 1,
|
CheckParser(NS_LITERAL_STRING("camera http://example.com 'self' http://example.net"), true, 1,
|
||||||
parsedFeatures);
|
parsedFeatures);
|
||||||
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
ASSERT_TRUE(parsedFeatures[0].Name().Equals(NS_LITERAL_STRING("camera")));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_SELF));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(selfPrincipal));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_EXAMPLE_COM));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(exampleComPrincipal));
|
||||||
ASSERT_TRUE(parsedFeatures[0].WhiteListContains(URL_EXAMPLE_NET));
|
ASSERT_TRUE(parsedFeatures[0].AllowListContains(exampleNetPrincipal));
|
||||||
|
|
||||||
// A couple of URLs but then *
|
// A couple of URLs but then *
|
||||||
CheckParser(NS_LITERAL_STRING("camera http://example.com 'self' http://example.net *"), true, 1,
|
CheckParser(NS_LITERAL_STRING("camera http://example.com 'self' http://example.net *"), true, 1,
|
||||||
|
|||||||
@@ -31,4 +31,3 @@
|
|||||||
|
|
||||||
[Test frame policy on cross origin iframe with allow = "'self' https://www.web-platform.test:8443 https://www.example.com" and allowfullscreen.]
|
[Test frame policy on cross origin iframe with allow = "'self' https://www.web-platform.test:8443 https://www.example.com" and allowfullscreen.]
|
||||||
expected: FAIL
|
expected: FAIL
|
||||||
|
|
||||||
|
|||||||
@@ -10,11 +10,12 @@
|
|||||||
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
|
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
|
||||||
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
|
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
|
||||||
var cross_origin_src = cross_origin + same_origin_src;
|
var cross_origin_src = cross_origin + same_origin_src;
|
||||||
|
var data_src = 'data:text/html,<h1>data: URL</h1>';
|
||||||
var policies = [
|
var policies = [
|
||||||
{allow: "*", sameOriginTestExpect: true, crossOriginTestExpect: true},
|
{allow: "*", sameOriginTestExpect: true, crossOriginTestExpect: true, dataOriginTestExpect: true},
|
||||||
{allow: "'self'", sameOriginTestExpect: true, crossOriginTestExpect: false},
|
{allow: "'self'", sameOriginTestExpect: true, crossOriginTestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'none'", sameOriginTestExpect: false, crossOriginTestExpect: false},
|
{allow: "'none'", sameOriginTestExpect: false, crossOriginTestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'self' " + cross_origin + " https://www.example.com", sameOriginTestExpect: true, crossOriginTestExpect: true}];
|
{allow: "'self' " + cross_origin + " https://www.example.com", sameOriginTestExpect: true, crossOriginTestExpect: true, dataOriginTestExpect: false}];
|
||||||
var pipe_front = '?pipe=sub|header(Feature-Policy,fullscreen ';
|
var pipe_front = '?pipe=sub|header(Feature-Policy,fullscreen ';
|
||||||
var pipe_end = ';)';
|
var pipe_end = ';)';
|
||||||
var header_policies = ["*", "'self'", "'none'"];
|
var header_policies = ["*", "'self'", "'none'"];
|
||||||
@@ -22,24 +23,58 @@
|
|||||||
// Test that frame.policy inherits from parent's header policy when allow
|
// Test that frame.policy inherits from parent's header policy when allow
|
||||||
// attribute is not specified.
|
// attribute is not specified.
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', same_origin_src, true);
|
test_frame_policy('fullscreen', same_origin_src, undefined, true);
|
||||||
}, 'Test frame policy on same origin iframe inherit from header policy.');
|
}, 'Test frame policy on same origin iframe inherit from header policy.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', cross_origin_src, true);
|
test_frame_policy('fullscreen', cross_origin_src, undefined, true);
|
||||||
}, 'Test frame policy on cross origin iframe inherit from header policy.');
|
}, 'Test frame policy on cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', undefined, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', same_origin_src, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc+ same origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', cross_origin_src, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc+ cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', data_src, undefined, true);
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe inherit from header policy.');
|
||||||
|
|
||||||
// Test frame policy with allow attribute set to be one of the policies above.
|
// Test frame policy with allow attribute set to be one of the policies above.
|
||||||
for (var i = 0; i < policies.length; i++) {
|
for (var i = 0; i < policies.length; i++) {
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, policies[i].sameOriginTestExpect,
|
'fullscreen', same_origin_src, undefined,
|
||||||
|
policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, policies[i].crossOriginTestExpect,
|
'fullscreen', cross_origin_src, undefined,
|
||||||
|
policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, policies[i].dataOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the header policy of the iframe document does not change the
|
// Test that the header policy of the iframe document does not change the
|
||||||
@@ -50,7 +85,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
same_origin_src + pipe_front + header_policies[j] + pipe_end,
|
same_origin_src + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].sameOriginTestExpect,
|
undefined, policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -58,7 +93,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
cross_origin_src + pipe_front + header_policies[j] + pipe_end,
|
cross_origin_src + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].crossOriginTestExpect,
|
undefined, policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -69,16 +104,42 @@
|
|||||||
for (var i = 0; i < policies.length; i++) {
|
for (var i = 0; i < policies.length; i++) {
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, policies[i].sameOriginTestExpect,
|
'fullscreen', same_origin_src, undefined,
|
||||||
|
policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, policies[i].crossOriginTestExpect,
|
'fullscreen', cross_origin_src, undefined,
|
||||||
|
policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, policies[i].dataOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -10,11 +10,12 @@
|
|||||||
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
|
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
|
||||||
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
|
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
|
||||||
var cross_origin_src = cross_origin + same_origin_src;
|
var cross_origin_src = cross_origin + same_origin_src;
|
||||||
|
var data_src = 'data:text/html,<h1>data: URL</h1>';
|
||||||
var policies = [
|
var policies = [
|
||||||
{allow: "*", sameOriginTestExpect: true, crossOriginTestExpect: true},
|
{allow: "*", sameOriginTestExpect: true, crossOriginTestExpect: true, dataOriginTestExpect: false},
|
||||||
{allow: "'self'", sameOriginTestExpect: true, crossOriginTestExpect: false},
|
{allow: "'self'", sameOriginTestExpect: true, crossOriginTestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'none'", sameOriginTestExpect: false, crossOriginTestExpect: false},
|
{allow: "'none'", sameOriginTestExpect: false, crossOriginTestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'self' " + cross_origin + " https://www.example.com", sameOriginTestExpect: true, crossOriginTestExpect: true}];
|
{allow: "'self' " + cross_origin + " https://www.example.com", sameOriginTestExpect: true, crossOriginTestExpect: true, dataOriginTestExpect: false}];
|
||||||
var pipe_front = '?pipe=sub|header(Feature-Policy,fullscreen ';
|
var pipe_front = '?pipe=sub|header(Feature-Policy,fullscreen ';
|
||||||
var pipe_end = ';)';
|
var pipe_end = ';)';
|
||||||
var header_policies = ["*", "'self'", "'none'"];
|
var header_policies = ["*", "'self'", "'none'"];
|
||||||
@@ -22,42 +23,92 @@
|
|||||||
// Test that frame.policy inherits from parent's header policy when allow
|
// Test that frame.policy inherits from parent's header policy when allow
|
||||||
// attribute is not specified.
|
// attribute is not specified.
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', same_origin_src, true);
|
test_frame_policy('fullscreen', same_origin_src, undefined, true);
|
||||||
}, 'Test frame policy on same origin iframe inherit from header policy.');
|
}, 'Test frame policy on same origin iframe inherit from header policy.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', cross_origin_src, false);
|
test_frame_policy('fullscreen', cross_origin_src, undefined, false);
|
||||||
}, 'Test frame policy on cross origin iframe inherit from header policy.');
|
}, 'Test frame policy on cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', undefined, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', same_origin_src, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', cross_origin_src, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', data_src, undefined, false);
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe inherit from header policy.');
|
||||||
|
|
||||||
// Test that frame policy can be used for sandboxed frames
|
// Test that frame policy can be used for sandboxed frames
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, false, undefined, false, true);
|
'fullscreen', same_origin_src, undefined, false, undefined, false, true);
|
||||||
}, 'Test frame policy on sandboxed iframe with no allow attribute.');
|
}, 'Test frame policy on sandboxed iframe with no allow attribute.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, true, 'fullscreen', false, true);
|
'fullscreen', same_origin_src, undefined, true, 'fullscreen', false, true);
|
||||||
}, 'Test frame policy on sandboxed iframe with allow="fullscreen".');
|
}, 'Test frame policy on sandboxed iframe with allow="fullscreen".');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, true, 'fullscreen \'src\'', false, true);
|
'fullscreen', same_origin_src, undefined, true, 'fullscreen \'src\'', false, true);
|
||||||
}, 'Test frame policy on sandboxed iframe with allow="fullscreen \'src\'".');
|
}, 'Test frame policy on sandboxed iframe with allow="fullscreen \'src\'".');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, false, 'fullscreen ' + cross_origin, false, true);
|
'fullscreen', cross_origin_src, undefined, false, 'fullscreen ' + cross_origin, false, true);
|
||||||
}, 'Test frame policy on sandboxed iframe with allow="fullscreen ' + cross_origin + '".');
|
}, 'Test frame policy on sandboxed iframe with allow="fullscreen ' + cross_origin + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, true, 'fullscreen', false, true);
|
||||||
|
}, 'Test frame policy on srcdoc sandboxed iframe with allow="fullscreen".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, true, 'fullscreen', false, true);
|
||||||
|
}, 'Test frame policy on srcdoc + same origin sandboxed iframe with allow="fullscreen".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, true, 'fullscreen', false, true);
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin sandboxed iframe with allow="fullscreen".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, false, 'fullscreen ' + cross_origin, false, true);
|
||||||
|
}, 'Test frame policy on sandboxed srcdoc iframe with allow="fullscreen ' + cross_origin + '".');
|
||||||
|
|
||||||
// Test frame policy with allow attribute set to be one of the policies above.
|
// Test frame policy with allow attribute set to be one of the policies above.
|
||||||
for (var i = 0; i < policies.length; i++) {
|
for (var i = 0; i < policies.length; i++) {
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, policies[i].sameOriginTestExpect,
|
'fullscreen', same_origin_src, undefined,
|
||||||
|
policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, policies[i].crossOriginTestExpect,
|
'fullscreen', cross_origin_src, undefined,
|
||||||
|
policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, policies[i].dataOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on data: URL origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the header policy of the iframe document does not change the
|
// Test that the header policy of the iframe document does not change the
|
||||||
@@ -68,7 +119,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
same_origin_src + pipe_front + header_policies[j] + pipe_end,
|
same_origin_src + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].sameOriginTestExpect,
|
undefined, policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -76,7 +127,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
cross_origin_src + pipe_front + header_policies[j] + pipe_end,
|
cross_origin_src + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].crossOriginTestExpect,
|
undefined, policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -87,16 +138,42 @@
|
|||||||
for (var i = 0; i < policies.length; i++) {
|
for (var i = 0; i < policies.length; i++) {
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, policies[i].sameOriginTestExpect,
|
'fullscreen', same_origin_src, undefined,
|
||||||
|
policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, policies[i].crossOriginTestExpect,
|
'fullscreen', cross_origin_src, undefined,
|
||||||
|
policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, policies[i].dataOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on data: URL origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -12,12 +12,13 @@
|
|||||||
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
|
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
|
||||||
var cross_origin_src = cross_origin + same_origin_src;
|
var cross_origin_src = cross_origin + same_origin_src;
|
||||||
var cross_origin_src1 = cross_origin1 + same_origin_src;
|
var cross_origin_src1 = cross_origin1 + same_origin_src;
|
||||||
|
var data_src = 'data:text/html,<h1>data: URL</h1>';
|
||||||
// Test feature policy with same_origin_src and cross_origin_src.
|
// Test feature policy with same_origin_src and cross_origin_src.
|
||||||
var policies = [
|
var policies = [
|
||||||
{allow: "*", sameOriginTestExpect: true, crossOriginTestExpect: true, crossOrigin1TestExpect: true},
|
{allow: "*", sameOriginTestExpect: true, crossOriginTestExpect: true, crossOrigin1TestExpect: true, dataOriginTestExpect: false},
|
||||||
{allow: "'self'", sameOriginTestExpect: true, crossOriginTestExpect: false, crossOrigin1TestExpect: false},
|
{allow: "'self'", sameOriginTestExpect: true, crossOriginTestExpect: false, crossOrigin1TestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'none'", sameOriginTestExpect: false, crossOriginTestExpect: false, crossOrigin1TestExpect: false},
|
{allow: "'none'", sameOriginTestExpect: false, crossOriginTestExpect: false, crossOrigin1TestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'self' " + cross_origin + " https://www.example.com", sameOriginTestExpect: true, crossOriginTestExpect: true, crossOrigin1TestExpect: false}];
|
{allow: "'self' " + cross_origin + " https://www.example.com", sameOriginTestExpect: true, crossOriginTestExpect: true, crossOrigin1TestExpect: false, dataOriginTestExpect: false}];
|
||||||
var pipe_front = '?pipe=sub|header(Feature-Policy,fullscreen ';
|
var pipe_front = '?pipe=sub|header(Feature-Policy,fullscreen ';
|
||||||
var pipe_end = ';)';
|
var pipe_end = ';)';
|
||||||
var header_policies = ["*", "'self'", "'none'"];
|
var header_policies = ["*", "'self'", "'none'"];
|
||||||
@@ -25,32 +26,75 @@
|
|||||||
// Test that frame.policy inherits from parent's header policy when allow
|
// Test that frame.policy inherits from parent's header policy when allow
|
||||||
// attribute is not specified.
|
// attribute is not specified.
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', same_origin_src, true);
|
test_frame_policy('fullscreen', same_origin_src, undefined, true);
|
||||||
}, 'Test frame policy on same origin iframe inherit from header policy.');
|
}, 'Test frame policy on same origin iframe inherit from header policy.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', cross_origin_src, true);
|
test_frame_policy('fullscreen', cross_origin_src, undefined, true);
|
||||||
}, 'Test frame policy on cross origin iframe inherit from header policy.');
|
}, 'Test frame policy on cross origin iframe inherit from header policy.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', cross_origin_src1, false);
|
test_frame_policy('fullscreen', cross_origin_src1, undefined, false);
|
||||||
}, 'Test frame policy on another cross origin iframe inherit from header policy.');
|
}, 'Test frame policy on another cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', undefined, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', same_origin_src, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', cross_origin_src, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', cross_origin_src1, true, true);
|
||||||
|
}, 'Test frame policy on srcdoc + another cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', data_src, undefined, false);
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe inherit from header policy.');
|
||||||
|
|
||||||
// Test frame policy with allow attribute set to be one of the policies above.
|
// Test frame policy with allow attribute set to be one of the policies above.
|
||||||
for (var i = 0; i < policies.length; i++) {
|
for (var i = 0; i < policies.length; i++) {
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, policies[i].sameOriginTestExpect,
|
'fullscreen', same_origin_src, undefined,
|
||||||
|
policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, policies[i].crossOriginTestExpect,
|
'fullscreen', cross_origin_src, undefined,
|
||||||
|
policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src1, policies[i].crossOrigin1TestExpect,
|
'fullscreen', cross_origin_src1, undefined,
|
||||||
|
policies[i].crossOrigin1TestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on another cross origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on another cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src1, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + another cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, policies[i].dataOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the header policy of the iframe document does not change the
|
// Test that the header policy of the iframe document does not change the
|
||||||
@@ -61,7 +105,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
same_origin_src + pipe_front + header_policies[j] + pipe_end,
|
same_origin_src + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].sameOriginTestExpect,
|
undefined, policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -69,7 +113,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
cross_origin_src + pipe_front + header_policies[j] + pipe_end,
|
cross_origin_src + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].crossOriginTestExpect,
|
undefined, policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -77,7 +121,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
cross_origin_src1 + pipe_front + header_policies[j] + pipe_end,
|
cross_origin_src1 + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].crossOrigin1TestExpect,
|
undefined, policies[i].crossOrigin1TestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on another cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on another cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -88,22 +132,55 @@
|
|||||||
for (var i = 0; i < policies.length; i++) {
|
for (var i = 0; i < policies.length; i++) {
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, policies[i].sameOriginTestExpect,
|
'fullscreen', same_origin_src, undefined,
|
||||||
|
policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, policies[i].crossOriginTestExpect,
|
'fullscreen', cross_origin_src, undefined,
|
||||||
|
policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src1, policies[i].crossOrigin1TestExpect,
|
'fullscreen', cross_origin_src1, undefined,
|
||||||
|
policies[i].crossOrigin1TestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on another cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on another cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src1, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + another cross origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, policies[i].dataOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -10,11 +10,12 @@
|
|||||||
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
|
var cross_origin = 'https://{{domains[www]}}:{{ports[https][0]}}';
|
||||||
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
|
var same_origin_src = '/feature-policy/resources/feature-policy-allowedfeatures.html';
|
||||||
var cross_origin_src = cross_origin + same_origin_src;
|
var cross_origin_src = cross_origin + same_origin_src;
|
||||||
|
var data_src = 'data:text/html,<h1>data: URL</h1>';
|
||||||
var policies = [
|
var policies = [
|
||||||
{allow: "*", sameOriginTestExpect: false, crossOriginTestExpect: false},
|
{allow: "*", sameOriginTestExpect: false, crossOriginTestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'self'", sameOriginTestExpect: false, crossOriginTestExpect: false},
|
{allow: "'self'", sameOriginTestExpect: false, crossOriginTestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'none'", sameOriginTestExpect: false, crossOriginTestExpect: false},
|
{allow: "'none'", sameOriginTestExpect: false, crossOriginTestExpect: false, dataOriginTestExpect: false},
|
||||||
{allow: "'self' " + cross_origin + " https://www.example.com", sameOriginTestExpect: false, crossOriginTestExpect: false}];
|
{allow: "'self' " + cross_origin + " https://www.example.com", sameOriginTestExpect: false, crossOriginTestExpect: false, dataOriginTestExpect: false}];
|
||||||
var pipe_front = '?pipe=sub|header(Feature-Policy,fullscreen ';
|
var pipe_front = '?pipe=sub|header(Feature-Policy,fullscreen ';
|
||||||
var pipe_end = ';)';
|
var pipe_end = ';)';
|
||||||
var header_policies = ["*", "'self'", "'none'"];
|
var header_policies = ["*", "'self'", "'none'"];
|
||||||
@@ -22,24 +23,58 @@
|
|||||||
// Test that frame.policy inherits from parent's header policy when allow
|
// Test that frame.policy inherits from parent's header policy when allow
|
||||||
// attribute is not specified.
|
// attribute is not specified.
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', same_origin_src, false);
|
test_frame_policy('fullscreen', same_origin_src, undefined, false);
|
||||||
}, 'Test frame policy on same origin iframe inherit from header policy.');
|
}, 'Test frame policy on same origin iframe inherit from header policy.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy('fullscreen', cross_origin_src, false);
|
test_frame_policy('fullscreen', cross_origin_src, undefined, false);
|
||||||
}, 'Test frame policy on cross origin iframe inherit from header policy.');
|
}, 'Test frame policy on cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', undefined, true, false);
|
||||||
|
}, 'Test frame policy on srcdoc iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', same_origin_src, true, false);
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', cross_origin_src, true, false);
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe inherit from header policy.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy('fullscreen', data_src, undefined, false);
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe inherit from header policy.');
|
||||||
|
|
||||||
// Test frame policy with allow attribute set to be one of the policies above.
|
// Test frame policy with allow attribute set to be one of the policies above.
|
||||||
for (var i = 0; i < policies.length; i++) {
|
for (var i = 0; i < policies.length; i++) {
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, policies[i].sameOriginTestExpect,
|
'fullscreen', same_origin_src, undefined,
|
||||||
|
policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, policies[i].crossOriginTestExpect,
|
'fullscreen', cross_origin_src, undefined,
|
||||||
|
policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow + '".');
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, policies[i].dataOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe with allow = "' + policies[i].allow + '".');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Test that the header policy of the iframe document does not change the
|
// Test that the header policy of the iframe document does not change the
|
||||||
@@ -50,7 +85,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
same_origin_src + pipe_front + header_policies[j] + pipe_end,
|
same_origin_src + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].sameOriginTestExpect,
|
undefined, policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -58,7 +93,7 @@
|
|||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen',
|
'fullscreen',
|
||||||
cross_origin_src + pipe_front + header_policies[j] + pipe_end,
|
cross_origin_src + pipe_front + header_policies[j] + pipe_end,
|
||||||
policies[i].crossOriginTestExpect,
|
undefined, policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';');
|
'fullscreen ' + policies[i].allow + ';');
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
'" and header policy = "Feature-Policy: fullscreen ' + header_policies[j] + ';".');
|
||||||
@@ -69,16 +104,42 @@
|
|||||||
for (var i = 0; i < policies.length; i++) {
|
for (var i = 0; i < policies.length; i++) {
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', same_origin_src, policies[i].sameOriginTestExpect,
|
'fullscreen', same_origin_src, undefined,
|
||||||
|
policies[i].sameOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on same origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
test(function() {
|
test(function() {
|
||||||
test_frame_policy(
|
test_frame_policy(
|
||||||
'fullscreen', cross_origin_src, policies[i].crossOriginTestExpect,
|
'fullscreen', cross_origin_src, undefined,
|
||||||
|
policies[i].crossOriginTestExpect,
|
||||||
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
}, 'Test frame policy on cross origin iframe with allow = "' + policies[i].allow +
|
||||||
'" and allowfullscreen.');
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', undefined, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', same_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + same origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', cross_origin_src, true, policies[i].sameOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on srcdoc + cross origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
|
test(function() {
|
||||||
|
test_frame_policy(
|
||||||
|
'fullscreen', data_src, undefined, policies[i].dataOriginTestExpect,
|
||||||
|
'fullscreen ' + policies[i].allow + ';', /*allowfullscreen*/true);
|
||||||
|
}, 'Test frame policy on data: URL cross origin iframe with allow = "' + policies[i].allow +
|
||||||
|
'" and allowfullscreen.');
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
</body>
|
</body>
|
||||||
|
|||||||
@@ -396,14 +396,15 @@ function test_subframe_header_policy(
|
|||||||
// by iframe allow attribute.
|
// by iframe allow attribute.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// feature: feature name.
|
// feature: feature name.
|
||||||
// src: the URL to load in the frame.
|
// src: the URL to load in the frame. If undefined, the iframe will have a
|
||||||
|
// srcdoc="" attribute
|
||||||
// test_expect: boolean value of whether the feature should be allowed.
|
// test_expect: boolean value of whether the feature should be allowed.
|
||||||
// allow: optional, the allow attribute (container policy) of the iframe.
|
// allow: optional, the allow attribute (container policy) of the iframe.
|
||||||
// allowfullscreen: optional, boolean value of allowfullscreen attribute.
|
// allowfullscreen: optional, boolean value of allowfullscreen attribute.
|
||||||
// sandbox: optional boolean. If true, the frame will be sandboxed (with
|
// sandbox: optional boolean. If true, the frame will be sandboxed (with
|
||||||
// allow-scripts, so that tests can run in it.)
|
// allow-scripts, so that tests can run in it.)
|
||||||
function test_frame_policy(
|
function test_frame_policy(
|
||||||
feature, src, test_expect, allow, allowfullscreen, sandbox) {
|
feature, src, srcdoc, test_expect, allow, allowfullscreen, sandbox) {
|
||||||
let frame = document.createElement('iframe');
|
let frame = document.createElement('iframe');
|
||||||
document.body.appendChild(frame);
|
document.body.appendChild(frame);
|
||||||
// frame_policy should be dynamically updated as allow and allowfullscreen is
|
// frame_policy should be dynamically updated as allow and allowfullscreen is
|
||||||
@@ -418,7 +419,12 @@ function test_frame_policy(
|
|||||||
if (!!sandbox) {
|
if (!!sandbox) {
|
||||||
frame.setAttribute('sandbox', 'allow-scripts');
|
frame.setAttribute('sandbox', 'allow-scripts');
|
||||||
}
|
}
|
||||||
|
if (!!src) {
|
||||||
frame.src = src;
|
frame.src = src;
|
||||||
|
}
|
||||||
|
if (!!srcdoc) {
|
||||||
|
frame.srcdoc = "<h1>Hello world!</h1>";
|
||||||
|
}
|
||||||
if (test_expect) {
|
if (test_expect) {
|
||||||
assert_true(frame_policy.allowedFeatures().includes(feature));
|
assert_true(frame_policy.allowedFeatures().includes(feature));
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
Reference in New Issue
Block a user