diff --git a/.well-known/origin-policy b/.well-known/origin-policy
new file mode 100644
index 000000000000000..df2b83256c2265f
--- /dev/null
+++ b/.well-known/origin-policy
@@ -0,0 +1,18 @@
+import os
+import glob
+
+
+def main(request, response):
+ host_piece = request.url_parts.hostname.split(".")[0]
+
+ filepath_pattern = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(
+ __file__)), "../origin-policy/policies/", "{} *.json".format(host_piece)))
+
+ matches = glob.glob(filepath_pattern)
+
+ if len(matches) != 1:
+ return 404, [], '{} origin policies found at a path matching "{}"'.format(len(matches), filepath_pattern)
+
+ with open(matches[0]) as f:
+ data = f.read()
+ return 200, [('Content-Type', 'application/originpolicy+json')], data
diff --git a/.well-known/origin-policy/policy-content-security-comma-in-policy b/.well-known/origin-policy/policy-content-security-comma-in-policy
deleted file mode 100644
index 42990f93e6d2722..000000000000000
--- a/.well-known/origin-policy/policy-content-security-comma-in-policy
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "content_security": {
- "policies": ["script-src 'self' 'unsafe-inline', img-src 'none'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-content-security-double-content-security b/.well-known/origin-policy/policy-content-security-double-content-security
deleted file mode 100644
index be9b3750647d121..000000000000000
--- a/.well-known/origin-policy/policy-content-security-double-content-security
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "content_security": {
- "policies": ["script-src 'self' 'unsafe-inline'"]
- },
- "content_security": {
- "policies": ["img-src 'none'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-content-security-double-policies b/.well-known/origin-policy/policy-content-security-double-policies
deleted file mode 100644
index 2e625c5c46389b7..000000000000000
--- a/.well-known/origin-policy/policy-content-security-double-policies
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "content_security": {
- "policies": ["script-src 'self' 'unsafe-inline'"],
- "policies": ["img-src 'none'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-content-security-noimg-report-only b/.well-known/origin-policy/policy-content-security-noimg-report-only
deleted file mode 100644
index 13c662ef2d6e1c7..000000000000000
--- a/.well-known/origin-policy/policy-content-security-noimg-report-only
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "content_security": {
- "policies_report_only": ["img-src 'none'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-content-security-non-object b/.well-known/origin-policy/policy-content-security-non-object
deleted file mode 100644
index 7f6e13836401251..000000000000000
--- a/.well-known/origin-policy/policy-content-security-non-object
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "content_security": ["script-src 'self' 'unsafe-inline'"]
-}
diff --git a/.well-known/origin-policy/policy-content-security-non-string b/.well-known/origin-policy/policy-content-security-non-string
deleted file mode 100644
index 8649b17c4d8e73e..000000000000000
--- a/.well-known/origin-policy/policy-content-security-non-string
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "content_security": {
- "policies": [["script-src 'self' 'unsafe-inline'"]]
- }
-}
diff --git a/.well-known/origin-policy/policy-content-security-valid b/.well-known/origin-policy/policy-content-security-valid
deleted file mode 100644
index d4babb7949eefdf..000000000000000
--- a/.well-known/origin-policy/policy-content-security-valid
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "content_security": {
- "policies": ["script-src 'self' 'unsafe-inline'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-content-security-valid-with-multi-item-array b/.well-known/origin-policy/policy-content-security-valid-with-multi-item-array
deleted file mode 100644
index 45ec32200d5f6e3..000000000000000
--- a/.well-known/origin-policy/policy-content-security-valid-with-multi-item-array
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "content_security": {
- "policies": ["script-src 'self' 'unsafe-inline'", "img-src 'none'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-content-security-valid-with-semicolon b/.well-known/origin-policy/policy-content-security-valid-with-semicolon
deleted file mode 100644
index e777d5c96d5921d..000000000000000
--- a/.well-known/origin-policy/policy-content-security-valid-with-semicolon
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "content_security": {
- "policies": ["script-src 'self' 'unsafe-inline'; img-src 'none'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-csp-1 b/.well-known/origin-policy/policy-csp-1
deleted file mode 100644
index d4babb7949eefdf..000000000000000
--- a/.well-known/origin-policy/policy-csp-1
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "content_security": {
- "policies": ["script-src 'self' 'unsafe-inline'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-csp-2 b/.well-known/origin-policy/policy-csp-2
deleted file mode 100644
index 34a6c5c873b5775..000000000000000
--- a/.well-known/origin-policy/policy-csp-2
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "content_security": {
- "policies": ["script-src 'self' 'nonce-test'"]
- }
-}
diff --git a/.well-known/origin-policy/policy-features-comma-in-policy b/.well-known/origin-policy/policy-features-comma-in-policy
deleted file mode 100644
index e991c788f24a160..000000000000000
--- a/.well-known/origin-policy/policy-features-comma-in-policy
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "features": {
- "policy": "camera 'self' https://example.com/, geolocation 'self' https://example.com/"
- }
-}
diff --git a/.well-known/origin-policy/policy-features-double-features b/.well-known/origin-policy/policy-features-double-features
deleted file mode 100644
index 583f1eaa2fcda87..000000000000000
--- a/.well-known/origin-policy/policy-features-double-features
+++ /dev/null
@@ -1,8 +0,0 @@
-{
- "features": {
- "policy": "camera 'self' https://example.com/"
- },
- "features": {
- "policy": "geolocation 'self' https://example.com/"
- }
-}
diff --git a/.well-known/origin-policy/policy-features-double-policy b/.well-known/origin-policy/policy-features-double-policy
deleted file mode 100644
index fb216bc47298384..000000000000000
--- a/.well-known/origin-policy/policy-features-double-policy
+++ /dev/null
@@ -1,6 +0,0 @@
-{
- "features": {
- "policy": "camera 'self' https://example.com/",
- "policy": "geolocation 'self' https://example.com/"
- }
-}
diff --git a/.well-known/origin-policy/policy-features-non-object b/.well-known/origin-policy/policy-features-non-object
deleted file mode 100644
index b4d255440dc4b30..000000000000000
--- a/.well-known/origin-policy/policy-features-non-object
+++ /dev/null
@@ -1,3 +0,0 @@
-{
- "features": "camera 'self' https://example.com/"
-}
diff --git a/.well-known/origin-policy/policy-features-non-string b/.well-known/origin-policy/policy-features-non-string
deleted file mode 100644
index 8b758c7f617790b..000000000000000
--- a/.well-known/origin-policy/policy-features-non-string
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "features": {
- "policy": ["camera 'self' https://example.com/"]
- }
-}
diff --git a/.well-known/origin-policy/policy-features-valid b/.well-known/origin-policy/policy-features-valid
deleted file mode 100644
index 22ef8992cf7b5e3..000000000000000
--- a/.well-known/origin-policy/policy-features-valid
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- "features": {
- "policy": "camera 'self' https://example.com/; geolocation 'self' https://example.com/"
- }
-}
diff --git a/origin-policy/content-security/comma-in-policy.https.html b/origin-policy/content-security/comma-in-policy.https.html
index 88d72446392e675..07d10811f0bf853 100644
--- a/origin-policy/content-security/comma-in-policy.https.html
+++ b/origin-policy/content-security/comma-in-policy.https.html
@@ -3,9 +3,14 @@
Commas in "content_security/policy" cause parse errors and thus no CSP
-
+
+
+
diff --git a/origin-policy/content-security/comma-in-policy.https.html.headers b/origin-policy/content-security/comma-in-policy.https.html.headers
deleted file mode 100644
index 32e453ab20de0c3..000000000000000
--- a/origin-policy/content-security/comma-in-policy.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-comma-in-policy
diff --git a/origin-policy/content-security/double-content-security.https.html b/origin-policy/content-security/double-content-security.https.html
index 99046803c9fe305..357bd7669a66865 100644
--- a/origin-policy/content-security/double-content-security.https.html
+++ b/origin-policy/content-security/double-content-security.https.html
@@ -3,11 +3,14 @@
Of two "content_security" items only the second counts
-
+
-
+
diff --git a/origin-policy/content-security/double-content-security.https.html.headers b/origin-policy/content-security/double-content-security.https.html.headers
deleted file mode 100644
index a380b053c270c61..000000000000000
--- a/origin-policy/content-security/double-content-security.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-double-content-security
diff --git a/origin-policy/content-security/double-policies.https.html b/origin-policy/content-security/double-policies.https.html
index 925b9d5a31e10ff..327670fcad0b3ae 100644
--- a/origin-policy/content-security/double-policies.https.html
+++ b/origin-policy/content-security/double-policies.https.html
@@ -3,11 +3,14 @@
Of two "content_security/policies" items only the second counts
-
+
-
+
diff --git a/origin-policy/content-security/double-policies.https.html.headers b/origin-policy/content-security/double-policies.https.html.headers
deleted file mode 100644
index 23f1d1434057d27..000000000000000
--- a/origin-policy/content-security/double-policies.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-double-policies
diff --git a/origin-policy/content-security/non-array.https.html b/origin-policy/content-security/non-array.https.html
index 78a67e16eb9d305..c95b5a15b0e6414 100644
--- a/origin-policy/content-security/non-array.https.html
+++ b/origin-policy/content-security/non-array.https.html
@@ -3,9 +3,14 @@
Non-array "content_security/policies" member must be ignored
-
+
+
+
diff --git a/origin-policy/content-security/non-array.https.html.headers b/origin-policy/content-security/non-array.https.html.headers
deleted file mode 100644
index 31e6f375ef967e2..000000000000000
--- a/origin-policy/content-security/non-array.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-non-array
diff --git a/origin-policy/content-security/non-object.https.html b/origin-policy/content-security/non-object.https.html
index 359c6c7692294eb..220136c4d050bea 100644
--- a/origin-policy/content-security/non-object.https.html
+++ b/origin-policy/content-security/non-object.https.html
@@ -3,9 +3,14 @@
Non-object "content_security" member must be ignored
-
+
+
+
diff --git a/origin-policy/content-security/non-object.https.html.headers b/origin-policy/content-security/non-object.https.html.headers
deleted file mode 100644
index 812ea9445eca18d..000000000000000
--- a/origin-policy/content-security/non-object.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-non-object
diff --git a/origin-policy/content-security/non-string.https.html b/origin-policy/content-security/non-string.https.html
index 8af3c1c4dff1369..57c29fe265bebe2 100644
--- a/origin-policy/content-security/non-string.https.html
+++ b/origin-policy/content-security/non-string.https.html
@@ -3,9 +3,14 @@
Non-string "content_security/policies" array member must be ignored
-
+
+
+
diff --git a/origin-policy/content-security/non-string.https.html.headers b/origin-policy/content-security/non-string.https.html.headers
deleted file mode 100644
index 0b9ce2ee3f84c52..000000000000000
--- a/origin-policy/content-security/non-string.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-non-string
diff --git a/origin-policy/content-security/resources/allow-unsafe-eval-disallow-images.mjs b/origin-policy/content-security/resources/allow-unsafe-eval-disallow-images.mjs
new file mode 100644
index 000000000000000..8715e74e5df8195
--- /dev/null
+++ b/origin-policy/content-security/resources/allow-unsafe-eval-disallow-images.mjs
@@ -0,0 +1,3 @@
+import { runCSPTest } from "./helper.mjs";
+
+runCSPTest({ unsafeEval: true, img: false });
diff --git a/origin-policy/content-security/resources/allow-unsafe-eval.mjs b/origin-policy/content-security/resources/allow-unsafe-eval.mjs
new file mode 100644
index 000000000000000..bd6ca6f8bbd1e99
--- /dev/null
+++ b/origin-policy/content-security/resources/allow-unsafe-eval.mjs
@@ -0,0 +1,3 @@
+import { runCSPTest } from "./helper.mjs";
+
+runCSPTest({ unsafeEval: true });
diff --git a/origin-policy/content-security/resources/disallow-unsafe-eval-disallow-images.mjs b/origin-policy/content-security/resources/disallow-unsafe-eval-disallow-images.mjs
new file mode 100644
index 000000000000000..41b25553d56338a
--- /dev/null
+++ b/origin-policy/content-security/resources/disallow-unsafe-eval-disallow-images.mjs
@@ -0,0 +1,3 @@
+import { runCSPTest } from "./helper.mjs";
+
+runCSPTest({ unsafeEval: false, img: false });
diff --git a/origin-policy/content-security/helper.js b/origin-policy/content-security/resources/helper.mjs
similarity index 89%
rename from origin-policy/content-security/helper.js
rename to origin-policy/content-security/resources/helper.mjs
index 4875977afa4437a..5eff7e16ba04a73 100644
--- a/origin-policy/content-security/helper.js
+++ b/origin-policy/content-security/resources/helper.mjs
@@ -1,4 +1,4 @@
-window.waitForOneSecurityPolicyViolationEvent = expectedBlockedURI => {
+export function waitForOneSecurityPolicyViolationEvent(expectedBlockedURI) {
return new Promise(resolve => {
let eventCount = 0;
let blockedURI = null;
@@ -17,9 +17,9 @@ window.waitForOneSecurityPolicyViolationEvent = expectedBlockedURI => {
});
});
});
-};
+}
-window.waitForImgFail = imgSrc => {
+export function waitForImgFail(imgSrc) {
return new Promise((resolve, reject) => {
const img = document.createElement("img");
img.onload = () => reject(new Error("Must not load the image"));
@@ -28,10 +28,9 @@ window.waitForImgFail = imgSrc => {
img.src = imgSrc;
document.body.append(img);
});
-};
+}
-
-window.waitForImgSuccess = imgSrc => {
+export function waitForImgSuccess(imgSrc) {
return new Promise((resolve, reject) => {
const img = document.createElement("img");
img.onload = () => resolve();
@@ -40,10 +39,10 @@ window.waitForImgSuccess = imgSrc => {
img.src = imgSrc;
document.body.append(img);
});
-};
+}
// Both params are optional; if they are not given as booleans then we will not test that aspect.
-window.runCSPTest = ({ unsafeEval, img }) => {
+export function runCSPTest({ unsafeEval, img }) {
if (unsafeEval === true) {
test(() => {
eval("window.evalAllowed = true;");
@@ -70,4 +69,4 @@ window.runCSPTest = ({ unsafeEval, img }) => {
"img loading must be disallowed"
);
}
-};
+}
diff --git a/origin-policy/content-security/resources/trigger-violation-report-report-only.mjs b/origin-policy/content-security/resources/trigger-violation-report-report-only.mjs
new file mode 100644
index 000000000000000..9766717e309b5f0
--- /dev/null
+++ b/origin-policy/content-security/resources/trigger-violation-report-report-only.mjs
@@ -0,0 +1,12 @@
+import { waitForOneSecurityPolicyViolationEvent, waitForImgSuccess } from "./helper.mjs";
+
+promise_test(() => {
+ const imgURL = (new URL("/common/security-features/subresource/image.py", document.location)).href;
+
+ return Promise.all([
+ waitForOneSecurityPolicyViolationEvent(imgURL).then(blockedURI => {
+ assert_equals(blockedURI, imgURL);
+ }),
+ waitForImgSuccess(imgURL)
+ ]);
+});
diff --git a/origin-policy/content-security/resources/trigger-violation-report.mjs b/origin-policy/content-security/resources/trigger-violation-report.mjs
new file mode 100644
index 000000000000000..319c87b0f8a6723
--- /dev/null
+++ b/origin-policy/content-security/resources/trigger-violation-report.mjs
@@ -0,0 +1,12 @@
+import { waitForOneSecurityPolicyViolationEvent, waitForImgFail } from "./helper.mjs";
+
+promise_test(() => {
+ const imgURL = (new URL("/common/security-features/subresource/image.py", document.location)).href;
+
+ return Promise.all([
+ waitForOneSecurityPolicyViolationEvent(imgURL).then(blockedURI => {
+ assert_equals(blockedURI, imgURL);
+ }),
+ waitForImgFail(imgURL)
+ ]);
+});
diff --git a/origin-policy/content-security/trigger-violation-report-report-only.https.html b/origin-policy/content-security/trigger-violation-report-report-only.https.html
index 3e5038b501dec9e..9eb83792852eb56 100644
--- a/origin-policy/content-security/trigger-violation-report-report-only.https.html
+++ b/origin-policy/content-security/trigger-violation-report-report-only.https.html
@@ -3,21 +3,14 @@
CSP via origin policy must trigger a securitypolicyviolation event even when the CSP is report-only
-
+
-
+
diff --git a/origin-policy/content-security/trigger-violation-report-report-only.https.html.headers b/origin-policy/content-security/trigger-violation-report-report-only.https.html.headers
deleted file mode 100644
index cb27e1500e0b4e4..000000000000000
--- a/origin-policy/content-security/trigger-violation-report-report-only.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-noimg-report-only
diff --git a/origin-policy/content-security/trigger-violation-report.https.html b/origin-policy/content-security/trigger-violation-report.https.html
index 22beca5a3dbbc92..f981b2b05cef7e5 100644
--- a/origin-policy/content-security/trigger-violation-report.https.html
+++ b/origin-policy/content-security/trigger-violation-report.https.html
@@ -3,21 +3,14 @@
CSP via origin policy must trigger a securitypolicyviolation event
-
+
-
+
diff --git a/origin-policy/content-security/trigger-violation-report.https.html.headers b/origin-policy/content-security/trigger-violation-report.https.html.headers
deleted file mode 100644
index 08bcb9fa94171ee..000000000000000
--- a/origin-policy/content-security/trigger-violation-report.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-noimg
diff --git a/origin-policy/content-security/valid-with-multi-item-array.https.html b/origin-policy/content-security/valid-with-multi-item-array.https.html
index bc9ebd0cccfcbd7..36333a1e4b19943 100644
--- a/origin-policy/content-security/valid-with-multi-item-array.https.html
+++ b/origin-policy/content-security/valid-with-multi-item-array.https.html
@@ -3,11 +3,14 @@
"content_security/policy" can contain multiple array items to enforce multiple CSPs
-
+
-
+
diff --git a/origin-policy/content-security/valid-with-multi-item-array.https.html.headers b/origin-policy/content-security/valid-with-multi-item-array.https.html.headers
deleted file mode 100644
index eeddaba7a59b580..000000000000000
--- a/origin-policy/content-security/valid-with-multi-item-array.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-valid-with-semicolon
diff --git a/origin-policy/content-security/valid-with-semicolon.https.html b/origin-policy/content-security/valid-with-semicolon.https.html
index 82158f1cf7044f8..9eadc8f89d31ab8 100644
--- a/origin-policy/content-security/valid-with-semicolon.https.html
+++ b/origin-policy/content-security/valid-with-semicolon.https.html
@@ -3,11 +3,14 @@
"content_security/policy" array items can contain semicolons to enforce multiple CSP directives
-
+
-
+
diff --git a/origin-policy/content-security/valid-with-semicolon.https.html.headers b/origin-policy/content-security/valid-with-semicolon.https.html.headers
deleted file mode 100644
index eeddaba7a59b580..000000000000000
--- a/origin-policy/content-security/valid-with-semicolon.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-valid-with-semicolon
diff --git a/origin-policy/content-security/valid.https.html b/origin-policy/content-security/valid.https.html
deleted file mode 100644
index 36e5ddbf958b317..000000000000000
--- a/origin-policy/content-security/valid.https.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-Valid "content_security" member disallows eval
-
-
-
-
-
diff --git a/origin-policy/content-security/valid.https.html.headers b/origin-policy/content-security/valid.https.html.headers
deleted file mode 100644
index 78aeeacd934c90f..000000000000000
--- a/origin-policy/content-security/valid.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-content-security-valid
diff --git a/origin-policy/features/comma-in-policy.https.html b/origin-policy/features/comma-in-policy.https.html
index 1b991f0d8b68af0..a9faba4bfd4dd0c 100644
--- a/origin-policy/features/comma-in-policy.https.html
+++ b/origin-policy/features/comma-in-policy.https.html
@@ -3,9 +3,14 @@
Commas in "features/policy" cause parse errors and thus no feature policy
-
+
+
+
diff --git a/origin-policy/features/comma-in-policy.https.html.headers b/origin-policy/features/comma-in-policy.https.html.headers
deleted file mode 100644
index c0e68720516a666..000000000000000
--- a/origin-policy/features/comma-in-policy.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-features-comma-in-policy
diff --git a/origin-policy/features/double-features.https.html b/origin-policy/features/double-features.https.html
index 8397f849f301480..aa687d681c66d62 100644
--- a/origin-policy/features/double-features.https.html
+++ b/origin-policy/features/double-features.https.html
@@ -3,9 +3,14 @@
Of two "features" items only the second counts
-
+
+
+
diff --git a/origin-policy/features/double-features.https.html.headers b/origin-policy/features/double-features.https.html.headers
deleted file mode 100644
index f0a57380a8f570d..000000000000000
--- a/origin-policy/features/double-features.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-features-double-features
diff --git a/origin-policy/features/double-policy.https.html b/origin-policy/features/double-policy.https.html
index f1d63d6de966b36..d9e544acaaf6a4e 100644
--- a/origin-policy/features/double-policy.https.html
+++ b/origin-policy/features/double-policy.https.html
@@ -3,9 +3,14 @@
Of two "features/policy" items only the second counts
-
+
+
+
diff --git a/origin-policy/features/double-policy.https.html.headers b/origin-policy/features/double-policy.https.html.headers
deleted file mode 100644
index c1421693e4dafff..000000000000000
--- a/origin-policy/features/double-policy.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-features-double-policy
diff --git a/origin-policy/features/non-object.https.html b/origin-policy/features/non-object.https.html
index 31f632bf0f1fed5..2bd4b67e600c9bb 100644
--- a/origin-policy/features/non-object.https.html
+++ b/origin-policy/features/non-object.https.html
@@ -3,9 +3,14 @@
Non-object "features" member must be ignored
-
+
+
+
diff --git a/origin-policy/features/non-object.https.html.headers b/origin-policy/features/non-object.https.html.headers
deleted file mode 100644
index e8f68712ed341e9..000000000000000
--- a/origin-policy/features/non-object.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-features-non-object
diff --git a/origin-policy/features/non-string.https.html b/origin-policy/features/non-string.https.html
index 019014c980a4a3a..190d224a4cfe05b 100644
--- a/origin-policy/features/non-string.https.html
+++ b/origin-policy/features/non-string.https.html
@@ -3,9 +3,14 @@
Non-string "features/policy" member must be ignored
-
+
+
+
diff --git a/origin-policy/features/non-string.https.html.headers b/origin-policy/features/non-string.https.html.headers
deleted file mode 100644
index 4c6c376697b855c..000000000000000
--- a/origin-policy/features/non-string.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-features-non-string
diff --git a/origin-policy/features/helper.js b/origin-policy/features/resources/helper.mjs
similarity index 83%
rename from origin-policy/features/helper.js
rename to origin-policy/features/resources/helper.mjs
index f9c16b58c2cf8bf..7ced355e645c7ba 100644
--- a/origin-policy/features/helper.js
+++ b/origin-policy/features/resources/helper.mjs
@@ -1,8 +1,8 @@
"use strict";
-window.runFPTest = ({ camera, geolocation }) => {
+export function runFPTest({ camera, geolocation }) {
test(() => {
assert_equals(document.featurePolicy.allowsFeature('camera', 'https://example.com/'), camera, 'camera');
assert_equals(document.featurePolicy.allowsFeature('geolocation', 'https://example.com/'), geolocation, 'geolocation');
});
-};
+}
diff --git a/origin-policy/features/resources/no-camera-no-geolocation.mjs b/origin-policy/features/resources/no-camera-no-geolocation.mjs
new file mode 100644
index 000000000000000..b25d9abcb92ec99
--- /dev/null
+++ b/origin-policy/features/resources/no-camera-no-geolocation.mjs
@@ -0,0 +1,3 @@
+import { runFPTest } from "./helper.mjs";
+
+runFPTest({ camera: false, geolocation: false });
diff --git a/origin-policy/features/resources/no-camera-yes-geolocation.mjs b/origin-policy/features/resources/no-camera-yes-geolocation.mjs
new file mode 100644
index 000000000000000..a961deeb38989b3
--- /dev/null
+++ b/origin-policy/features/resources/no-camera-yes-geolocation.mjs
@@ -0,0 +1,3 @@
+import { runFPTest } from "./helper.mjs";
+
+runFPTest({ camera: false, geolocation: true });
diff --git a/origin-policy/features/resources/yes-camera-yes-geolocation.mjs b/origin-policy/features/resources/yes-camera-yes-geolocation.mjs
new file mode 100644
index 000000000000000..9f3b1d8303fe63a
--- /dev/null
+++ b/origin-policy/features/resources/yes-camera-yes-geolocation.mjs
@@ -0,0 +1,3 @@
+import { runFPTest } from "./helper.mjs";
+
+runFPTest({ camera: true, geolocation: true });
diff --git a/origin-policy/features/valid-with-semicolon.https.html b/origin-policy/features/valid-with-semicolon.https.html
new file mode 100644
index 000000000000000..8d2d0f4495ff7f4
--- /dev/null
+++ b/origin-policy/features/valid-with-semicolon.https.html
@@ -0,0 +1,16 @@
+
+
+Valid "features" member, with a semicolon
+
+
+
+
+
+
+
diff --git a/origin-policy/features/valid.https.html b/origin-policy/features/valid.https.html
deleted file mode 100644
index 6ff2076a7f076e7..000000000000000
--- a/origin-policy/features/valid.https.html
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-Valid "features" member
-
-
-
-
-
diff --git a/origin-policy/features/valid.https.html.headers b/origin-policy/features/valid.https.html.headers
deleted file mode 100644
index 9d0e25792c46d40..000000000000000
--- a/origin-policy/features/valid.https.html.headers
+++ /dev/null
@@ -1 +0,0 @@
-Sec-Origin-Policy: policy=policy-features-valid
diff --git a/origin-policy/origin-policy-report-to.https.tentative.sub.html b/origin-policy/origin-policy-report-to.https.tentative.sub.html
deleted file mode 100644
index dfef7a1d133c267..000000000000000
--- a/origin-policy/origin-policy-report-to.https.tentative.sub.html
+++ /dev/null
@@ -1,22 +0,0 @@
-
-
-
- Test that Origin Policy report-to are deliverd to the declared reporting group
-
-
-
-
-
-
-
-
-
diff --git a/origin-policy/origin-policy-report-to.https.tentative.sub.html.sub.headers b/origin-policy/origin-policy-report-to.https.tentative.sub.html.sub.headers
deleted file mode 100644
index 92a90c347d3a7d0..000000000000000
--- a/origin-policy/origin-policy-report-to.https.tentative.sub.html.sub.headers
+++ /dev/null
@@ -1 +0,0 @@
-Set-Cookie: origin-policy-report-to=5b4d35b6-0771-46fe-8700-ed2bb59ed4be; Path=/origin-policy/
diff --git a/origin-policy/origin-policy.https.tentative.html b/origin-policy/origin-policy.https.tentative.html
deleted file mode 100644
index 34a71fe40a19241..000000000000000
--- a/origin-policy/origin-policy.https.tentative.html
+++ /dev/null
@@ -1,143 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/origin-policy/policies/README.md b/origin-policy/policies/README.md
new file mode 100644
index 000000000000000..b07be74035f2dee
--- /dev/null
+++ b/origin-policy/policies/README.md
@@ -0,0 +1,5 @@
+These policies are served via the Python script at /.well-known/origin-policy. Their filenames must be in the form `subdomain human-facing-string-with-no-spaces.json`. They will be served in response to requests to that subdomain.
+
+The human-facing string has no impact on the tests, and just makes it easier to scroll through the list.
+
+The list of potential hostnames is created by `tools/serve/serve.py`'s `_make_origin_policy_subdomains` function, and can be expanded as necessary.
diff --git a/origin-policy/policies/op1 cspfp-comma-in-policy.json b/origin-policy/policies/op1 cspfp-comma-in-policy.json
new file mode 100644
index 000000000000000..189d28db8ba80d6
--- /dev/null
+++ b/origin-policy/policies/op1 cspfp-comma-in-policy.json
@@ -0,0 +1,13 @@
+{
+ "ids": [
+ "cspfp-comma-in-policy"
+ ],
+ "content_security": {
+ "policies": [
+ "script-src 'self' 'unsafe-inline', img-src 'none'"
+ ]
+ },
+ "features": {
+ "policy": "camera 'self' https://example.com/, geolocation 'self' https://example.com/"
+ }
+}
diff --git a/origin-policy/policies/op10 cspfp-valid.json b/origin-policy/policies/op10 cspfp-valid.json
new file mode 100644
index 000000000000000..0fc1d163f2b6195
--- /dev/null
+++ b/origin-policy/policies/op10 cspfp-valid.json
@@ -0,0 +1,13 @@
+{
+ "ids": [
+ "cspfp-valid"
+ ],
+ "content_security": {
+ "policies": [
+ "script-src 'self' 'unsafe-inline'; img-src 'none'"
+ ]
+ },
+ "features": {
+ "policy": "camera 'self' https://example.com/; geolocation 'self' https://example.com/"
+ }
+}
diff --git a/origin-policy/policies/op2 cspfp-double-top-level.json b/origin-policy/policies/op2 cspfp-double-top-level.json
new file mode 100644
index 000000000000000..26d798b585d96fd
--- /dev/null
+++ b/origin-policy/policies/op2 cspfp-double-top-level.json
@@ -0,0 +1,21 @@
+{
+ "ids": [
+ "cspfp-double-top-level"
+ ],
+ "content_security": {
+ "policies": [
+ "script-src 'self' 'unsafe-inline'"
+ ]
+ },
+ "content_security": {
+ "policies": [
+ "img-src 'none'"
+ ]
+ },
+ "features": {
+ "policy": "camera 'self' https://example.com/"
+ },
+ "features": {
+ "policy": "geolocation 'self' https://example.com/"
+ }
+}
diff --git a/origin-policy/policies/op3 cspfp-double-second-level.json b/origin-policy/policies/op3 cspfp-double-second-level.json
new file mode 100644
index 000000000000000..6665332807bea37
--- /dev/null
+++ b/origin-policy/policies/op3 cspfp-double-second-level.json
@@ -0,0 +1,17 @@
+{
+ "ids": [
+ "cspfp-double-second-level"
+ ],
+ "content_security": {
+ "policies": [
+ "script-src 'self' 'unsafe-inline'"
+ ],
+ "policies": [
+ "img-src 'none'"
+ ]
+ },
+ "features": {
+ "policy": "camera 'self' https://example.com/",
+ "policy": "geolocation 'self' https://example.com/"
+ }
+}
diff --git a/.well-known/origin-policy/policy-content-security-non-array b/origin-policy/policies/op4 csp-non-array.json
similarity index 70%
rename from .well-known/origin-policy/policy-content-security-non-array
rename to origin-policy/policies/op4 csp-non-array.json
index b96546c5f88fe77..5916b1ff9b572dd 100644
--- a/.well-known/origin-policy/policy-content-security-non-array
+++ b/origin-policy/policies/op4 csp-non-array.json
@@ -1,4 +1,7 @@
{
+ "ids": [
+ "csp-non-array"
+ ],
"content_security": {
"policies": "script-src 'self' 'unsafe-inline'"
}
diff --git a/origin-policy/policies/op5 cspfp-non-object.json b/origin-policy/policies/op5 cspfp-non-object.json
new file mode 100644
index 000000000000000..7488f9bfef297e0
--- /dev/null
+++ b/origin-policy/policies/op5 cspfp-non-object.json
@@ -0,0 +1,9 @@
+{
+ "ids": [
+ "cspfp-non-object"
+ ],
+ "content_security": [
+ "script-src 'self' 'unsafe-inline'"
+ ],
+ "features": "camera 'self' https://example.com/"
+}
diff --git a/origin-policy/policies/op6 cspfp-non-string.json b/origin-policy/policies/op6 cspfp-non-string.json
new file mode 100644
index 000000000000000..5c6941bf8fd1892
--- /dev/null
+++ b/origin-policy/policies/op6 cspfp-non-string.json
@@ -0,0 +1,17 @@
+{
+ "ids": [
+ "csp-non-string"
+ ],
+ "content_security": {
+ "policies": [
+ [
+ "script-src 'self' 'unsafe-inline'"
+ ]
+ ]
+ },
+ "features": {
+ "policy": [
+ "camera 'self' https://example.com/"
+ ]
+ }
+}
diff --git a/origin-policy/policies/op7 csp-noimg-report-only.json b/origin-policy/policies/op7 csp-noimg-report-only.json
new file mode 100644
index 000000000000000..fd5c522042a7e06
--- /dev/null
+++ b/origin-policy/policies/op7 csp-noimg-report-only.json
@@ -0,0 +1,10 @@
+{
+ "ids": [
+ "csp-noimg-report-only"
+ ],
+ "content_security": {
+ "policies_report_only": [
+ "img-src 'none'"
+ ]
+ }
+}
diff --git a/.well-known/origin-policy/policy-content-security-noimg b/origin-policy/policies/op8 csp-noimg.json
similarity index 67%
rename from .well-known/origin-policy/policy-content-security-noimg
rename to origin-policy/policies/op8 csp-noimg.json
index cd57b7b21e916b4..b88e1f80bf93c9b 100644
--- a/.well-known/origin-policy/policy-content-security-noimg
+++ b/origin-policy/policies/op8 csp-noimg.json
@@ -1,4 +1,7 @@
{
+ "ids": [
+ "csp-noimg"
+ ],
"content_security": {
"policies": ["img-src 'none'"]
}
diff --git a/origin-policy/policies/op9 csp-valid-with-multi-item-array.json b/origin-policy/policies/op9 csp-valid-with-multi-item-array.json
new file mode 100644
index 000000000000000..edd743038db8d48
--- /dev/null
+++ b/origin-policy/policies/op9 csp-valid-with-multi-item-array.json
@@ -0,0 +1,11 @@
+{
+ "ids": [
+ "csp-valid-with-multi-item-array"
+ ],
+ "content_security": {
+ "policies": [
+ "script-src 'self' 'unsafe-inline'",
+ "img-src 'none'"
+ ]
+ }
+}
diff --git a/origin-policy/resources/origin-policy-test-runner.js b/origin-policy/resources/origin-policy-test-runner.js
new file mode 100644
index 000000000000000..a1c6453debd20d7
--- /dev/null
+++ b/origin-policy/resources/origin-policy-test-runner.js
@@ -0,0 +1,28 @@
+window.runTestsInSubframe = ({ hostname, testJS }) => {
+ test(() => {
+ assert_equals(location.protocol, "https:");
+ }, "Prerequisite check: running on HTTPS");
+
+ promise_test(() => new Promise((resolve, reject) => {
+ const url = new URL(window.location.href);
+ url.hostname = `${hostname}.${document.domain}`;
+ url.pathname = "/origin-policy/resources/subframe-with-origin-policy.py";
+
+ // Normalize the URL so that callers can idiomatically give values relative
+ // to themselves.
+ url.searchParams.append("test", new URL(testJS, document.baseURI).pathname);
+
+ const iframe = document.createElement("iframe");
+ iframe.src = url.href;
+
+ // We need to delegate anything we plan to toggle with FP otherwise it will
+ // be locked to disallowed.
+ iframe.allow = "camera *; geolocation *";
+
+ iframe.onload = resolve;
+ iframe.onerror = () => reject(new Error(`Could not load ${url.href}`));
+ document.body.append(iframe);
+
+ fetch_tests_from_window(iframe.contentWindow);
+ }), "Test setup of the iframe");
+};
diff --git a/origin-policy/resources/subframe-with-origin-policy.py b/origin-policy/resources/subframe-with-origin-policy.py
new file mode 100644
index 000000000000000..636a649a0e20beb
--- /dev/null
+++ b/origin-policy/resources/subframe-with-origin-policy.py
@@ -0,0 +1,26 @@
+def main(request, response):
+ """Send a response with the Origin-Policy header asking for the latest
+ policy, that runs the test JS given by the ?test= argument. This is meant
+ to be loaded into an iframe by origin-policy-test-runner.js.
+
+ The ?test= argument is best given as an absolute path (starting with /)
+ since it will otherwise be interpreted relative to where this file is
+ served.
+ """
+ test_file = request.GET.first("test")
+
+ response.headers.set("Origin-Policy", "allowed=(latest)")
+ response.headers.set("Content-Type", "text/html")
+
+ return """
+
+
+ Origin policy subframe
+
+
+
+
+
+
+
+ """ % test_file
diff --git a/origin-policy/sec-origin-policy-header.html.py b/origin-policy/sec-origin-policy-header.html.py
deleted file mode 100644
index 7754e04a313c129..000000000000000
--- a/origin-policy/sec-origin-policy-header.html.py
+++ /dev/null
@@ -1,64 +0,0 @@
-def main(request, response):
- """Send a response with the origin policy indicated by the ?policy= argument.
-
- Won't send a policy when the browser doesn't indicate support.
- The response tests whether inline script and eval are allowed, and will
- send a corresponding message to the parent frame.
- For easier debugging, we'll also show the results in-page.
- """
- origin_policy_header = "Sec-Origin-Policy"
- request_policy = request.headers.get(origin_policy_header)
- response_policy = request.GET.first("policy", default="")
-
- if request_policy and response_policy:
- response.headers.set(origin_policy_header, "policy=%s" % response_policy)
- response.headers.set("Vary", "sec-origin-policy")
-
- response.headers.set("Content-Type", "text/html");
- return """
-
-
- Page with an Origin Policy
-
-
-
-
-
- Reveal whether CSP with "unsafe-inline" or "unsafe-eval" is present:
-
- - inline script allowed:
- - eval allowed:
-
-
-
-
-
- """
-
diff --git a/origin-policy/sec-origin-policy-subframe.html b/origin-policy/sec-origin-policy-subframe.html
deleted file mode 100644
index d716ba11d97ce61..000000000000000
--- a/origin-policy/sec-origin-policy-subframe.html
+++ /dev/null
@@ -1,3 +0,0 @@
-The forbidden frame.
-Content shouldn't matter, because this frame shouldn't be loaded.
-So there.
diff --git a/origin-policy/sec-origin-policy-subframe.html.sub.headers b/origin-policy/sec-origin-policy-subframe.html.sub.headers
deleted file mode 100644
index a046f0096ba1b30..000000000000000
--- a/origin-policy/sec-origin-policy-subframe.html.sub.headers
+++ /dev/null
@@ -1,3 +0,0 @@
-Report-To: { "group": "report-to-group", "max_age": 1000, "endpoints": [{ "url": "https://{{hosts[alt][]}}:{{ports[https][0]}}/content-security-policy/support/report.py?op=put&reportID=5b4d35b6-0771-46fe-8700-ed2bb59ed4be" }] }
-Sec-Origin-Policy: policy=nonexistingpolicy, report-to=report-to-group
-
diff --git a/tools/serve/serve.py b/tools/serve/serve.py
index 0985810cc58e30c..062a70d5fac97d3 100644
--- a/tools/serve/serve.py
+++ b/tools/serve/serve.py
@@ -366,6 +366,7 @@ def add_mount_point(self, url_base, path):
("GET", "*.any.serviceworker.html", ServiceWorkersHandler),
("GET", "*.any.worker.js", AnyWorkerHandler),
("GET", "*.asis", handlers.AsIsHandler),
+ ("GET", "/.well-known/origin-policy", handlers.PythonScriptHandler),
("*", "*.py", handlers.PythonScriptHandler),
("GET", "*", handlers.FileHandler)
]