diff --git a/browser/installer/package-manifest.in b/browser/installer/package-manifest.in index 68728bd4547..fce0e766087 100644 --- a/browser/installer/package-manifest.in +++ b/browser/installer/package-manifest.in @@ -326,7 +326,6 @@ @BINPATH@/components/nsWebHandlerApp.js @BINPATH@/components/nsBadCertHandler.js @BINPATH@/components/nsFormAutoComplete.js -@BINPATH@/components/contentSecurityPolicy.js #ifdef XP_MACOSX @BINPATH@/components/libalerts_s.dylib #endif diff --git a/caps/idl/nsIPrincipal.idl b/caps/idl/nsIPrincipal.idl index f1c78641acb..127f8949ca5 100644 --- a/caps/idl/nsIPrincipal.idl +++ b/caps/idl/nsIPrincipal.idl @@ -47,12 +47,11 @@ struct JSPrincipals; %} interface nsIURI; -interface IContentSecurityPolicy; [ptr] native JSContext(JSContext); [ptr] native JSPrincipals(JSPrincipals); -[scriptable, uuid(799ab95c-0038-4e0f-b705-74c21f185bb5)] +[scriptable, uuid(b8268b9a-2403-44ed-81e3-614075c92034)] interface nsIPrincipal : nsISerializable { /** @@ -242,9 +241,4 @@ interface nsIPrincipal : nsISerializable * one, this will return null. Getting this attribute never throws. */ readonly attribute nsISupports certificate; - - /** - * A Content Security Policy associated with this principal. - */ - [noscript] attribute IContentSecurityPolicy csp; }; diff --git a/caps/include/nsPrincipal.h b/caps/include/nsPrincipal.h index b9ff3912727..1a933163efd 100644 --- a/caps/include/nsPrincipal.h +++ b/caps/include/nsPrincipal.h @@ -138,7 +138,6 @@ protected: DomainPolicy* mSecurityPolicy; - nsCOMPtr mCSP; nsCOMPtr mCodebase; nsCOMPtr mDomain; PRPackedBool mTrusted; diff --git a/caps/src/nsNullPrincipal.cpp b/caps/src/nsNullPrincipal.cpp index ad770e2a93c..63171280293 100644 --- a/caps/src/nsNullPrincipal.cpp +++ b/caps/src/nsNullPrincipal.cpp @@ -251,21 +251,6 @@ nsNullPrincipal::GetURI(nsIURI** aURI) return NS_EnsureSafeToReturn(mURI, aURI); } -NS_IMETHODIMP -nsNullPrincipal::GetCsp(IContentSecurityPolicy** aCsp) -{ - // CSP on a null principal makes no sense - *aCsp = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsNullPrincipal::SetCsp(IContentSecurityPolicy* aCsp) -{ - // CSP on a null principal makes no sense - return NS_ERROR_NOT_AVAILABLE; -} - NS_IMETHODIMP nsNullPrincipal::GetDomain(nsIURI** aDomain) { diff --git a/caps/src/nsPrincipal.cpp b/caps/src/nsPrincipal.cpp index 5a8bbd18e23..e6124df9d86 100644 --- a/caps/src/nsPrincipal.cpp +++ b/caps/src/nsPrincipal.cpp @@ -57,7 +57,6 @@ #include "nsIPrefService.h" #include "nsIClassInfoImpl.h" #include "nsDOMError.h" -#include "IContentSecurityPolicy.h" #include "nsPrincipal.h" @@ -775,25 +774,6 @@ nsPrincipal::GetCertificate(nsISupports** aCertificate) return NS_OK; } -NS_IMETHODIMP -nsPrincipal::GetCsp(IContentSecurityPolicy** aCsp) -{ - NS_IF_ADDREF(*aCsp = mCSP); - return NS_OK; -} - -NS_IMETHODIMP -nsPrincipal::SetCsp(IContentSecurityPolicy* aCsp) -{ - // If CSP was already set, it should not be destroyed! Instead, it should - // get set anew when a new principal is created. - if (mCSP) - return NS_ERROR_ALREADY_INITIALIZED; - - mCSP = aCsp; - return NS_OK; -} - NS_IMETHODIMP nsPrincipal::GetHashValue(PRUint32* aValue) { diff --git a/caps/src/nsSystemPrincipal.cpp b/caps/src/nsSystemPrincipal.cpp index c2e0aa2cf54..7673e85467c 100644 --- a/caps/src/nsSystemPrincipal.cpp +++ b/caps/src/nsSystemPrincipal.cpp @@ -223,20 +223,6 @@ nsSystemPrincipal::GetHasCertificate(PRBool* aResult) return NS_OK; } -NS_IMETHODIMP -nsSystemPrincipal::GetCsp(IContentSecurityPolicy** aCsp) -{ - *aCsp = nsnull; - return NS_OK; -} - -NS_IMETHODIMP -nsSystemPrincipal::SetCsp(IContentSecurityPolicy* aCsp) -{ - // CSP on a null principal makes no sense - return NS_OK; -} - NS_IMETHODIMP nsSystemPrincipal::GetDomain(nsIURI** aDomain) { diff --git a/content/base/public/IContentSecurityPolicy.idl b/content/base/public/IContentSecurityPolicy.idl deleted file mode 100644 index df348fd97f2..00000000000 --- a/content/base/public/IContentSecurityPolicy.idl +++ /dev/null @@ -1,152 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Content Security Policy IDL definition. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation - * - * Contributor(s): - * Sid Stamm - * Brandon Sterne - * Daniel Veditz - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsISupports.idl" - -interface nsIURI; -interface nsIHttpChannel; -interface nsIDocShell; - -/** - * IContentSecurityPolicy - * Describes an XPCOM component used to model an enforce CSPs. - */ - -[scriptable, uuid(AB36A2BF-CB32-4AA6-AB41-6B4E4444A221)] -interface IContentSecurityPolicy : nsISupports -{ - - /** - * Set to true when the CSP has been read in and parsed and is ready to - * enforce. This is a barrier for the nsDocument so it doesn't load any - * sub-content until either it knows that a CSP is ready or will not be used. - */ - attribute boolean isInitialized; - - /** - * When set to true, content load-blocking and fail-closed are disabled: CSP - * will ONLY send reports, and not modify behavior. - */ - attribute boolean reportOnlyMode; - - /** - * A read-only string version of the policy for debugging. - */ - readonly attribute AString policy; - - /** - * Whether this policy allows in-page script. - * - * Calls to this may trigger violation reports when queried, so - * this value should not be cached. - */ - readonly attribute boolean allowsInlineScript; - - /** - * whether this policy allows eval and eval-like functions - * such as setTimeout("code string", time). - * - * Calls to this may trigger violation reports when queried, so - * this value should not be cached. - */ - readonly attribute boolean allowsEval; - - /** - * Manually triggers violation report sending given a URI and reason. - * The URI may be null, in which case "self" is sent. - * @param blockedURI - * the URI that violated the policy - * @param violatedDirective - * the directive that was violated. - * @return - * nothing. - */ - void sendReports(in AString blockedURI, in AString violatedDirective); - - /** - * Called after the CSP object is created to fill in the appropriate request - * and request header information needed in case a report needs to be sent. - */ - void scanRequestData(in nsIHttpChannel aChannel); - - /** - * Updates the policy currently stored in the CSP to be "refined" or - * tightened by the one specified in the string policyString. - */ - void refinePolicy(in AString policyString, in nsIURI selfURI); - - /** - * Verifies ancestry as permitted by the policy. - * - * Calls to this may trigger violation reports when queried, so - * this value should not be cached. - * - * @param docShell - * containing the protected resource - * @return - * true if the frame's ancestors are all permitted by policy - */ - boolean permitsAncestry(in nsIDocShell docShell); - - /** - * Delegate method called by the service when sub-elements of the protected - * document are being loaded. Given a bit of information about the request, - * decides whether or not the policy is satisfied. - * - * Calls to this may trigger violation reports when queried, so - * this value should not be cached. - */ - short shouldLoad(in unsigned long aContentType, - in nsIURI aContentLocation, - in nsIURI aRequestOrigin, - in nsISupports aContext, - in ACString aMimeTypeGuess, - in nsISupports aExtra); - - /** - * Delegate method called by the service when sub-elements of the protected - * document are being processed. Given a bit of information about the request, - * decides whether or not the policy is satisfied. - */ - short shouldProcess(in unsigned long aContentType, - in nsIURI aContentLocation, - in nsIURI aRequestOrigin, - in nsISupports aContext, - in ACString aMimeType, - in nsISupports aExtra); - -}; diff --git a/content/base/public/Makefile.in b/content/base/public/Makefile.in index 77236055146..cb90f36fdf2 100644 --- a/content/base/public/Makefile.in +++ b/content/base/public/Makefile.in @@ -113,7 +113,6 @@ XPIDLSRCS = \ nsIObjectLoadingContent.idl \ nsIFrameLoader.idl \ nsIXMLHttpRequest.idl \ - IContentSecurityPolicy.idl \ $(NULL) include $(topsrcdir)/config/rules.mk diff --git a/content/base/src/CSPUtils.jsm b/content/base/src/CSPUtils.jsm deleted file mode 100644 index 1a39f0f2391..00000000000 --- a/content/base/src/CSPUtils.jsm +++ /dev/null @@ -1,1295 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Content Security Policy data structures. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation - * - * Contributor(s): - * Sid Stamm - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -/** - * Content Security Policy Utilities - * - * Overview - * This contains a set of classes and utilities for CSP. It is in this - * separate file for testing purposes. - */ - -// Module stuff -var EXPORTED_SYMBOLS = ["CSPRep", "CSPSourceList", "CSPSource", - "CSPHost", "CSPWarning", "CSPError", "CSPdebug"]; - - -// these are not exported -var gIoService = Components.classes["@mozilla.org/network/io-service;1"] - .getService(Components.interfaces.nsIIOService); - -var gETLDService = Components.classes["@mozilla.org/network/effective-tld-service;1"] - .getService(Components.interfaces.nsIEffectiveTLDService); - - -function CSPWarning(aMsg) { - // customize this to redirect output. - aMsg = 'CSP WARN: ' + aMsg + "\n"; - dump(aMsg); - Components.classes["@mozilla.org/consoleservice;1"] - .getService(Components.interfaces.nsIConsoleService) - .logStringMessage(aMsg); -} -function CSPError(aMsg) { - aMsg = 'CSP ERROR: ' + aMsg + "\n"; - dump(aMsg); - Components.classes["@mozilla.org/consoleservice;1"] - .getService(Components.interfaces.nsIConsoleService) - .logStringMessage(aMsg); -} -function CSPdebug(aMsg) { - aMsg = 'CSP debug: ' + aMsg + "\n"; - dump(aMsg); - Components.classes["@mozilla.org/consoleservice;1"] - .getService(Components.interfaces.nsIConsoleService) - .logStringMessage(aMsg); -} - -//:::::::::::::::::::::::: CLASSES ::::::::::::::::::::::::::// - -/** - * Class that represents a parsed policy structure. - */ -function CSPRep() { - // this gets set to true when the policy is done parsing, or when a - // URI-borne policy has finished loading. - this._isInitialized = false; - - this._allowEval = false; - this._allowInlineScripts = false; - - // don't auto-populate _directives, so it is easier to find bugs - this._directives = {}; -} - -CSPRep.SRC_DIRECTIVES = { - ALLOW: "allow", - SCRIPT_SRC: "script-src", - STYLE_SRC: "style-src", - MEDIA_SRC: "media-src", - IMG_SRC: "img-src", - OBJECT_SRC: "object-src", - FRAME_SRC: "frame-src", - FRAME_ANCESTORS: "frame-ancestors", - FONT_SRC: "font-src", - XHR_SRC: "xhr-src" -}; - -CSPRep.URI_DIRECTIVES = { - REPORT_URI: "report-uri", /* list of URIs */ - POLICY_URI: "policy-uri" /* single URI */ -}; - -CSPRep.OPTIONS_DIRECTIVE = "options"; - -/** - * Factory to create a new CSPRep, parsed from a string. - * - * @param aStr - * string rep of a CSP - * @param self (optional) - * string or CSPSource representing the "self" source - * @returns - * an instance of CSPRep - */ -CSPRep.fromString = function(aStr, self) { - var SD = CSPRep.SRC_DIRECTIVES; - var UD = CSPRep.URI_DIRECTIVES; - var aCSPR = new CSPRep(); - aCSPR._originalText = aStr; - - var dirs = aStr.split(";"); - - directive: - for each(var dir in dirs) { - dir = dir.trim(); - var dirname = dir.split(/\s+/)[0]; - var dirvalue = dir.substring(dirname.length).trim(); - - // OPTIONS DIRECTIVE //////////////////////////////////////////////// - if (dirname === CSPRep.OPTIONS_DIRECTIVE) { - // grab value tokens and interpret them - var options = dirvalue.split(/\s+/); - for each (var opt in options) { - if (opt === "inline-script") - aCSPR._allowInlineScripts = true; - else if (opt === "eval-script") - aCSPR._allowEval = true; - else - CSPWarning("don't understand option '" + opt + "'. Ignoring it."); - } - continue directive; - } - - // SOURCE DIRECTIVES //////////////////////////////////////////////// - for each(var sdi in SD) { - if (dirname === sdi) { - // process dirs, and enforce that 'self' is defined. - var dv = CSPSourceList.fromString(dirvalue, self, true); - if (dv) { - aCSPR._directives[sdi] = dv; - continue directive; - } - } - } - - // REPORT URI /////////////////////////////////////////////////////// - if (dirname === UD.REPORT_URI) { - // might be space-separated list of URIs - var uriStrings = dirvalue.split(/\s+/); - var okUriStrings = []; - var selfUri = self ? gIoService.newURI(self.toString(),null,null) : null; - - // Verify that each report URI is in the same etld + 1 - // if "self" is defined, and just that it's valid otherwise. - for (let i in uriStrings) { - try { - var uri = gIoService.newURI(uriStrings[i],null,null); - if (self) { - if (gETLDService.getBaseDomain(uri) === - gETLDService.getBaseDomain(selfUri)) { - okUriStrings.push(uriStrings[i]); - } else { - CSPWarning("can't use report URI from non-matching eTLD+1: " - + gETLDService.getBaseDomain(uri)); - } - } - } catch(e) { - CSPWarning("couldn't parse report URI: " + dirvalue); - } - } - aCSPR._directives[UD.REPORT_URI] = okUriStrings.join(' '); - continue directive; - } - - // POLICY URI ////////////////////////////////////////////////////////// - if (dirname === UD.POLICY_URI) { - // POLICY_URI can only be alone - if (aCSPR._directives.length > 0 || dirs.length > 1) { - CSPError("policy-uri directive can only appear alone"); - return CSPRep.fromString("allow 'none'"); - } - - var uri = ''; - try { - uri = gIoService.newURI(dirvalue, null, null); - } catch(e) { - CSPError("could not parse URI in policy URI: " + dirvalue); - return CSPRep.fromString("allow 'none'"); - } - - // Verify that policy URI comes from the same origin - if (self) { - var selfUri = gIoService.newURI(self.toString(), null, null); - if (selfUri.host !== uri.host){ - CSPError("can't fetch policy uri from non-matching hostname: " + uri.host); - return CSPRep.fromString("allow 'none'"); - } - if (selfUri.port !== uri.port){ - CSPError("can't fetch policy uri from non-matching port: " + uri.port); - return CSPRep.fromString("allow 'none'"); - } - if (selfUri.scheme !== uri.scheme){ - CSPError("can't fetch policy uri from non-matching scheme: " + uri.scheme); - return CSPRep.fromString("allow 'none'"); - } - } - - var req = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] - .createInstance(Components.interfaces.nsIXMLHttpRequest); - - // insert error hook - req.onerror = CSPError; - - // synchronous -- otherwise we need to architect a callback into the - // xpcom component so that whomever creates the policy object gets - // notified when it's loaded and ready to go. - req.open("GET", dirvalue, false); - - // make request anonymous - // This prevents sending cookies with the request, in case the policy URI - // is injected, it can't be abused for CSRF. - req.channel.loadFlags |= Components.interfaces.nsIChannel.LOAD_ANONYMOUS; - - req.send(null); - if (req.status == 200) { - aCSPR = CSPRep.fromString(req.responseText, self); - // remember where we got the policy - aCSPR._directives[UD.POLICY_URI] = dirvalue; - return aCSPR; - } - CSPError("Error fetching policy URI: server response was " + req.status); - return CSPRep.fromString("allow 'none'"); - } - - // UNIDENTIFIED DIRECTIVE ///////////////////////////////////////////// - CSPWarning("Couldn't process unknown directive '" + dirname + "'"); - - } // end directive: loop - - aCSPR.makeExplicit(); - return aCSPR; -}; - -CSPRep.prototype = { - /** - * Returns a space-separated list of all report uris defined, or 'none' if there are none. - */ - getReportURIs: - function() { - if (!this._directives[CSPRep.URI_DIRECTIVES.REPORT_URI]) - return ""; - return this._directives[CSPRep.URI_DIRECTIVES.REPORT_URI]; - }, - - /** - * Compares this CSPRep instance to another. - */ - equals: - function(that) { - if (this._directives.length != that._directives.length) { - return false; - } - for (var i in this._directives) { - if (!that._directives[i] || !this._directives[i].equals(that._directives[i])) { - return false; - } - } - return (this.allowsInlineScripts === that.allowsInlineScripts) - && (this.allowsEvalInScripts === that.allowsEvalInScripts); - }, - - /** - * Generates string representation of the policy. Should be fairly similar - * to the original. - */ - toString: - function csp_toString() { - var dirs = []; - - if (this._allowEval || this._allowInlineScripts) { - dirs.push("options " + (this._allowEval ? "eval-script" : "") - + (this._allowInlineScripts ? "inline-script" : "")); - } - for (var i in this._directives) { - if (this._directives[i]) { - dirs.push(i + " " + this._directives[i].toString()); - } - } - return dirs.join("; "); - }, - - /** - * Determines if this policy accepts a URI. - * @param aContext - * one of the SRC_DIRECTIVES defined above - * @returns - * true if the policy permits the URI in given context. - */ - permits: - function csp_permits(aURI, aContext) { - if (!aURI) return false; - - // GLOBALLY ALLOW "about:" SCHEME - if (aURI instanceof String && aURI.substring(0,6) === "about:") - return true; - if (aURI instanceof Components.interfaces.nsIURI && aURI.scheme === "about") - return true; - - // make sure the context is valid - for (var i in CSPRep.SRC_DIRECTIVES) { - if (CSPRep.SRC_DIRECTIVES[i] === aContext) { - return this._directives[aContext].permits(aURI); - } - } - return false; - }, - - /** - * Intersects with another CSPRep, deciding the subset policy - * that should be enforced, and returning a new instance. - * @param aCSPRep - * a CSPRep instance to use as "other" CSP - * @returns - * a new CSPRep instance of the intersection - */ - intersectWith: - function cspsd_intersectWith(aCSPRep) { - var newRep = new CSPRep(); - - for (var dir in CSPRep.SRC_DIRECTIVES) { - var dirv = CSPRep.SRC_DIRECTIVES[dir]; - newRep._directives[dirv] = this._directives[dirv] - .intersectWith(aCSPRep._directives[dirv]); - } - - // REPORT_URI - var reportURIDir = CSPRep.URI_DIRECTIVES.REPORT_URI; - if (this._directives[reportURIDir] && aCSPRep._directives[reportURIDir]) { - newRep._directives[reportURIDir] = - this._directives[reportURIDir].concat(aCSPRep._directives[reportURIDir]); - } - else if (this._directives[reportURIDir]) { - // blank concat makes a copy of the string. - newRep._directives[reportURIDir] = this._directives[reportURIDir].concat(); - } - else if (aCSPRep._directives[reportURIDir]) { - // blank concat makes a copy of the string. - newRep._directives[reportURIDir] = aCSPRep._directives[reportURIDir].concat(); - } - - for (var dir in CSPRep.SRC_DIRECTIVES) { - var dirv = CSPRep.SRC_DIRECTIVES[dir]; - newRep._directives[dirv] = this._directives[dirv] - .intersectWith(aCSPRep._directives[dirv]); - } - - newRep._allowEval = this.allowsEvalInScripts - && aCSPRep.allowsEvalInScripts; - - newRep._allowInlineScripts = this.allowsInlineScripts - && aCSPRep.allowsInlineScripts; - - return newRep; - }, - - /** - * Copies default source list to each unspecified directive. - * @returns - * true if the makeExplicit succeeds - * false if it fails (for some weird reason) - */ - makeExplicit: - function cspsd_makeExplicit() { - var SD = CSPRep.SRC_DIRECTIVES; - var allowDir = this._directives[SD.ALLOW]; - if (!allowDir) { - return false; - } - - for (var dir in SD) { - var dirv = SD[dir]; - if (dirv === SD.ALLOW) continue; - if (!this._directives[dirv]) { - // implicit directive, make explicit - this._directives[dirv] = allowDir.clone(); - this._directives[dirv]._isImplicit = true; - } - } - this._isInitialized = true; - return true; - }, - - /** - * Returns true if "eval" is enabled through the "eval" keyword. - */ - get allowsEvalInScripts () { - return this._allowEval; - }, - - /** - * Returns true if inline scripts are enabled through the "inline" - * keyword. - */ - get allowsInlineScripts () { - return this._allowInlineScripts; - }, -}; - -////////////////////////////////////////////////////////////////////// -/** - * Class to represent a list of sources - */ -function CSPSourceList() { - this._sources = []; - this._permitAllSources = false; - - // Set to true when this list is created using "makeExplicit()" - // It's useful to know this when reporting the directive that was violated. - this._isImplicit = false; -} - -/** - * Factory to create a new CSPSourceList, parsed from a string. - * - * @param aStr - * string rep of a CSP Source List - * @param self (optional) - * string or CSPSource representing the "self" source - * @param enforceSelfChecks (optional) - * if present, and "true", will check to be sure "self" has the - * appropriate values to inherit when they are omitted from the source. - * @returns - * an instance of CSPSourceList - */ -CSPSourceList.fromString = function(aStr, self, enforceSelfChecks) { - // Source list is: - // ::= - // | "'none'" - // ::= - // | " " - - var slObj = new CSPSourceList(); - if (aStr === "'none'") - return slObj; - - if (aStr === "*") { - slObj._permitAllSources = true; - return slObj; - } - - var tokens = aStr.split(/\s+/); - for (var i in tokens) { - if (tokens[i] === "") continue; - var src = CSPSource.create(tokens[i], self, enforceSelfChecks); - if (!src) { - CSPWarning("Failed to parse unrecoginzied source " + tokens[i]); - continue; - } - slObj._sources.push(src); - } - - return slObj; -}; - -CSPSourceList.prototype = { - /** - * Compares one CSPSourceList to another. - * - * @param that - * another CSPSourceList - * @returns - * true if they have the same data - */ - equals: - function(that) { - if (that._sources.length != this._sources.length) { - return false; - } - // sort both arrays and compare like a zipper - // XXX (sid): I think we can make this more efficient - var sortfn = function(a,b) { - return a.toString() > b.toString(); - }; - var a_sorted = this._sources.sort(sortfn); - var b_sorted = that._sources.sort(sortfn); - for (var i in a_sorted) { - if (!a_sorted[i].equals(b_sorted[i])) { - return false; - } - } - return true; - }, - - /** - * Generates string representation of the Source List. - * Should be fairly similar to the original. - */ - toString: - function() { - if (this.isNone()) { - return "'none'"; - } - if (this._permitAllSources) { - return "*"; - } - return this._sources.map(function(x) { return x.toString(); }).join(" "); - }, - - /** - * Returns whether or not this source list represents the "'none'" special - * case. - */ - isNone: - function() { - return (!this._permitAllSources) && (this._sources.length < 1); - }, - - /** - * Returns whether or not this source list permits all sources (*). - */ - isAll: - function() { - return this._permitAllSources; - }, - - /** - * Makes a new instance that resembles this object. - * @returns - * a new CSPSourceList - */ - clone: - function() { - var aSL = new CSPSourceList(); - aSL._permitAllSources = this._permitAllSources; - for (var i in this._sources) { - aSL._sources[i] = this._sources[i].clone(); - } - return aSL; - }, - - /** - * Determines if this directive accepts a URI. - * @param aURI - * the URI in question - * @returns - * true if the URI matches a source in this source list. - */ - permits: - function cspsd_permits(aURI) { - if (this.isNone()) return false; - if (this.isAll()) return true; - - for (var i in this._sources) { - if (this._sources[i].permits(aURI)) { - return true; - } - } - return false; - }, - - /** - * Intersects with another CSPSourceList, deciding the subset directive - * that should be enforced, and returning a new instance. - * @param that - * the other CSPSourceList to intersect "this" with - * @returns - * a new instance of a CSPSourceList representing the intersection - */ - intersectWith: - function cspsd_intersectWith(that) { - - var newCSPSrcList = null; - - if (this.isNone() || that.isNone()) - newCSPSrcList = CSPSourceList.fromString("'none'"); - - if (this.isAll()) newCSPSrcList = that.clone(); - if (that.isAll()) newCSPSrcList = this.clone(); - - if (!newCSPSrcList) { - // the shortcuts didn't apply, must do intersection the hard way. - // -- find only common sources - - // XXX (sid): we should figure out a better algorithm for this. - // This is horribly inefficient. - var isrcs = []; - for (var i in this._sources) { - for (var j in that._sources) { - var s = that._sources[j].intersectWith(this._sources[i]); - if (s) { - isrcs.push(s); - } - } - } - // Next, remove duplicates - dup: for (var i = 0; i < isrcs.length; i++) { - for (var j = 0; j < i; j++) { - if (isrcs[i].equals(isrcs[j])) { - isrcs.splice(i, 1); - i--; - continue dup; - } - } - } - newCSPSrcList = new CSPSourceList(); - newCSPSrcList._sources = isrcs; - } - - // if either was explicit, so is this. - newCSPSrcList._isImplicit = this._isImplicit && that._isImplicit; - - return newCSPSrcList; - } -} - -////////////////////////////////////////////////////////////////////// -/** - * Class to model a source (scheme, host, port) - */ -function CSPSource() { - this._scheme = undefined; - this._port = undefined; - this._host = undefined; - - // when set to true, this source represents 'self' - this._isSelf = false; -} - -/** - * General factory method to create a new source from one of the following - * types: - * - nsURI - * - string - * - CSPSource (clone) - */ -CSPSource.create = function(aData, self, enforceSelfChecks) { - if (typeof aData === 'string') - return CSPSource.fromString(aData, self, enforceSelfChecks); - - if (aData instanceof Components.interfaces.nsIURI) - return CSPSource.fromURI(aData, self, enforceSelfChecks); - - if (aData instanceof CSPSource) { - var ns = aData.clone(); - ns._self = CSPSource.create(self); - return ns; - } - - return null; -} - -/** - * Factory to create a new CSPSource, from a nsIURI. - * - * Don't use this if you want to wildcard ports! - * - * @param aURI - * nsIURI rep of a URI - * @param self (optional) - * string or CSPSource representing the "self" source - * @param enforceSelfChecks (optional) - * if present, and "true", will check to be sure "self" has the - * appropriate values to inherit when they are omitted from aURI. - * @returns - * an instance of CSPSource - */ -CSPSource.fromURI = function(aURI, self, enforceSelfChecks) { - if (!(aURI instanceof Components.interfaces.nsIURI)){ - CSPError("Provided argument is not an nsIURI"); - return null; - } - - if (!self && enforceSelfChecks) { - CSPError("Can't use 'self' if self data is not provided"); - return null; - } - - if (self && !(self instanceof CSPSource)) { - self = CSPSource.create(self, undefined, false); - } - - var sObj = new CSPSource(); - sObj._self = self; - - // PARSE - // If 'self' is undefined, then use default port for scheme if there is one. - - // grab scheme (if there is one) - try { - sObj._scheme = aURI.scheme; - } catch(e) { - sObj._scheme = undefined; - CSPError("can't parse a URI without a scheme: " + aURI.asciiSpec); - return null; - } - - // grab host (if there is one) - try { - // if there's no host, an exception will get thrown - // (NS_ERROR_FAILURE) - sObj._host = CSPHost.fromString(aURI.host); - } catch(e) { - sObj._host = undefined; - } - - // grab port (if there is one) - // creating a source from an nsURI is limited in that one cannot specify "*" - // for port. In fact, there's no way to represent "*" differently than - // a blank port in an nsURI, since "*" turns into -1, and so does an - // absence of port declaration. - try { - // if there's no port, an exception will get thrown - // (NS_ERROR_FAILURE) - if (aURI.port > 0) { - sObj._port = aURI.port; - } else { - // port is never inherited from self -- this gets too confusing. - // Instead, whatever scheme is used (an explicit one or the inherited - // one) dictates the port if no port is explicitly stated. - if (sObj._scheme) { - sObj._port = gIoService.getProtocolHandler(sObj._scheme).defaultPort; - if (sObj._port < 1) - sObj._port = undefined; - } - } - } catch(e) { - sObj._port = undefined; - } - - return sObj; -}; - -/** - * Factory to create a new CSPSource, parsed from a string. - * - * @param aStr - * string rep of a CSP Source - * @param self (optional) - * string or CSPSource representing the "self" source - * @param enforceSelfChecks (optional) - * if present, and "true", will check to be sure "self" has the - * appropriate values to inherit when they are omitted from aURI. - * @returns - * an instance of CSPSource - */ -CSPSource.fromString = function(aStr, self, enforceSelfChecks) { - if (!aStr) - return null; - - if (!(typeof aStr === 'string')) { - CSPError("Provided argument is not a string"); - return null; - } - - if (!self && enforceSelfChecks) { - CSPError("Can't use 'self' if self data is not provided"); - return null; - } - - if (self && !(self instanceof CSPSource)) { - self = CSPSource.create(self, undefined, false); - } - - var sObj = new CSPSource(); - sObj._self = self; - - // take care of 'self' keyword - if (aStr === "'self'") { - if (!self) { - CSPError("self keyword used, but no self data specified"); - return null; - } - sObj._isSelf = true; - sObj._self = self.clone(); - return sObj; - } - - // We could just create a URI and then send this off to fromURI, but - // there's no way to leave out the scheme or wildcard the port in an nsURI. - // That has to be supported here. - - // split it up - var chunks = aStr.split(":"); - - // If there is only one chunk, it's gotta be a host. - if (chunks.length == 1) { - sObj._host = CSPHost.fromString(chunks[0]); - if (!sObj._host) { - CSPError("Couldn't parse invalid source " + aStr); - return null; - } - - // enforce 'self' inheritance - if (enforceSelfChecks) { - // note: the non _scheme accessor checks sObj._self - if (!sObj.scheme || !sObj.port) { - CSPError("Can't create host-only source " + aStr + " without 'self' data"); - return null; - } - } - return sObj; - } - - // If there are two chunks, it's either scheme://host or host:port - // ... but scheme://host can have an empty host. - // ... and host:port can have an empty host - if (chunks.length == 2) { - - // is the last bit a port? - if (chunks[1] === "*" || chunks[1].match(/^\d+$/)) { - sObj._port = chunks[1]; - // then the previous chunk *must* be a host or empty. - if (chunks[0] !== "") { - sObj._host = CSPHost.fromString(chunks[0]); - if (!sObj._host) { - CSPError("Couldn't parse invalid source " + aStr); - return null; - } - } - // enforce 'self' inheritance - // (scheme:host requires port, host:port does too. Wildcard support is - // only available if the scheme and host are wildcarded) - if (enforceSelfChecks) { - // note: the non _scheme accessor checks sObj._self - if (!sObj.scheme || !sObj.host || !sObj.port) { - CSPError("Can't create source " + aStr + " without 'self' data"); - return null; - } - } - } - // is the first bit a scheme? - else if (CSPSource.validSchemeName(chunks[0])) { - sObj._scheme = chunks[0]; - // then the second bit *must* be a host or empty - if (chunks[1] === "") { - // Allow scheme-only sources! These default to wildcard host/port, - // especially since host and port don't always matter. - // Example: "javascript:" and "data:" - if (!sObj._host) sObj._host = "*"; - if (!sObj._port) sObj._port = "*"; - } else { - // some host was defined. - // ... remove <= 3 leading slashes (from the scheme) and parse - var cleanHost = chunks[1].replace(/^\/{0,3}/,""); - // ... and parse - sObj._host = CSPHost.fromString(cleanHost); - if (!sObj._host) { - CSPError("Couldn't parse invalid host " + cleanHost); - return null; - } - } - - // enforce 'self' inheritance (scheme-only should be scheme:*:* now, and - // if there was a host provided it should be scheme:host:selfport - if (enforceSelfChecks) { - // note: the non _scheme accessor checks sObj._self - if (!sObj.scheme || !sObj.host || !sObj.port) { - CSPError("Can't create source " + aStr + " without 'self' data"); - return null; - } - } - } - else { - // AAAH! Don't know what to do! No valid scheme or port! - CSPError("Couldn't parse invalid source " + aStr); - return null; - } - - return sObj; - } - - // If there are three chunks, we got 'em all! - if (!CSPSource.validSchemeName(chunks[0])) { - CSPError("Couldn't parse scheme in " + aStr); - return null; - } - sObj._scheme = chunks[0]; - if (!(chunks[2] === "*" || chunks[2].match(/^\d+$/))) { - CSPError("Couldn't parse port in " + aStr); - return null; - } - - sObj._port = chunks[2]; - - // ... remove <= 3 leading slashes (from the scheme) and parse - var cleanHost = chunks[1].replace(/^\/{0,3}/,""); - sObj._host = CSPHost.fromString(cleanHost); - - return sObj._host ? sObj : null; -}; - -CSPSource.validSchemeName = function(aStr) { - // ::= - // ::= - // | - // ::= | | "+" | "." | "-" - - return aStr.match(/^[a-zA-Z][a-zA-Z0-9+.-]*$/); -}; - -CSPSource.prototype = { - - get scheme () { - if (!this._scheme && this._self) - return this._self.scheme; - return this._scheme; - }, - - get host () { - if (!this._host && this._self) - return this._self.host; - return this._host; - }, - - /** - * If 'self' has port hard-defined, and this doesn't have a port - * hard-defined, use the self's port. Otherwise, if both are implicit, - * resolve default port for this scheme. - */ - get port () { - if (this._port) return this._port; - // if no port, get the default port for the scheme. - if (this._scheme) { - try { - var port = gIoService.getProtocolHandler(this._scheme).defaultPort; - if (port > 0) return port; - } catch(e) { - // if any errors happen, fail gracefully. - } - } - // if there was no scheme (and thus no default scheme), return self.port - if (this._self && this._self.port) return this._self.port; - - return undefined; - }, - - /** - * Generates string representation of the Source. - * Should be fairly similar to the original. - */ - toString: - function() { - if (this._isSelf) - return this._self.toString(); - - var s = ""; - if (this._scheme) - s = s + this._scheme + "://"; - if (this._host) - s = s + this._host; - if (this._port) - s = s + ":" + this._port; - return s; - }, - - /** - * Makes a new instance that resembles this object. - * @returns - * a new CSPSource - */ - clone: - function() { - var aClone = new CSPSource(); - aClone._self = this._self ? this._self.clone() : undefined; - aClone._scheme = this._scheme; - aClone._port = this._port; - aClone._host = this._host ? this._host.clone() : undefined; - aClone._isSelf = this._isSelf; - return aClone; - }, - - /** - * Determines if this Source accepts a URI. - * @param aSource - * the URI, or CSPSource in question - * @returns - * true if the URI matches a source in this source list. - */ - permits: - function(aSource) { - if (!aSource) return false; - - if (!(aSource instanceof CSPSource)) - return this.permits(CSPSource.create(aSource)); - - // verify scheme - if (this.scheme != aSource.scheme) - return false; - - // port is defined in 'this' (undefined means it may not be relevant - // to the scheme) AND this port (implicit or explicit) matches - // aSource's port - if (this.port && this.port !== "*" && this.port != aSource.port) - return false; - - // host is defined in 'this' (undefined means it may not be relevant - // to the scheme) AND this host (implicit or explicit) permits - // aSource's host. - if (this.host && !this.host.permits(aSource.host)) - return false; - - // all scheme, host and port matched! - return true; - }, - - /** - * Determines the intersection of two sources. - * Returns a null object if intersection generates no - * hosts that satisfy it. - * @param that - * the other CSPSource to intersect "this" with - * @returns - * a new instance of a CSPSource representing the intersection - */ - intersectWith: - function(that) { - var newSource = new CSPSource(); - - // 'self' is not part of the intersection. Intersect the raw values from - // the source, self must be set by someone creating this source. - // When intersecting, we take the more specific of the two: if one scheme, - // host or port is undefined, the other is taken. (This is contrary to - // when "permits" is called -- there, the value of 'self' is looked at - // when a scheme, host or port is undefined.) - - // port - if (!this._port) - newSource._port = that._port; - else if (!that._port) - newSource._port = this._port; - else if (this._port === "*") - newSource._port = that._port; - else if (that._port === "*") - newSource._port = this._port; - else if (that._port === this._port) - newSource._port = this._port; - else { - CSPError("Could not intersect " + this + " with " + that - + " due to port problems."); - return null; - } - - // scheme - if (!this._scheme) - newSource._scheme = that._scheme; - else if (!that._scheme) - newSource._scheme = this._scheme; - if (this._scheme === "*") - newSource._scheme = that._scheme; - else if (that._scheme === "*") - newSource._scheme = this._scheme; - else if (that._scheme === this._scheme) - newSource._scheme = this._scheme; - else { - CSPError("Could not intersect " + this + " with " + that - + " due to scheme problems."); - return null; - } - - // host - if (!this._host) - newSource._host = that._host; - else if (!that._host) - newSource._host = this._host; - else // both this and that have hosts - newSource._host = this._host.intersectWith(that._host); - - return newSource; - }, - - /** - * Compares one CSPSource to another. - * - * @param that - * another CSPSource - * @param resolveSelf (optional) - * if present, and 'true', implied values are obtained from 'self' - * instead of assumed to be "anything" - * @returns - * true if they have the same data - */ - equals: - function(that, resolveSelf) { - // 1. schemes match - // 2. ports match - // 3. either both hosts are undefined, or one equals the other. - if (resolveSelf) - return this.scheme === that.scheme - && this.port === that.port - && (!(this.host || that.host) || - (this.host && this.host.equals(that.host))); - - // otherwise, compare raw (non-self-resolved values) - return this._scheme === that._scheme - && this._port === that._port - && (!(this._host || that._host) || - (this._host && this._host.equals(that._host))); - }, - -}; - -////////////////////////////////////////////////////////////////////// -/** - * Class to model a host *.x.y. - */ -function CSPHost() { - this._segments = []; -} - -/** - * Factory to create a new CSPHost, parsed from a string. - * - * @param aStr - * string rep of a CSP Host - * @returns - * an instance of CSPHost - */ -CSPHost.fromString = function(aStr) { - if (!aStr) return null; - - // host string must be LDH with dots and stars. - var invalidChar = aStr.match(/[^a-zA-Z0-9\-\.\*]/); - if (invalidChar) { - CSPdebug("Invalid character '" + invalidChar + "' in host " + aStr); - return null; - } - - var hObj = new CSPHost(); - hObj._segments = aStr.split(/\./); - if (hObj._segments.length < 1 || - hObj._segments.length == 1 && hObj._segments[0] != "*" - && hObj._segments[0] != "localhost") { - // only short hosts allowed are "*" and "localhost" - return null; - } - - // validate data in segments - for (var i in hObj._segments) { - var seg = hObj._segments[i]; - if (seg == "*") { - if (i > 0) { - // Wildcard must be FIRST - CSPdebug("Wildcard char located at invalid position in '" + aStr + "'"); - return null; - } - } - else if (seg.match(/[^a-zA-Z0-9\-]/)) { - // Non-wildcard segment must be LDH string - CSPdebug("Invalid segment '" + seg + "' in host value"); - return null; - } - } - return hObj; -}; - -CSPHost.prototype = { - /** - * Generates string representation of the Source. - * Should be fairly similar to the original. - */ - toString: - function() { - return this._segments.join("."); - }, - - /** - * Makes a new instance that resembles this object. - * @returns - * a new CSPHost - */ - clone: - function() { - var aHost = new CSPHost(); - for (var i in this._segments) { - aHost._segments[i] = this._segments[i]; - } - return aHost; - }, - - /** - * Returns true if this host accepts the provided host (or the other way - * around). - * @param aHost - * the FQDN in question (CSPHost or String) - * @returns - */ - permits: - function(aHost) { - if (!aHost) return false; - - if (!(aHost instanceof CSPHost)) { - // -- compare CSPHost to String - return this.permits(CSPHost.fromString(aHost)); - } - var thislen = this._segments.length; - var thatlen = aHost._segments.length; - - // don't accept a less specific host: - // \--> *.b.a doesn't accept b.a. - if (thatlen < thislen) { return false; } - - // check for more specific host (and wildcard): - // \--> *.b.a accepts d.c.b.a. - // \--> c.b.a doesn't accept d.c.b.a. - if ((thatlen > thislen) && this._segments[0] != "*") { - return false; - } - - // Given the wildcard condition (from above), - // only necessary to compare elements that are present - // in this host. Extra tokens in aHost are ok. - // * Compare from right to left. - for (var i=1; i <= thislen; i++) { - if (this._segments[thislen-i] != "*" && - (this._segments[thislen-i] != aHost._segments[thatlen-i])) { - return false; - } - } - - // at this point, all conditions are met, so the host is allowed - return true; - }, - - /** - * Determines the intersection of two Hosts. - * Basically, they must be the same, or one must have a wildcard. - * @param that - * the other CSPHost to intersect "this" with - * @returns - * a new instance of a CSPHost representing the intersection - * (or null, if they can't be intersected) - */ - intersectWith: - function(that) { - if (!(this.permits(that) || that.permits(this))) { - // host definitions cannot co-exist without a more general host - // ... one must be a subset of the other, or intersection makes no sense. - return null; - } - - // pick the more specific one, if both are same length. - if (this._segments.length == that._segments.length) { - // *.a vs b.a : b.a - return (this._segments[0] === "*") ? that.clone() : this.clone(); - } - - // different lengths... - // *.b.a vs *.a : *.b.a - // *.b.a vs d.c.b.a : d.c.b.a - return (this._segments.length > that._segments.length) ? - this.clone() : that.clone(); - }, - - /** - * Compares one CSPHost to another. - * - * @param that - * another CSPHost - * @returns - * true if they have the same data - */ - equals: - function(that) { - if (this._segments.length != that._segments.length) - return false; - - for (var i=0; i - * Brandon Sterne - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - - -/** - * Content Security Policy - * - * Overview - * This is a stub component that will be fleshed out to do all the fancy stuff - * that ContentSecurityPolicy has to do. - */ - -/* :::::::: Constants and Helpers ::::::::::::::: */ - -const Cc = Components.classes; -const Ci = Components.interfaces; -const Cr = Components.results; -const Cu = Components.utils; - -const CSP_VIOLATION_TOPIC = "csp-on-violate-policy"; - -Cu.import("resource://gre/modules/XPCOMUtils.jsm"); -Cu.import("resource://gre/modules/CSPUtils.jsm"); - -/* ::::: Policy Parsing & Data structures :::::: */ - -function ContentSecurityPolicy() { - CSPdebug("CSP CREATED"); - this._isInitialized = false; - this._reportOnlyMode = false; - this._policy = CSPRep.fromString("allow *"); - - // default options "wide open" since this policy will be intersected soon - this._policy._allowInlineScripts = true; - this._policy._allowEval = true; - - this._requestHeaders = []; - this._request = ""; - CSPdebug("CSP POLICY INITED TO 'allow *'"); - - this._observerService = Cc['@mozilla.org/observer-service;1'] - .getService(Ci.nsIObserverService); -} - -/* - * Set up mappings from nsIContentPolicy content types to CSP directives. - */ -{ - let cp = Ci.nsIContentPolicy; - let csp = ContentSecurityPolicy; - let cspr_sd = CSPRep.SRC_DIRECTIVES; - - csp._MAPPINGS=[]; - - /* default, catch-all case */ - csp._MAPPINGS[cp.TYPE_OTHER] = cspr_sd.ALLOW; - - /* self */ - csp._MAPPINGS[cp.TYPE_DOCUMENT] = null; - - /* shouldn't see this one */ - csp._MAPPINGS[cp.TYPE_REFRESH] = null; - - /* categorized content types */ - csp._MAPPINGS[cp.TYPE_SCRIPT] = cspr_sd.SCRIPT_SRC; - csp._MAPPINGS[cp.TYPE_IMAGE] = cspr_sd.IMG_SRC; - csp._MAPPINGS[cp.TYPE_STYLESHEET] = cspr_sd.STYLE_SRC; - csp._MAPPINGS[cp.TYPE_OBJECT] = cspr_sd.OBJECT_SRC; - csp._MAPPINGS[cp.TYPE_SUBDOCUMENT] = cspr_sd.FRAME_SRC; - csp._MAPPINGS[cp.TYPE_MEDIA] = cspr_sd.MEDIA_SRC; - csp._MAPPINGS[cp.TYPE_FONT] = cspr_sd.FONT_SRC; - csp._MAPPINGS[cp.TYPE_XMLHTTPREQUEST] = cspr_sd.XHR_SRC; - - - /* These must go through the catch-all */ - csp._MAPPINGS[cp.TYPE_XBL] = cspr_sd.ALLOW; - csp._MAPPINGS[cp.TYPE_PING] = cspr_sd.ALLOW; - csp._MAPPINGS[cp.TYPE_OBJECT_SUBREQUEST] = cspr_sd.ALLOW; - csp._MAPPINGS[cp.TYPE_DTD] = cspr_sd.ALLOW; -} - -ContentSecurityPolicy.prototype = { - classDescription: "Content Security Policy Component", - contractID: "@mozilla.org/contentsecuritypolicy;1", - classID: Components.ID("{AB36A2BF-CB32-4AA6-AB41-6B4E4444A221}"), - QueryInterface: XPCOMUtils.generateQI([Ci.IContentSecurityPolicy]), - - // get this contractID registered for certain categories via XPCOMUtils - _xpcom_categories: [ ], - - get isInitialized() { - return this._isInitialized; - }, - - set isInitialized (foo) { - this._isInitialized = foo; - }, - - get policy () { - return this._policy.toString(); - }, - - get allowsInlineScript() { - // trigger automatic report to go out when inline scripts are disabled. - if (!this._policy.allowsInlineScripts) { - var violation = 'violated base restriction: Inline Scripts will not execute'; - // gotta wrap the violation string, since it's sent out to observers as - // an nsISupports. - let wrapper = Cc["@mozilla.org/supports-cstring;1"] - .createInstance(Ci.nsISupportsCString); - wrapper.data = violation; - this._observerService.notifyObservers( - wrapper, - CSP_VIOLATION_TOPIC, - 'inline script base restriction'); - this.sendReports('self', violation); - } - return this._reportOnlyMode || this._policy.allowsInlineScripts; - }, - - get allowsEval() { - // trigger automatic report to go out when eval and friends are disabled. - if (!this._policy.allowsEvalInScripts) { - var violation = 'violated base restriction: Code will not be created from strings'; - // gotta wrap the violation string, since it's sent out to observers as - // an nsISupports. - let wrapper = Cc["@mozilla.org/supports-cstring;1"] - .createInstance(Ci.nsISupportsCString); - wrapper.data = violation; - this._observerService.notifyObservers( - wrapper, - CSP_VIOLATION_TOPIC, - 'eval script base restriction'); - this.sendReports('self', violation); - } - return this._reportOnlyMode || this._policy.allowsEvalInScripts; - }, - - set reportOnlyMode(val) { - this._reportOnlyMode = val; - }, - - get reportOnlyMode () { - return this._reportOnlyMode; - }, - - /* - // Having a setter is a bad idea... opens up the policy to "loosening" - // Instead, use "refinePolicy." - set policy (aStr) { - this._policy = CSPRep.fromString(aStr); - }, - */ - - /** - * Given an nsIHttpChannel, fill out the appropriate data. - */ - scanRequestData: - function(aChannel) { - // grab the request line - var internalChannel = aChannel.QueryInterface(Ci.nsIHttpChannelInternal); - var reqMaj = {}; - var reqMin = {}; - var reqVersion = internalChannel.getRequestVersion(reqMaj, reqMin); - this._request = aChannel.requestMethod + " " - + aChannel.URI.asciiSpec - + " HTTP/" + reqMaj.value + "." + reqMin.value; - - // grab the request headers - var self = this; - aChannel.visitRequestHeaders({ - visitHeader: function(aHeader, aValue) { - self._requestHeaders.push(aHeader + ": " + aValue); - }}); - }, - -/* ........ Methods .............. */ - - /** - * Given a new policy, intersects the currently enforced policy with the new - * one and stores the result. The effect is a "tightening" or refinement of - * an old policy. This is called any time a new policy is encountered and - * the effective policy has to be refined. - */ - refinePolicy: - function csp_refinePolicy(aPolicy, selfURI) { - CSPdebug("REFINE POLICY: " + aPolicy); - CSPdebug(" SELF: " + selfURI.asciiSpec); - - // stay uninitialized until policy merging is done - this._isInitialized = false; - - // If there is a policy-uri, fetch the policy, then re-call this function. - // (1) parse and create a CSPRep object - var newpolicy = CSPRep.fromString(aPolicy, - selfURI.scheme + "://" + selfURI.hostPort); - - // (2) Intersect the currently installed CSPRep object with the new one - var intersect = this._policy.intersectWith(newpolicy); - - // (3) Save the result - this._policy = intersect; - this._isInitialized = true; - }, - - /** - * Generates and sends a violation report to the specified report URIs. - */ - sendReports: - function(blockedUri, violatedDirective) { - var uriString = this._policy.getReportURIs(); - var uris = uriString.split(/\s+/); - if (uris.length > 0) { - // Generate report to send composed of: - // - // GET /index.html HTTP/1.1 - // Host: example.com - // User-Agent: ... - // ... - // - // ... - // ... - // - // - var strHeaders = ""; - for (let i in this._requestHeaders) { - strHeaders += this._requestHeaders[i] + "\n"; - } - - var report = "\n" + - " " + this._request + "\n" + - " \n" + - " " + - (typeof blockedUri === "nsIURI" ? blockedUri.asciiSpec : blockedUri) + - "\n" + - " " + violatedDirective + "\n" + - "\n"; - - CSPdebug("Constructed violation report:\n" + report); - - // For each URI in the report list, send out a report. - for (let i in uris) { - if (uris[i] === "") - continue; - - var failure = function(aEvt) { - if (req.readyState == 4 && req.status != 200) { - CSPError("Failed to send report to " + reportURI); - } - }; - var req = Cc["@mozilla.org/xmlextras/xmlhttprequest;1"] - .createInstance(Ci.nsIXMLHttpRequest); - - try { - req.open("POST", uris[i], true); - req.setRequestHeader('Content-Type', 'application/xml'); - req.upload.addEventListener("error", failure, false); - req.upload.addEventListener("abort", failure, false); - //req.channel.loadFlags |= Ci.nsIRequest.LOAD_BYPASS_CACHE; - - // make request anonymous - // This prevents sending cookies with the request, - // in case the policy URI is injected, it can't be - // abused for CSRF. - req.channel.loadFlags |= Ci.nsIChannel.LOAD_ANONYMOUS; - - req.send(report); - CSPdebug("Sent violation report to " + uris[i]); - } catch(e) { - // it's possible that the URI was invalid, just log a - // warning and skip over that. - CSPWarning("Tried to send report to invalid URI: \"" + uris[i] + "\""); - } - } - } - }, - - /** - * Exposed Method to analyze docShell for approved frame ancestry. - * Also sends violation reports if necessary. - * @param docShell - * the docShell for this policy's resource. - * @return - * true if the frame ancestry is allowed by this policy. - */ - permitsAncestry: - function(docShell) { - if (!docShell) { return false; } - CSPdebug(" in permitsAncestry(), docShell = " + docShell); - - // walk up this docShell tree until we hit chrome - var dst = docShell.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIDocShellTreeItem); - - // collect ancestors and make sure they're allowed. - var ancestors = []; - while (dst.parent) { - dst = dst.parent; - let it = dst.QueryInterface(Ci.nsIInterfaceRequestor) - .getInterface(Ci.nsIWebNavigation); - if (it.currentURI) { - if (it.currentURI.scheme === "chrome") { - break; - } - let ancestor = it.currentURI; - CSPdebug(" found frame ancestor " + ancestor.asciiSpec); - ancestors.push(ancestor); - } - } - - // scan the discovered ancestors - let cspContext = CSPRep.SRC_DIRECTIVES.FRAME_ANCESTORS; - for (let i in ancestors) { - let ancestor = ancestors[i].prePath; - if (!this._policy.permits(ancestor, cspContext)) { - // report the frame-ancestor violation - let directive = this._policy._directives[cspContext]; - let violatedPolicy = (directive._isImplicit - ? 'allow' : 'frame-ancestors ') - + directive.toString(); - // send an nsIURI object to the observers (more interesting than a string) - this._observerService.notifyObservers( - ancestors[i], - CSP_VIOLATION_TOPIC, - violatedPolicy); - this.sendReports(ancestors[i].asciiSpec, violatedPolicy); - // need to lie if we are testing in report-only mode - return this._reportOnlyMode; - } - } - return true; - }, - - /** - * Delegate method called by the service when sub-elements of the protected - * document are being loaded. Given a bit of information about the request, - * decides whether or not the policy is satisfied. - */ - shouldLoad: - function csp_shouldLoad(aContentType, - aContentLocation, - aRequestOrigin, - aContext, - aMimeTypeGuess, - aExtra) { - - // don't filter chrome stuff - if (aContentLocation.scheme === 'chrome') { - return Ci.nsIContentPolicy.ACCEPT; - } - - // interpret the context, and then pass off to the decision structure - CSPdebug("shouldLoad location = " + aContentLocation.asciiSpec); - CSPdebug("shouldLoad content type = " + aContentType); - var cspContext = ContentSecurityPolicy._MAPPINGS[aContentType]; - // CSPdebug("shouldLoad CSP directive =" + cspContext); - - // if the mapping is null, there's no policy, let it through. - if (!cspContext) { - return Ci.nsIContentPolicy.ACCEPT; - } - - // otherwise, honor the translation - // var source = aContentLocation.scheme + "://" + aContentLocation.hostPort; - var res = this._policy.permits(aContentLocation, cspContext) - ? Ci.nsIContentPolicy.ACCEPT - : Ci.nsIContentPolicy.REJECT_SERVER; - - // frame-ancestors is taken care of early on (as this document is loaded) - - // If the result is *NOT* ACCEPT, then send report - if (res != Ci.nsIContentPolicy.ACCEPT) { - CSPdebug("blocking request for " + aContentLocation.asciiSpec); - try { - let directive = this._policy._directives[cspContext]; - let violatedPolicy = (directive._isImplicit - ? 'allow' : cspContext) - + ' ' + directive.toString(); - this._observerService.notifyObservers( - aContentLocation, - CSP_VIOLATION_TOPIC, - violatedPolicy); - this.sendReports(aContentLocation, violatedPolicy); - } catch(e) { - CSPdebug('---------------- ERROR: ' + e); - } - } - - return (this._reportOnlyMode ? Ci.nsIContentPolicy.ACCEPT : res); - }, - - shouldProcess: - function csp_shouldProcess(aContentType, - aContentLocation, - aRequestOrigin, - aContext, - aMimeType, - aExtra) { - // frame-ancestors check is done outside the ContentPolicy - var res = Ci.nsIContentPolicy.ACCEPT; - CSPdebug("shouldProcess aContext=" + aContext); - return res; - }, - -}; - - - -function NSGetModule(aComMgr, aFileSpec) - XPCOMUtils.generateModule([ContentSecurityPolicy]); diff --git a/content/base/src/nsCSPService.cpp b/content/base/src/nsCSPService.cpp deleted file mode 100644 index 813819ba526..00000000000 --- a/content/base/src/nsCSPService.cpp +++ /dev/null @@ -1,214 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brandon Sterne - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "prlog.h" -#include "nsString.h" -#include "nsCOMPtr.h" -#include "nsIURI.h" -#include "nsIPrincipal.h" -#include "nsIObserver.h" -#include "nsIDocument.h" -#include "nsIContent.h" -#include "nsContentUtils.h" -#include "nsCSPService.h" -#include "IContentSecurityPolicy.h" - -/* Keeps track of whether or not CSP is enabled */ -static PRBool gCSPEnabled = PR_TRUE; - -#ifdef PR_LOGGING -static PRLogModuleInfo* gCspPRLog; -#endif - -CSPService::CSPService() -{ - nsContentUtils::AddBoolPrefVarCache("security.csp.enable", &gCSPEnabled); - -#ifdef PR_LOGGING - if (!gCspPRLog) - gCspPRLog = PR_NewLogModule("CSP"); -#endif -} - -CSPService::~CSPService() -{ -} - -NS_IMPL_ISUPPORTS1(CSPService, nsIContentPolicy) - -/* nsIContentPolicy implementation */ -NS_IMETHODIMP -CSPService::ShouldLoad(PRUint32 aContentType, - nsIURI *aContentLocation, - nsIURI *aRequestOrigin, - nsISupports *aRequestContext, - const nsACString &aMimeTypeGuess, - nsISupports *aExtra, - PRInt16 *aDecision) -{ - if (!aContentLocation) - return NS_ERROR_FAILURE; - -#ifdef PR_LOGGING - { - nsCAutoString location; - aContentLocation->GetSpec(location); - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("CSPService::ShouldLoad called for %s", location.get())); - } -#endif - // default decision, CSP can revise it if there's a policy to enforce - *aDecision = nsIContentPolicy::ACCEPT; - - // No need to continue processing if CSP is disabled - if (!gCSPEnabled) - return NS_OK; - - // find the nsDocument that initiated this request and see if it has a - // CSP policy object - nsresult rv; - nsCOMPtr doc; - nsCOMPtr principal; - nsCOMPtr csp; - nsCOMPtr node(do_QueryInterface(aRequestContext)); - if (node) { - doc = node->GetOwnerDoc(); - } - if (!doc) { - doc = do_QueryInterface(aRequestContext); - } - - if (doc) { - principal = doc->NodePrincipal(); - principal->GetCsp(getter_AddRefs(csp)); - - if (csp) { -#ifdef PR_LOGGING - nsAutoString policy; - csp->GetPolicy(policy); - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("Document has CSP: %s", - NS_ConvertUTF16toUTF8(policy).get())); -#endif - // obtain the enforcement decision - csp->ShouldLoad(aContentType, - aContentLocation, - aRequestOrigin, - aRequestContext, - aMimeTypeGuess, - aExtra, - aDecision); - } - } -#ifdef PR_LOGGING - else { - nsCAutoString uriSpec; - aContentLocation->GetSpec(uriSpec); - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("COULD NOT get nsIDocument for location: %s", uriSpec.get())); - } -#endif - - return NS_OK; -} - -NS_IMETHODIMP -CSPService::ShouldProcess(PRUint32 aContentType, - nsIURI *aContentLocation, - nsIURI *aRequestOrigin, - nsISupports *aRequestContext, - const nsACString &aMimeTypeGuess, - nsISupports *aExtra, - PRInt16 *aDecision) -{ - if (!aContentLocation) - return NS_ERROR_FAILURE; - - // default decision is to accept the item - *aDecision = nsIContentPolicy::ACCEPT; - - // No need to continue processing if CSP is disabled - if (!gCSPEnabled) - return NS_OK; - - // find the nsDocument that initiated this request and see if it has a - // CSP policy object - nsresult rv; - nsCOMPtr doc; - nsCOMPtr principal; - nsCOMPtr csp; - nsCOMPtr node(do_QueryInterface(aRequestContext)); - if (node) { - doc = node->GetOwnerDoc(); - } - if (!doc) { - doc = do_QueryInterface(aRequestContext); - } - - if (doc) { - principal = doc->NodePrincipal(); - principal->GetCsp(getter_AddRefs(csp)); - - if (csp) { -#ifdef PR_LOGGING - nsAutoString policy; - csp->GetPolicy(policy); - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("shouldProcess - document has policy: %s", - NS_ConvertUTF16toUTF8(policy).get())); -#endif - // obtain the enforcement decision - csp->ShouldProcess(aContentType, - aContentLocation, - aRequestOrigin, - aRequestContext, - aMimeTypeGuess, - aExtra, - aDecision); - } - } -#ifdef PR_LOGGING - else { - nsCAutoString uriSpec; - aContentLocation->GetSpec(uriSpec); - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("COULD NOT get nsIDocument for location: %s", uriSpec.get())); - } -#endif - return NS_OK; -} diff --git a/content/base/src/nsCSPService.h b/content/base/src/nsCSPService.h deleted file mode 100644 index a1e056164cd..00000000000 --- a/content/base/src/nsCSPService.h +++ /dev/null @@ -1,57 +0,0 @@ -/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is mozilla.org code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation. - * Portions created by the Initial Developer are Copyright (C) 2009 - * the Initial Developer. All Rights Reserved. - * - * Contributor(s): - * Brandon Sterne - * - * Alternatively, the contents of this file may be used under the terms of - * either of the GNU General Public License Version 2 or later (the "GPL"), - * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -#include "nsXPCOM.h" -#include "nsIContentPolicy.h" - -#define CSPSERVICE_CONTRACTID "@mozilla.org/cspservice;1" -#define CSPSERVICE_CID \ - { 0x8d2f40b2, 0x4875, 0x4c95, \ - { 0x97, 0xd9, 0x3f, 0x7d, 0xca, 0x2c, 0xb4, 0x60 } } -class CSPService : public nsIContentPolicy -{ -public: - NS_DECL_ISUPPORTS - NS_DECL_NSICONTENTPOLICY - - CSPService(); - virtual ~CSPService(); - -private: - PRBool mEnabled; -}; diff --git a/content/base/src/nsDocument.cpp b/content/base/src/nsDocument.cpp index 2f20b1635db..8fd3149d78f 100644 --- a/content/base/src/nsDocument.cpp +++ b/content/base/src/nsDocument.cpp @@ -181,9 +181,6 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID); #include "nsSVGUtils.h" #endif // MOZ_SMIL -// FOR CSP (autogenerated by xpidl) -#include "IContentSecurityPolicy.h" - #ifdef MOZ_LOGGING // so we can get logging even in release builds @@ -191,12 +188,8 @@ static NS_DEFINE_CID(kDOMEventGroupCID, NS_DOMEVENTGROUP_CID); #endif #include "prlog.h" -/* Keeps track of whether or not CSP is enabled */ -static PRBool gCSPEnabled = PR_TRUE; - #ifdef PR_LOGGING static PRLogModuleInfo* gDocumentLeakPRLog; -static PRLogModuleInfo* gCspPRLog; #endif void @@ -1502,13 +1495,8 @@ nsDocument::nsDocument(const char* aContentType) if (gDocumentLeakPRLog) PR_LOG(gDocumentLeakPRLog, PR_LOG_DEBUG, ("DOCUMENT %p created", this)); - - if (!gCspPRLog) - gCspPRLog = PR_NewLogModule("CSP"); #endif - nsContentUtils::AddBoolPrefVarCache("security.csp.enable", &gCSPEnabled); - // Start out mLastStyleSheetSet as null, per spec SetDOMStringToNull(mLastStyleSheetSet); } @@ -2263,114 +2251,10 @@ nsDocument::StartDocumentLoad(const char* aCommand, nsIChannel* aChannel, RetrieveRelevantHeaders(aChannel); mChannel = aChannel; - - nsresult rv = InitCSP(); - NS_ENSURE_SUCCESS(rv, rv); return NS_OK; } -nsresult -nsDocument::InitCSP() -{ - if (gCSPEnabled) { - nsAutoString cspHeaderValue; - nsAutoString cspROHeaderValue; - - this->GetHeaderData(nsGkAtoms::headerCSP, cspHeaderValue); - this->GetHeaderData(nsGkAtoms::headerCSPReportOnly, cspROHeaderValue); - - PRBool system = PR_FALSE; - nsIScriptSecurityManager *ssm = nsContentUtils::GetSecurityManager(); - - if (NS_SUCCEEDED(ssm->IsSystemPrincipal(NodePrincipal(), &system)) && system) { - // only makes sense to register new CSP if this document is not priviliged - return NS_OK; - } - - if (cspHeaderValue.IsEmpty() && cspROHeaderValue.IsEmpty()) { - // no CSP header present, stop processing - return NS_OK; - } - -#ifdef PR_LOGGING - PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP header specified for document %p", this)); -#endif - - nsresult rv; - nsCOMPtr mCSP; - mCSP = do_CreateInstance("@mozilla.org/contentsecuritypolicy;1", &rv); - - if (NS_FAILED(rv)) { -#ifdef PR_LOGGING - PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("Failed to create CSP object: %x", rv)); -#endif - return rv; - } - - // Store the request context for violation reports - nsCOMPtr httpChannel = do_QueryInterface(mChannel); - mCSP->ScanRequestData(httpChannel); - - // Start parsing the policy - nsCOMPtr chanURI; - mChannel->GetURI(getter_AddRefs(chanURI)); - -#ifdef PR_LOGGING - PR_LOG(gCspPRLog, PR_LOG_DEBUG, ("CSP Loaded")); -#endif - - // ReportOnly mode is enabled *only* if there are no regular-strength CSP - // headers present. If there are, then we ignore the ReportOnly mode and - // toss a warning into the error console, proceeding with enforcing the - // regular-strength CSP. - if (cspHeaderValue.IsEmpty()) { - mCSP->SetReportOnlyMode(true); - mCSP->RefinePolicy(cspROHeaderValue, chanURI); -#ifdef PR_LOGGING - { - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("CSP (report only) refined, policy: \"%s\"", - NS_ConvertUTF16toUTF8(cspROHeaderValue).get())); - } -#endif - } else { - //XXX(sstamm): maybe we should post a warning when both read only and regular - // CSP headers are present. - mCSP->RefinePolicy(cspHeaderValue, chanURI); -#ifdef PR_LOGGING - { - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("CSP refined, policy: \"%s\"", - NS_ConvertUTF16toUTF8(cspHeaderValue).get())); - } -#endif - } - - //Copy into principal - nsIPrincipal* principal = GetPrincipal(); - - if (principal) { - principal->SetCsp(mCSP); -#ifdef PR_LOGGING - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("Inserted CSP into principal %p", principal)); - } - else { - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("Couldn't copy CSP into absent principal %p", principal)); -#endif - } - } -#ifdef PR_LOGGING - else { //CSP was not enabled! - PR_LOG(gCspPRLog, PR_LOG_DEBUG, - ("CSP is disabled, skipping CSP init for document %p", this)); - } -#endif - return NS_OK; -} - void nsDocument::StopDocumentLoad() { @@ -6758,8 +6642,6 @@ nsDocument::RetrieveRelevantHeaders(nsIChannel *aChannel) "content-disposition", "refresh", "x-dns-prefetch-control", - "x-content-security-policy", - "x-content-security-policy-read-only", // add more http headers if you need // XXXbz don't add content-location support without reading bug // 238654 and its dependencies/dups first. diff --git a/content/base/src/nsDocument.h b/content/base/src/nsDocument.h index 4ad6ccd0a15..3a829c2d628 100644 --- a/content/base/src/nsDocument.h +++ b/content/base/src/nsDocument.h @@ -1211,8 +1211,6 @@ private: void PostUnblockOnloadEvent(); void DoUnblockOnload(); - nsresult InitCSP(); - /** * See if aDocument is a child of this. If so, return the frame element in * this document that holds currentDoc (or an ancestor). diff --git a/content/base/src/nsGkAtomList.h b/content/base/src/nsGkAtomList.h index cc800ee4a12..8cd6af9acc3 100644 --- a/content/base/src/nsGkAtomList.h +++ b/content/base/src/nsGkAtomList.h @@ -1007,8 +1007,6 @@ GK_ATOM(withParam, "with-param") GK_ATOM(wizard, "wizard") GK_ATOM(wrap, "wrap") GK_ATOM(headerDNSPrefetchControl,"x-dns-prefetch-control") -GK_ATOM(headerCSP, "x-content-security-policy") -GK_ATOM(headerCSPReportOnly, "x-content-security-policy-report-only") GK_ATOM(xml, "xml") GK_ATOM(xmlns, "xmlns") GK_ATOM(xmp, "xmp") diff --git a/content/base/test/Makefile.in b/content/base/test/Makefile.in index 6f8b2cf6222..fa81473572a 100644 --- a/content/base/test/Makefile.in +++ b/content/base/test/Makefile.in @@ -333,10 +333,6 @@ _TEST_FILES = test_bug5141.html \ test_bug503481b.html \ file_bug503481b_inner.html \ test_viewport_scroll.html \ - test_CSP.html \ - file_CSP.sjs \ - file_CSP_main.html \ - file_CSP_main.js \ $(NULL) # Disabled; see bug 492181 diff --git a/content/base/test/file_CSP.sjs b/content/base/test/file_CSP.sjs deleted file mode 100644 index b31158ca853..00000000000 --- a/content/base/test/file_CSP.sjs +++ /dev/null @@ -1,44 +0,0 @@ -// SJS file for CSP mochitests - -function handleRequest(request, response) -{ - var query = {}; - request.queryString.split('&').forEach(function (val) { - var [name, value] = val.split('='); - query[name] = unescape(value); - }); - - var isPreflight = request.method == "OPTIONS"; - - - //avoid confusing cache behaviors - response.setHeader("Cache-Control", "no-cache", false); - - if ("main" in query) { - var xhr = Components.classes["@mozilla.org/xmlextras/xmlhttprequest;1"] - .createInstance(Components.interfaces.nsIXMLHttpRequest); - //serve the main page with a CSP header! - // -- anything served from 'self' (localhost:8888) will be allowed, - // -- anything served from other hosts (example.com:80) will be blocked. - // -- XHR tests are set up in the file_CSP_main.js file which is sourced. - response.setHeader("X-Content-Security-Policy", - "allow 'self'", - false); - xhr.open("GET", "http://localhost:8888/tests/content/base/test/file_CSP_main.html", false); - xhr.send(null); - if(xhr.status == 200) { - response.write(xhr.responseText); - } - } else { - if ("type" in query) { - response.setHeader("Content-Type", unescape(query['type']), false); - } else { - response.setHeader("Content-Type", "text/html", false); - } - - if ("content" in query) { - response.setHeader("Content-Type", "text/html", false); - response.write(unescape(query['content'])); - } - } -} diff --git a/content/base/test/file_CSP_main.html b/content/base/test/file_CSP_main.html deleted file mode 100644 index 1b86486bc2a..00000000000 --- a/content/base/test/file_CSP_main.html +++ /dev/null @@ -1,55 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
arbitrary good
-
arbitrary_bad
- - diff --git a/content/base/test/file_CSP_main.js b/content/base/test/file_CSP_main.js deleted file mode 100644 index f2d12ff85e8..00000000000 --- a/content/base/test/file_CSP_main.js +++ /dev/null @@ -1,16 +0,0 @@ -// some javascript for the CSP XHR tests -// - -try { - var xhr_good = new XMLHttpRequest(); - var xhr_good_uri ="http://localhost:8888/tests/content/base/test/file_CSP.sjs?testid=xhr_good"; - xhr_good.open("GET", xhr_good_uri, true); - xhr_good.send(null); -} catch(e) {} - -try { - var xhr_bad = new XMLHttpRequest(); - var xhr_bad_uri ="http://example.com/tests/content/base/test/file_CSP.sjs?testid=xhr_bad"; - xhr_bad.open("GET", xhr_bad_uri, true); - xhr_bad.send(null); -} catch(e) {} diff --git a/content/base/test/test_CSP.html b/content/base/test/test_CSP.html deleted file mode 100644 index 3875e387fa1..00000000000 --- a/content/base/test/test_CSP.html +++ /dev/null @@ -1,127 +0,0 @@ - - - - Test for Content Security Policy Connections - - - - - -

