forked from mirrors/gecko-dev
		
	 918ed6c474
			
		
	
	
		918ed6c474
		
	
	
	
	
		
			
			This was done using the following script:
37e3803c7a/processors/chromeutils-import.jsm
MozReview-Commit-ID: 1Nc3XDu0wGl
--HG--
extra : source : 12fc4dee861c812fd2bd032c63ef17af61800c70
extra : intermediate-source : 34c999fa006bffe8705cf50c54708aa21a962e62
extra : histedit_source : b2be2c5e5d226e6c347312456a6ae339c1e634b0
		
	
			
		
			
				
	
	
		
			224 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			224 lines
		
	
	
	
		
			7.4 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| /*
 | |
|  * Description of the tests:
 | |
|  *   These tests check for conformance to the CSP spec as they relate to Web Manifests.
 | |
|  *
 | |
|  *   In particular, the tests check that default-src and manifest-src directives are
 | |
|  *   are respected by the ManifestObtainer.
 | |
|  */
 | |
| /*globals Cu, is, ok*/
 | |
| "use strict";
 | |
| const {
 | |
|   ManifestObtainer
 | |
| } = ChromeUtils.import("resource://gre/modules/ManifestObtainer.jsm", {});
 | |
| const path = "/tests/dom/security/test/csp/";
 | |
| const testFile = `${path}file_web_manifest.html`;
 | |
| const remoteFile = `${path}file_web_manifest_remote.html`;
 | |
| const httpsManifest = `${path}file_web_manifest_https.html`;
 | |
| const server = `${path}file_testserver.sjs`;
 | |
| const defaultURL = new URL(`http://example.org${server}`);
 | |
| const secureURL = new URL(`https://example.com:443${server}`);
 | |
