Index: third_party/WebKit/Source/devtools/front_end/sdk/CSPParser.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/sdk/CSPParser.js b/third_party/WebKit/Source/devtools/front_end/sdk/CSPParser.js |
new file mode 100644 |
index 0000000000000000000000000000000000000000..8d4350ee85c44eb4e4832ec46d7260ea4a49df48 |
--- /dev/null |
+++ b/third_party/WebKit/Source/devtools/front_end/sdk/CSPParser.js |
@@ -0,0 +1,275 @@ |
+// Copyright 2016 The Chromium Authors. All rights reserved. |
+// Use of this source code is governed by a BSD-style license that can be |
+// found in the LICENSE file. |
+ |
+/** |
+ * @constructor |
+ * |
+ * @property {!Array<!WebInspector.CSPParser.Policy>} policies - An Array of policies that belong to the security policy. |
+ * @property {string} reportUri - The URI that reports are submitted to. "Not Set" if no URI is given. |
+ * |
+ * @param {!Array<!WebInspector.CSPParser.Policy>} policies |
+ * @param {?string} reportUri |
+ */ |
+WebInspector.CSPParser = class { |
+ constructor(policies, reportUri) { |
+ this._policies = policies; |
+ this._reportUri = reportUri ? reportUri : "Not Set"; |
+ } |
+ |
+ /** |
+ * @return {!Array<!WebInspector.CSPParser.Policy>} |
+ */ |
+ get policies() { |
+ return this._policies; |
+ } |
+ |
+ /** |
+ * @returns {string|null} |
+ */ |
+ get reportUri() { |
+ return this._reportUri; |
+ } |
+ |
+ /** |
+ * @param {string} string |
+ * @param {boolean} reportOnly |
+ * @returns {!WebInspector.CSPParser} |
+ */ |
+ static buildFromString(string, reportOnly) { |
+ let items = string.split(";"); |
+ let policies = []; |
+ items.forEach(value => { |
+ let policyName = undefined; |
+ let rules = []; |
+ value.trim().split(" ").filter(d => !!d).forEach(item => { |
+ if (! policyName && item.trim() !== "") { |
+ policyName = item; |
+ return; |
+ } |
+ let obj = WebInspector.CSPParser.Rule.build(item, reportOnly); |
+ rules.push(obj); |
+ }); |
+ let policy = WebInspector.CSPParser.Policy.build(/** @type {string} */ (policyName), rules); |
+ policies.push(policy); |
+ }); |
+ let reportUri = null; |
+ let reportPolicy = policies.filter(item => item.name === "report-uri")[0]; |
+ if (reportPolicy) { |
+ policies.splice(policies.indexOf(reportPolicy), 1); |
+ reportUri = reportPolicy.rules[0].value; |
+ } |
+ return new WebInspector.CSPParser(policies, reportUri); |
+ } |
+} |
+ |
+/** |
+ * @enum {string} |
+ */ |
+WebInspector.CSPParser.Location = { |
+ Header: "Header", |
+ Meta: "Meta Tag" |
+}; |
+ |
+/** |
+ * @enum {string} |
+ */ |
+WebInspector.CSPParser.SecurityLevel = { |
+ Safe: "safe", |
+ PossiblyUnsafe: "possibly-unsafe", |
+ Unsafe: "unsafe", |
+ Deprecated: "deprecated" |
+}; |
+ |
+/** |
+ * @enum {string} |
+ */ |
+WebInspector.CSPParser.DeprecatedRules = { |
+ "frame-src": "Use child-src instead, unless you are supporting browsers that use CSP 1.0 only." |
+}; |
+ |
+/** |
+ * @constructor |
+ * |
+ * @property {string} humanReadableSecurityState - A human-readable form of the security state |
+ * @property {string} value - The value of the rule for the property. |
+ * @property {!WebInspector.CSPParser.SecurityLevel} securityState - Security state of the rule |
+ * @property {string|undefined} reason - Reason for the given security state. |
+ * @property {boolean} reportOnly - Whether the rule is in report-only mode. |
+ * |
+ * @param {string} value |
+ * @param {!WebInspector.CSPParser.SecurityLevel} securityState |
+ * @param {string|undefined} reason |
+ * @param {boolean} reportOnly |
+ */ |
+WebInspector.CSPParser.Rule = class { |
+ constructor(value, securityState, reason, reportOnly) |
+ { |
+ this._value = value; |
+ this._securityState = securityState; |
+ this._reason = reason; |
+ this._reportOnly = reportOnly; |
+ } |
+ |
+ /** |
+ * @return {string} |
+ */ |
+ get value() { |
+ return this._value; |
+ } |
+ |
+ /** |
+ * @return {!WebInspector.CSPParser.SecurityLevel} |
+ */ |
+ get securityState() { |
+ return /** @type {!WebInspector.CSPParser.SecurityLevel} */ (this._securityState); |
+ } |
+ |
+ /** |
+ * @returns {string} |
+ */ |
+ get humanReadableSecurityState() { |
+ let securityState = this._securityState; |
+ securityState = securityState.split("-").join(" "); |
+ return securityState.charAt(0).toUpperCase() + securityState.slice(1); |
+ } |
+ |
+ /** |
+ * @return {string|undefined} |
+ */ |
+ get reason() { |
+ return this._reason; |
+ } |
+ |
+ /** |
+ * @return {boolean} |
+ */ |
+ get location() { |
+ return this._reportOnly; |
+ } |
+ |
+ /** |
+ * Suppress invalid cast since the reason type is correct, interpreter seems to have issues. |
+ * @suppress {invalidCasts} |
+ * @param {string} item - The item to build a rule from. |
+ * @param {boolean} reportOnly - Whether the rule is in report-only mode. |
+ * @return WebInspector.CSPParser.Rule |
+ */ |
+ static build(item, reportOnly) { |
+ let securityState = WebInspector.CSPParser.SecurityLevel.Safe; |
+ let reason = undefined; |
+ |
+ let unsafeRules = [ |
+ "'unsafe-eval'", |
+ "'unsafe-inline'" |
+ ]; |
+ |
+ if (item.includes("*")) { |
+ securityState = WebInspector.CSPParser.SecurityLevel.PossiblyUnsafe; |
+ reason = "Consider removing wildcard"; |
+ } |
+ if (unsafeRules.indexOf(item) > -1) { |
+ securityState = WebInspector.CSPParser.SecurityLevel.Unsafe; |
+ reason = "XSS Risk"; |
+ } |
+ |
+ return new WebInspector.CSPParser.Rule(item, securityState, reason, reportOnly); |
+ } |
+} |
+ |
+/** |
+ * @constructor |
+ * @property {string} name - The policy name provided. |
+ * @property {!WebInspector.CSPParser.SecurityLevel} securityState - Security state of the policy |
+ * @property {!Array<!WebInspector.CSPParser.Rule>} rules - Rules of the policy. |
+ * @property {boolean} deprecated - Indicate whether the policy is deprecated. |
+ * @property {string|undefined} securityStateReason - Reason for the given security state. |
+ * @property {string} humanReadableSecurityState - A human-readable form of the security state |
+ * |
+ * @param {string} name |
+ * @param {!WebInspector.CSPParser.SecurityLevel} securityState |
+ * @param {!Array<!WebInspector.CSPParser.Rule>} rules |
+ * @param {boolean} deprecated |
+ */ |
+WebInspector.CSPParser.Policy = class { |
+ constructor(name, securityState, rules, deprecated) |
+ { |
+ this._name = name; |
+ this._securityState = securityState; |
+ this._rules = rules; |
+ this._deprecated = deprecated; |
+ } |
+ |
+ /** |
+ * @returns {string} |
+ */ |
+ get name() { |
+ return this._name; |
+ } |
+ |
+ /** |
+ * @returns {!WebInspector.CSPParser.SecurityLevel} |
+ */ |
+ get securityState() { |
+ return /** @type {!WebInspector.CSPParser.SecurityLevel} */ (this._securityState); |
+ } |
+ |
+ /** |
+ * @returns {boolean} |
+ */ |
+ get deprecated() { |
+ return this._deprecated; |
+ } |
+ |
+ /** |
+ * @returns {string} |
+ */ |
+ get humanReadableSecurityState() { |
+ let securityState = this._securityState; |
+ if (this._deprecated) { |
+ securityState += " and " + WebInspector.CSPParser.SecurityLevel.Deprecated; |
+ } |
+ securityState = securityState.split("-").join(" "); |
+ return securityState.charAt(0).toUpperCase() + securityState.slice(1); |
+ } |
+ |
+ /** |
+ * @returns {!Array<!WebInspector.CSPParser.Rule>} |
+ */ |
+ get rules() { |
+ return this._rules; |
+ } |
+ |
+ /** |
+ * @returns {string|undefined} |
+ */ |
+ get securityStateReason() { |
+ if (this._deprecated) { |
+ return WebInspector.CSPParser.DeprecatedRules[this._name]; |
+ } |
+ return undefined; |
+ } |
+ |
+ /** |
+ * @param {string} name |
+ * @param {!Array<!WebInspector.CSPParser.Rule>} rules |
+ * @return WebInspector.CSPParser.Policy |
+ */ |
+ static build(name, rules) { |
+ let securityState = WebInspector.CSPParser.SecurityLevel.Safe; |
+ |
+ rules.forEach(item => { |
+ // Check if the state is unsafe and the existing policy state is not unsafe. |
+ // We don't want to raise the state if it is already lower. |
+ if (item.securityState === WebInspector.CSPParser.SecurityLevel.PossiblyUnsafe && |
+ securityState !== WebInspector.CSPParser.SecurityLevel.Unsafe) { |
+ securityState = WebInspector.CSPParser.SecurityLevel.PossiblyUnsafe; |
+ } |
+ if (item.securityState === WebInspector.CSPParser.SecurityLevel.Unsafe) { |
+ securityState = WebInspector.CSPParser.SecurityLevel.Unsafe; |
+ } |
+ }); |
+ |
+ return new WebInspector.CSPParser.Policy(name, securityState, rules, Object.keys(WebInspector.CSPParser.DeprecatedRules).includes(name)); |
+ } |
+} |