- - - - - - - diff --git a/content/base/test/unit/test_csputils.js b/content/base/test/unit/test_csputils.js deleted file mode 100644 index a7a46807c91..00000000000 --- a/content/base/test/unit/test_csputils.js +++ /dev/null @@ -1,497 +0,0 @@ -/* ***** BEGIN LICENSE BLOCK ***** - * Version: MPL 1.1/GPL 2.0/LGPL 2.1 - * - * The contents of this file are subject to the Mozilla Public License Version - * 1.1 (the "License"); you may not use this file except in compliance with - * the License. You may obtain a copy of the License at - * http://www.mozilla.org/MPL/ - * - * Software distributed under the License is distributed on an "AS IS" basis, - * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License - * for the specific language governing rights and limitations under the - * License. - * - * The Original Code is the Content Security Policy Data Structures testing code. - * - * The Initial Developer of the Original Code is - * Mozilla Corporation - * - * Contributor(s): - * Sid Stamm - * - * Alternatively, the contents of this file may be used under the terms of - * either the GNU General Public License Version 2 or later (the "GPL"), or - * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), - * in which case the provisions of the GPL or the LGPL are applicable instead - * of those above. If you wish to allow use of your version of this file only - * under the terms of either the GPL or the LGPL, and not to allow others to - * use your version of this file under the terms of the MPL, indicate your - * decision by deleting the provisions above and replace them with the notice - * and other provisions required by the GPL or the LGPL. If you do not delete - * the provisions above, a recipient may use your version of this file under - * the terms of any one of the MPL, the GPL or the LGPL. - * - * ***** END LICENSE BLOCK ***** */ - -//load('CSPUtils.jsm'); -Components.utils.import('resource://gre/modules/CSPUtils.jsm'); - -// load the HTTP server -do_load_httpd_js(); - -var httpServer = new nsHttpServer(); - -const POLICY_FROM_URI = "allow 'self'; img-src *"; -const POLICY_PORT = 9000; -const POLICY_URI = "http://localhost:" + POLICY_PORT + "/policy"; - -// helper to assert that an object or array must have a given key -function do_check_has_key(foo, key, stack) { - if (!stack) - stack = Components.stack.caller; - - var keys = []; - for(let k in keys) { keys.push(k); } - var text = key + " in [" + keys.join(",") + "]"; - - for(var x in foo) { - if(x == key) { - //succeed - ++_passedChecks; - dump("TEST-PASS | " + stack.filename + " | [" + stack.name + " : " + - stack.lineNumber + "] " + text + "\n"); - return; - } - } - do_throw(text, stack); -} - -// helper to use .equals on stuff -function do_check_equivalent(foo, bar, stack) { - if (!stack) - stack = Components.stack.caller; - - var text = foo + ".equals(" + bar + ")"; - - if(foo.equals && foo.equals(bar)) { - ++_passedChecks; - dump("TEST-PASS | " + stack.filename + " | [" + stack.name + " : " + - stack.lineNumber + "] " + text + "\n"); - return; - } - do_throw(text, stack); -} - -var tests = []; -function test(fcn) { - tests.push(fcn); -} - -test( - function test_CSPHost_fromstring() { - var h; - - h = CSPHost.fromString("*"); - do_check_neq(null, h); // "* lone wildcard should work" - - h = CSPHost.fromString("foo.bar"); - do_check_neq(null, h); // "standard tuple failed" - - h = CSPHost.fromString("*.bar"); - do_check_neq(null, h); // "wildcard failed" - - h = CSPHost.fromString("foo.*.bar"); - do_check_eq(null, h); // "wildcard in wrong place worked" - - h = CSPHost.fromString("com"); - do_check_eq(null, h); // "lone symbol should fail" - - h = CSPHost.fromString("f00b4r.com"); - do_check_neq(null, h); // "Numbers in hosts should work" - - h = CSPHost.fromString("foo-bar.com"); - do_check_neq(null, h); // "dashes in hosts should work" - - h = CSPHost.fromString("foo!bar.com"); - do_check_eq(null, h); // "special chars in hosts should fail" - }); - -test( - function test_CSPHost_clone() { - h = CSPHost.fromString("*.a.b.c"); - h2 = h.clone(); - for(var i in h._segments) { - // "cloned segments should match" - do_check_eq(h._segments[i], h2._segments[i]); - } - }); - -test( - function test_CSPHost_permits() { - var h = CSPHost.fromString("*.b.c"); - var h2 = CSPHost.fromString("a.b.c"); - do_check_true( h.permits(h2)); //"CSPHost *.b.c should allow CSPHost a.b.c" - do_check_true( h.permits("a.b.c")); //"CSPHost *.b.c should allow string a.b.c" - do_check_false(h.permits("b.c")); //"CSPHost *.b.c should not allow string b.c" - do_check_false(h.permits("a.a.c")); //"CSPHost *.b.c should not allow string a.a.c" - do_check_false(h2.permits(h)); //"CSPHost a.b.c should not allow CSPHost *.b.c" - do_check_false(h2.permits("b.c")); //"CSPHost a.b.c should not allow string b.c" - do_check_true( h2.permits("a.b.c")); //"CSPHost a.b.c should allow string a.b.c" - }); - -test( - function test_CSPHost_intersectWith() { - var h = CSPHost.fromString("*.b.c"); - //"*.a.b.c ^ *.b.c should be *.a.b.c" - do_check_eq("*.a.b.c", h.intersectWith(CSPHost.fromString("*.a.b.c")).toString()); - - //"*.b.c ^ *.d.e should not work (null)" - do_check_eq(null, h.intersectWith(CSPHost.fromString("*.d.e"))); - }); - -///////////////////// Test the Source object ////////////////////// - -test( - function test_CSPSource_fromString() { - // can't do these tests because "self" is not defined. - //"basic source should not be null."); - do_check_neq(null, CSPSource.fromString("a.com")); - - //"ldh characters should all work for host."); - do_check_neq(null, CSPSource.fromString("a2-c.com")); - - //"wildcard should work in first token for host."); - do_check_neq(null, CSPSource.fromString("*.a.com")); - - //print(" --- Ignore the following two errors if they print ---"); - //"wildcard should not work in non-first token for host."); - do_check_eq(null, CSPSource.fromString("x.*.a.com")); - - //"funny characters (#) should not work for host."); - do_check_eq(null, CSPSource.fromString("a#2-c.com")); - //print(" --- Stop ignoring errors that print ---\n"); - - //"failed to parse host with port."); - do_check_neq(null, CSPSource.create("a.com:23")); - //"failed to parse host with scheme."); - do_check_neq(null, CSPSource.create("https://a.com")); - //"failed to parse host with scheme and port."); - do_check_neq(null, CSPSource.create("https://a.com:200")); - }); - -test( - function test_CSPSource_fromString_withSelf() { - var src; - src = CSPSource.create("a.com", "https://foobar.com:443"); - //"src should inherit port * - do_check_true(src.permits("https://a.com:443")); - //"src should inherit and require https scheme - do_check_false(src.permits("http://a.com")); - //"src should inherit scheme 'https'" - do_check_true(src.permits("https://a.com")); - - src = CSPSource.create("http://a.com", "https://foobar.com:443"); - //"src should inherit and require http scheme" - do_check_false(src.permits("https://a.com")); - //"src should inherit scheme 'http'" - do_check_true(src.permits("http://a.com")); - //"src should inherit port and scheme from parent" - //"src should inherit default port for 'http'" - do_check_true(src.permits("http://a.com:80")); - - src = CSPSource.create("'self'", "https://foobar.com:443"); - //"src should inherit port * - do_check_true(src.permits("https://foobar.com:443")); - //"src should inherit and require https scheme - do_check_false(src.permits("http://foobar.com")); - //"src should inherit scheme 'https'" - do_check_true(src.permits("https://foobar.com")); - //"src should reject other hosts" - do_check_false(src.permits("https://a.com")); - }); - -///////////////////// Test the source list ////////////////////// - -test( - function test_CSPSourceList_fromString() { - var sd = CSPSourceList.fromString("'none'"); - //"'none' -- should parse" - do_check_neq(null,sd); - // "'none' should be a zero-length list" - do_check_eq(0, sd._sources.length); - do_check_true(sd.isNone()); - - sd = CSPSourceList.fromString("*"); - //"'*' should be a zero-length list" - do_check_eq(0, sd._sources.length); - - //print(" --- Ignore the following three errors if they print ---"); - //"funny char in host" - do_check_true(CSPSourceList.fromString("f!oo.bar").isNone()); - //"funny char in scheme" - do_check_true(CSPSourceList.fromString("ht!ps://f-oo.bar").isNone()); - //"funny char in port" - do_check_true(CSPSourceList.fromString("https://f-oo.bar:3f").isNone()); - //print(" --- Stop ignoring errors that print ---\n"); - }); - -test( - function test_CSPSourceList_fromString_twohost() { - var str = "foo.bar:21 https://ras.bar"; - var parsed = "foo.bar:21 https://ras.bar"; - var sd = CSPSourceList.fromString(str, "http://self.com:80"); - //"two-host list should parse" - do_check_neq(null,sd); - //"two-host list should parse to two hosts" - do_check_eq(2, sd._sources.length); - //"two-host list should contain original data" - do_check_eq(parsed, sd.toString()); - }); - -test( - function test_CSPSourceList_permits() { - var nullSourceList = CSPSourceList.fromString("'none'"); - var simpleSourceList = CSPSourceList.fromString("a.com", "http://self.com"); - var doubleSourceList = CSPSourceList.fromString("https://foo.com http://bar.com:88", - "http://self.com:88"); - var allSourceList = CSPSourceList.fromString("*"); - - //'none' should permit none." - do_check_false( nullSourceList.permits("http://a.com")); - //a.com should permit a.com" - do_check_true( simpleSourceList.permits("http://a.com")); - //wrong host" - do_check_false( simpleSourceList.permits("http://b.com")); - //double list permits http://bar.com:88" - do_check_true( doubleSourceList.permits("http://bar.com:88")); - //double list permits https://bar.com:88" - do_check_false( doubleSourceList.permits("https://bar.com:88")); - //double list does not permit http://bar.com:443" - do_check_false( doubleSourceList.permits("http://bar.com:443")); - //"double list permits https://foo.com:88" (should not inherit port) - do_check_false( doubleSourceList.permits("https://foo.com:88")); - //"double list does not permit foo.com on http" - do_check_false( doubleSourceList.permits("http://foo.com")); - - //"* does not permit specific host" - do_check_true( allSourceList.permits("http://x.com:23")); - //"* does not permit a long host with no port" - do_check_true( allSourceList.permits("http://a.b.c.d.e.f.g.h.i.j.k.l.x.com")); - - }); - -test( - function test_CSPSourceList_intersect() { - // for this test, 'self' values are irrelevant - // policy a /\ policy b intersects policies, not context (where 'self' - // values come into play) - var nullSourceList = CSPSourceList.fromString("'none'"); - var simpleSourceList = CSPSourceList.fromString("a.com"); - var doubleSourceList = CSPSourceList.fromString("https://foo.com http://bar.com:88"); - var singleFooSourceList = CSPSourceList.fromString("https://foo.com"); - var allSourceList = CSPSourceList.fromString("*"); - - //"Intersection of one source with 'none' source list should be none."); - do_check_true(nullSourceList.intersectWith(simpleSourceList).isNone()); - //"Intersection of two sources with 'none' source list should be none."); - do_check_true(nullSourceList.intersectWith(doubleSourceList).isNone()); - //"Intersection of '*' with 'none' source list should be none."); - do_check_true(nullSourceList.intersectWith(allSourceList).isNone()); - - //"Intersection of one source with '*' source list should be one source."); - do_check_equivalent(allSourceList.intersectWith(simpleSourceList), - simpleSourceList); - //"Intersection of two sources with '*' source list should be two sources."); - do_check_equivalent(allSourceList.intersectWith(doubleSourceList), - doubleSourceList); - - //"Non-overlapping source lists should intersect to 'none'"); - do_check_true(simpleSourceList.intersectWith(doubleSourceList).isNone()); - - //"subset and superset should intersect to subset."); - do_check_equivalent(singleFooSourceList, - doubleSourceList.intersectWith(singleFooSourceList)); - - //TODO: write more tests? - - }); - -///////////////////// Test the Whole CSP rep object ////////////////////// - -test( - function test_CSPRep_fromString() { - - // check default init - //ASSERT(!(new CSPRep())._isInitialized, "Uninitialized rep thinks it is.") - - var cspr; - var cspr_allowval; - - // check default policy "allow *" - cspr = CSPRep.fromString("allow *", "http://self.com:80"); - //"ALLOW directive is missing when specified in fromString" - do_check_has_key(cspr._directives, CSPRep.SRC_DIRECTIVES.ALLOW); - - // ... and check that the other directives were auto-filled with the - // ALLOW one. - var SD = CSPRep.SRC_DIRECTIVES; - cspr_allowval = cspr._directives[SD.ALLOW]; - for(var d in CSPRep.SRC_DIRECTIVES) { - //"Missing key " + d - do_check_has_key(cspr._directives, SD[d]); - //"Implicit directive " + d + " has non-allow value." - do_check_eq(cspr._directives[SD[d]].toString(), cspr_allowval.toString()); - } - }); - - -test( - function test_CSPRep_fromString_oneDir() { - - var cspr; - var SD = CSPRep.SRC_DIRECTIVES; - var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.IMG_SRC, - SD.FRAME_ANCESTORS, SD.FRAME_SRC]; - - // check one-directive policies - cspr = CSPRep.fromString("allow bar.com; script-src https://foo.com", - "http://self.com"); - - for(var x in DEFAULTS) { - //DEFAULTS[x] + " does not use default rule." - do_check_false(cspr.permits("http://bar.com:22", DEFAULTS[x])); - //DEFAULTS[x] + " does not use default rule." - do_check_true(cspr.permits("http://bar.com:80", DEFAULTS[x])); - //DEFAULTS[x] + " does not use default rule." - do_check_false(cspr.permits("https://foo.com:400", DEFAULTS[x])); - //DEFAULTS[x] + " does not use default rule." - do_check_false(cspr.permits("https://foo.com", DEFAULTS[x])); - } - //"script-src false positive in policy. - do_check_false(cspr.permits("http://bar.com:22", SD.SCRIPT_SRC)); - //"script-src false negative in policy. - do_check_true(cspr.permits("https://foo.com:443", SD.SCRIPT_SRC)); - }); - -test( - function test_CSPRep_fromString_twodir() { - var cspr; - var SD = CSPRep.SRC_DIRECTIVES; - var DEFAULTS = [SD.STYLE_SRC, SD.MEDIA_SRC, SD.FRAME_ANCESTORS, SD.FRAME_SRC]; - - // check two-directive policies - var polstr = "allow allow.com; " - + "script-src https://foo.com; " - + "img-src bar.com:*"; - cspr = CSPRep.fromString(polstr, "http://self.com"); - - for(var x in DEFAULTS) { - do_check_true(cspr.permits("http://allow.com", DEFAULTS[x])); - //DEFAULTS[x] + " does not use default rule. - do_check_false(cspr.permits("https://foo.com:400", DEFAULTS[x])); - //DEFAULTS[x] + " does not use default rule. - do_check_false(cspr.permits("http://bar.com:400", DEFAULTS[x])); - //DEFAULTS[x] + " does not use default rule. - } - //"img-src does not use default rule. - do_check_false(cspr.permits("http://allow.com:22", SD.IMG_SRC)); - //"img-src does not use default rule. - do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC)); - //"img-src does not use default rule. - do_check_true(cspr.permits("http://bar.com:88", SD.IMG_SRC)); - - //"script-src does not use default rule. - do_check_false(cspr.permits("http://allow.com:22", SD.SCRIPT_SRC)); - //"script-src does not use default rule. - do_check_true(cspr.permits("https://foo.com:443", SD.SCRIPT_SRC)); - //"script-src does not use default rule. - do_check_false(cspr.permits("http://bar.com:400", SD.SCRIPT_SRC)); - }); - -test(function test_CSPRep_fromString_withself() { - var cspr; - var SD = CSPRep.SRC_DIRECTIVES; - var self = "https://self.com:34"; - - // check one-directive policies - cspr = CSPRep.fromString("allow 'self'; script-src 'self' https://*:*", - self); - //"img-src does not enforce default rule, 'self'. - do_check_false(cspr.permits("https://foo.com:400", SD.IMG_SRC)); - //"img-src does not allow self - CSPdebug(cspr); - do_check_true(cspr.permits(self, SD.IMG_SRC)); - //"script-src is too relaxed - do_check_false(cspr.permits("http://evil.com", SD.SCRIPT_SRC)); - //"script-src should allow self - do_check_true(cspr.permits(self, SD.SCRIPT_SRC)); - //"script-src is too strict on host/port - do_check_true(cspr.permits("https://evil.com:100", SD.SCRIPT_SRC)); - }); - -///////////////////// TEST POLICY_URI ////////////////////// -test(function test_CSPRep_fromPolicyURI() { - var cspr; - var SD = CSPRep.SRC_DIRECTIVES; - var self = "http://localhost:" + POLICY_PORT; - - cspr = CSPRep.fromString("policy-uri " + POLICY_URI, self); - cspr_static = CSPRep.fromString(POLICY_FROM_URI, self); - - //"policy-uri failed to load" - do_check_neq(null,cspr); - - // other directives inherit self - for(var i in SD) { - //SD[i] + " parsed wrong from policy uri" - do_check_equivalent(cspr._directives[SD[i]], - cspr_static._directives[SD[i]]); - } - }); -/* - -test(function test_CSPRep_fromPolicyURI_failswhenmixed() { - var cspr; - var self = "http://localhost:" + POLICY_PORT; - var closed_policy = CSPRep.fromString("allow 'none'"); - var my_uri_policy = "policy-uri " + POLICY_URI; - - //print(" --- Ignore the following two errors if they print ---"); - cspr = CSPRep.fromString("allow *; " + my_uri_policy, self); - - //"Parsing should fail when 'policy-uri' is mixed with allow directive" - do_check_equivalent(cspr, closed_policy); - cspr = CSPRep.fromString("img-src 'self'; " + my_uri_policy, self); - - //"Parsing should fail when 'policy-uri' is mixed with other directives" - do_check_equivalent(cspr, closed_policy); - //print(" --- Stop ignoring errors that print ---\n"); - - }); -*/ - -// TODO: test reporting -// TODO: test refinements (?) -// TODO: test 'eval' and 'inline' keywords - -function run_test() { - function policyresponder(request,response) { - response.setStatusLine(request.httpVersion, 200, "OK"); - response.setHeader("Content-Type", "text/csp", false); - response.bodyOutputStream.write(POLICY_FROM_URI, POLICY_FROM_URI.length); - } - //server.registerDirectory("/", nsILocalFileForBasePath); - httpServer.registerPathHandler("/policy", policyresponder); - httpServer.start(POLICY_PORT); - - for(let i in tests) { - tests[i](); - } - - //teardown - httpServer.stop(function() { }); - do_test_finished(); -} - - - diff --git a/layout/build/nsLayoutModule.cpp b/layout/build/nsLayoutModule.cpp index dbe1f0be1ed..52be6f8fd3f 100644 --- a/layout/build/nsLayoutModule.cpp +++ b/layout/build/nsLayoutModule.cpp @@ -268,7 +268,6 @@ static void Shutdown(); #endif #include "nsGeolocation.h" -#include "nsCSPService.h" // Transformiix /* {0C351177-0159-4500-86B0-A219DFDE4258} */ @@ -849,60 +848,6 @@ NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsGeolocation, Init) NS_GENERIC_FACTORY_SINGLETON_CONSTRUCTOR(nsGeolocationService, nsGeolocationService::GetGeolocationService) -static NS_METHOD -CSPServiceRegistration(nsIComponentManager *aCompMgr, - nsIFile *aPath, - const char *registryLocation, - const char *componentType, - const nsModuleComponentInfo *info) -{ - nsresult rv; - nsCOMPtr servman = do_QueryInterface((nsISupports*)aCompMgr, &rv); - if (NS_FAILED(rv)) - return rv; - - nsCOMPtr catman; - rv = servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID, - NS_GET_IID(nsICategoryManager), - getter_AddRefs(catman)); - if (NS_FAILED(rv)) - return rv; - - nsXPIDLCString previous; - rv = catman->AddCategoryEntry("content-policy", - "CSPService", - CSPSERVICE_CONTRACTID, - PR_TRUE, - PR_TRUE, - getter_Copies(previous)); - return rv; -} - -static NS_METHOD -CSPServiceUnregistration(nsIComponentManager *aCompMgr, - nsIFile *aPath, - const char *registryLocation, - const nsModuleComponentInfo *info){ - nsresult rv; - - nsCOMPtr servman = do_QueryInterface((nsISupports*)aCompMgr, &rv); - if (NS_FAILED(rv)) return rv; - - nsCOMPtr catman; - rv = servman->GetServiceByContractID(NS_CATEGORYMANAGER_CONTRACTID, - NS_GET_IID(nsICategoryManager), - getter_AddRefs(catman)); - if (NS_FAILED(rv)) return rv; - - rv = catman->DeleteCategoryEntry("content-policy", - "CSPService", - PR_TRUE); - - return rv; -} - -NS_GENERIC_FACTORY_CONSTRUCTOR(CSPService) - // The list of components we register static const nsModuleComponentInfo gComponents[] = { #ifdef DEBUG @@ -1508,12 +1453,6 @@ static const nsModuleComponentInfo gComponents[] = { "@mozilla.org/focus-manager;1", CreateFocusManager }, - { "Content Security Policy Service", - CSPSERVICE_CID, - CSPSERVICE_CONTRACTID, - CSPServiceConstructor, - CSPServiceRegistration, - CSPServiceUnregistration }, { "Event Listener Service", NS_EVENTLISTENERSERVICE_CID, diff --git a/modules/libpref/src/init/all.js b/modules/libpref/src/init/all.js index a704c5d88fb..04b27863a34 100644 --- a/modules/libpref/src/init/all.js +++ b/modules/libpref/src/init/all.js @@ -950,8 +950,6 @@ pref("security.xpconnect.plugin.unrestricted", true); // security-sensitive dialogs should delay button enabling. In milliseconds. pref("security.dialog_enable_delay", 2000); -pref("security.csp.enable", true); - // Modifier key prefs: default to Windows settings, // menu access key = alt, accelerator key = control. // Use 17 for Ctrl, 18 for Alt, 224 for Meta, 0 for none. Mac settings in macprefs.js