| const tests = [
 | |
|   // CSP block everything, so trying to load a manifest
 | |
|   // will result in a policy violation.
 | |
|   {
 | |
|     expected: "default-src 'none' blocks fetching manifest.",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", testFile);
 | |
|       url.searchParams.append("csp", "default-src 'none'");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(topic) {
 | |
|       is(topic, "csp-on-violate-policy", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // CSP allows fetching only from mochi.test:8888,
 | |
|   // so trying to load a manifest from same origin
 | |
|   // triggers a CSP violation.
 | |
|   {
 | |
|     expected: "default-src mochi.test:8888 blocks manifest fetching.",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", testFile);
 | |
|       url.searchParams.append("csp", "default-src mochi.test:8888");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(topic) {
 | |
|       is(topic, "csp-on-violate-policy", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // CSP restricts fetching to 'self', so allowing the manifest
 | |
|   // to load. The name of the manifest is then checked.
 | |
|   {
 | |
|     expected: "CSP default-src 'self' allows fetch of manifest.",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", testFile);
 | |
|       url.searchParams.append("csp", "default-src 'self'");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(manifest) {
 | |
|       is(manifest.name, "loaded", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // CSP only allows fetching from mochi.test:8888 and remoteFile
 | |
|   // requests a manifest from that origin, so manifest should load.
 | |
|   {
 | |
|     expected: "CSP default-src mochi.test:8888 allows fetching manifest.",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", remoteFile);
 | |
|       url.searchParams.append("csp", "default-src http://mochi.test:8888");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(manifest) {
 | |
|       is(manifest.name, "loaded", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // default-src blocks everything, so any attempt to
 | |
|   // fetch a manifest from another origin will trigger a
 | |
|   // policy violation.
 | |
|   {
 | |
|     expected: "default-src 'none' blocks mochi.test:8888",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", remoteFile);
 | |
|       url.searchParams.append("csp", "default-src 'none'");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(topic) {
 | |
|       is(topic, "csp-on-violate-policy", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // CSP allows fetching from self, so manifest should load.
 | |
|   {
 | |
|     expected: "CSP manifest-src allows self",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", testFile);
 | |
|       url.searchParams.append("csp", "manifest-src 'self'");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(manifest) {
 | |
|       is(manifest.name, "loaded", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // CSP allows fetching from example.org, so manifest should load.
 | |
|   {
 | |
|     expected: "CSP manifest-src allows http://example.org",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", testFile);
 | |
|       url.searchParams.append("csp", "manifest-src http://example.org");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(manifest) {
 | |
|       is(manifest.name, "loaded", this.expected);
 | |
|     }
 | |
|   }, {
 | |
|     expected: "CSP manifest-src allows mochi.test:8888",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", remoteFile);
 | |
|       url.searchParams.append("cors", "*");
 | |
|       url.searchParams.append("csp", "default-src *; manifest-src http://mochi.test:8888");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(manifest) {
 | |
|       is(manifest.name, "loaded", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // CSP restricts fetching to mochi.test:8888, but the test
 | |
|   // file is at example.org. Hence, a policy violation is
 | |
|   // triggered.
 | |
|   {
 | |
|     expected: "CSP blocks manifest fetching from example.org.",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", testFile);
 | |
|       url.searchParams.append("csp", "manifest-src mochi.test:8888");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(topic) {
 | |
|       is(topic, "csp-on-violate-policy", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // CSP is set to only allow manifest to be loaded from same origin,
 | |
|   // but the remote file attempts to load from a different origin. Thus
 | |
|   // this causes a CSP violation.
 | |
|   {
 | |
|     expected: "CSP manifest-src 'self' blocks cross-origin fetch.",
 | |
|     get tabURL() {
 | |
|       const url = new URL(defaultURL);
 | |
|       url.searchParams.append("file", remoteFile);
 | |
|       url.searchParams.append("csp", "manifest-src 'self'");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(topic) {
 | |
|       is(topic, "csp-on-violate-policy", this.expected);
 | |
|     }
 | |
|   },
 | |
|   // CSP allows fetching over TLS from example.org, so manifest should load.
 | |
|   {
 | |
|     expected: "CSP manifest-src allows example.com over TLS",
 | |
|     get tabURL() {
 | |
|       // secureURL loads https://example.com:443
 | |
|       // and gets manifest from https://example.org:443
 | |
|       const url = new URL(secureURL);
 | |
|       url.searchParams.append("file", httpsManifest);
 | |
|       url.searchParams.append("cors", "*");
 | |
|       url.searchParams.append("csp", "manifest-src https://example.com:443");
 | |
|       return url.href;
 | |
|     },
 | |
|     run(manifest) {
 | |
|       is(manifest.name, "loaded", this.expected);
 | |
|     }
 | |
|   },
 | |
| ];
 | |
| 
 | |
| //jscs:disable
 | |
| add_task(async function() {
 | |
|   //jscs:enable
 | |
|   const testPromises = tests.map((test) => {
 | |
|     const tabOptions = {
 | |
|       gBrowser,
 | |
|       url: test.tabURL,
 | |
|       skipAnimation: true,
 | |
|     };
 | |
|     return BrowserTestUtils.withNewTab(tabOptions, (browser) => testObtainingManifest(browser, test));
 | |
|   });
 | |
|   await Promise.all(testPromises);
 | |
| });
 | |
| 
 | |
| async function testObtainingManifest(aBrowser, aTest) {
 | |
|   const waitForObserver = waitForNetObserver(aBrowser, aTest);
 | |
|   // Expect an exception (from promise rejection) if there a content policy
 | |
|   // that is violated.
 | |
|   try {
 | |
|     const manifest = await ManifestObtainer.browserObtainManifest(aBrowser);
 | |
|     aTest.run(manifest);
 | |
|   } catch (e) {
 | |
|     const wasBlocked = e.message.includes("NetworkError when attempting to fetch resource");
 | |
|     ok(wasBlocked, `Expected promise rejection obtaining ${aTest.tabURL}: ${e.message}`);
 | |
|   } finally {
 | |
|     await waitForObserver;
 | |
|   }
 | |
| }
 | |
| 
 | |
| // Helper object used to observe policy violations when blocking is expected.
 | |
| function waitForNetObserver(aBrowser, aTest) {
 | |
|   // We don't need to wait for violation, so just resolve
 | |
|   if (!aTest.expected.includes("block")){
 | |
|     return Promise.resolve();
 | |
|   }
 | |
| 
 | |
|   return ContentTask.spawn(aBrowser, null, () => {
 | |
|     return new Promise(resolve => {
 | |
|       function observe(subject, topic) {
 | |
|         Services.obs.removeObserver(observe, "csp-on-violate-policy");
 | |
|         resolve();
 | |
|       };
 | |
|       Services.obs.addObserver(observe, "csp-on-violate-policy");
 | |
|     });
 | |
|   }).then(() => aTest.run("csp-on-violate-policy"));
 | |
| }
 |