OLD | NEW |
(Empty) | |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 /** |
| 6 * @constructor |
| 7 * |
| 8 * @property {!Array<!WebInspector.CSPParser.Policy>} policies - An Array of pol
icies that belong to the security policy. |
| 9 * @property {string} reportUri - The URI that reports are submitted to. "Not Se
t" if no URI is given. |
| 10 * |
| 11 * @param {!Array<!WebInspector.CSPParser.Policy>} policies |
| 12 * @param {?string} reportUri |
| 13 */ |
| 14 WebInspector.CSPParser = class { |
| 15 constructor(policies, reportUri) { |
| 16 this._policies = policies; |
| 17 this._reportUri = reportUri ? reportUri : "Not Set"; |
| 18 } |
| 19 |
| 20 /** |
| 21 * @return {!Array<!WebInspector.CSPParser.Policy>} |
| 22 */ |
| 23 get policies() { |
| 24 return this._policies; |
| 25 } |
| 26 |
| 27 /** |
| 28 * @returns {string|null} |
| 29 */ |
| 30 get reportUri() { |
| 31 return this._reportUri; |
| 32 } |
| 33 |
| 34 /** |
| 35 * @param {string} string |
| 36 * @param {boolean} reportOnly |
| 37 * @returns {!WebInspector.CSPParser} |
| 38 */ |
| 39 static buildFromString(string, reportOnly) { |
| 40 let items = string.split(";"); |
| 41 let policies = []; |
| 42 items.forEach(value => { |
| 43 let policyName = undefined; |
| 44 let rules = []; |
| 45 value.trim().split(" ").filter(d => !!d).forEach(item => { |
| 46 if (! policyName && item.trim() !== "") { |
| 47 policyName = item; |
| 48 return; |
| 49 } |
| 50 let obj = WebInspector.CSPParser.Rule.build(item, reportOnly); |
| 51 rules.push(obj); |
| 52 }); |
| 53 let policy = WebInspector.CSPParser.Policy.build(/** @type {string}
*/ (policyName), rules); |
| 54 policies.push(policy); |
| 55 }); |
| 56 let reportUri = null; |
| 57 let reportPolicy = policies.filter(item => item.name === "report-uri")[0
]; |
| 58 if (reportPolicy) { |
| 59 policies.splice(policies.indexOf(reportPolicy), 1); |
| 60 reportUri = reportPolicy.rules[0].value; |
| 61 } |
| 62 return new WebInspector.CSPParser(policies, reportUri); |
| 63 } |
| 64 } |
| 65 |
| 66 /** |
| 67 * @enum {string} |
| 68 */ |
| 69 WebInspector.CSPParser.Location = { |
| 70 Header: "Header", |
| 71 Meta: "Meta Tag" |
| 72 }; |
| 73 |
| 74 /** |
| 75 * @enum {string} |
| 76 */ |
| 77 WebInspector.CSPParser.SecurityLevel = { |
| 78 Safe: "safe", |
| 79 PossiblyUnsafe: "possibly-unsafe", |
| 80 Unsafe: "unsafe", |
| 81 Deprecated: "deprecated" |
| 82 }; |
| 83 |
| 84 /** |
| 85 * @enum {string} |
| 86 */ |
| 87 WebInspector.CSPParser.DeprecatedRules = { |
| 88 "frame-src": "Use child-src instead, unless you are supporting browsers that
use CSP 1.0 only." |
| 89 }; |
| 90 |
| 91 /** |
| 92 * @constructor |
| 93 * |
| 94 * @property {string} humanReadableSecurityState - A human-readable form of the
security state |
| 95 * @property {string} value - The value of the rule for the property. |
| 96 * @property {!WebInspector.CSPParser.SecurityLevel} securityState - Security st
ate of the rule |
| 97 * @property {string|undefined} reason - Reason for the given security state. |
| 98 * @property {boolean} reportOnly - Whether the rule is in report-only mode. |
| 99 * |
| 100 * @param {string} value |
| 101 * @param {!WebInspector.CSPParser.SecurityLevel} securityState |
| 102 * @param {string|undefined} reason |
| 103 * @param {boolean} reportOnly |
| 104 */ |
| 105 WebInspector.CSPParser.Rule = class { |
| 106 constructor(value, securityState, reason, reportOnly) |
| 107 { |
| 108 this._value = value; |
| 109 this._securityState = securityState; |
| 110 this._reason = reason; |
| 111 this._reportOnly = reportOnly; |
| 112 } |
| 113 |
| 114 /** |
| 115 * @return {string} |
| 116 */ |
| 117 get value() { |
| 118 return this._value; |
| 119 } |
| 120 |
| 121 /** |
| 122 * @return {!WebInspector.CSPParser.SecurityLevel} |
| 123 */ |
| 124 get securityState() { |
| 125 return /** @type {!WebInspector.CSPParser.SecurityLevel} */ (this._secur
ityState); |
| 126 } |
| 127 |
| 128 /** |
| 129 * @returns {string} |
| 130 */ |
| 131 get humanReadableSecurityState() { |
| 132 let securityState = this._securityState; |
| 133 securityState = securityState.split("-").join(" "); |
| 134 return securityState.charAt(0).toUpperCase() + securityState.slice(1); |
| 135 } |
| 136 |
| 137 /** |
| 138 * @return {string|undefined} |
| 139 */ |
| 140 get reason() { |
| 141 return this._reason; |
| 142 } |
| 143 |
| 144 /** |
| 145 * @return {boolean} |
| 146 */ |
| 147 get location() { |
| 148 return this._reportOnly; |
| 149 } |
| 150 |
| 151 /** |
| 152 * Suppress invalid cast since the reason type is correct, interpreter seems
to have issues. |
| 153 * @suppress {invalidCasts} |
| 154 * @param {string} item - The item to build a rule from. |
| 155 * @param {boolean} reportOnly - Whether the rule is in report-only mode. |
| 156 * @return WebInspector.CSPParser.Rule |
| 157 */ |
| 158 static build(item, reportOnly) { |
| 159 let securityState = WebInspector.CSPParser.SecurityLevel.Safe; |
| 160 let reason = undefined; |
| 161 |
| 162 let unsafeRules = [ |
| 163 "'unsafe-eval'", |
| 164 "'unsafe-inline'" |
| 165 ]; |
| 166 |
| 167 if (item.includes("*")) { |
| 168 securityState = WebInspector.CSPParser.SecurityLevel.PossiblyUnsafe; |
| 169 reason = "Consider removing wildcard"; |
| 170 } |
| 171 if (unsafeRules.indexOf(item) > -1) { |
| 172 securityState = WebInspector.CSPParser.SecurityLevel.Unsafe; |
| 173 reason = "XSS Risk"; |
| 174 } |
| 175 |
| 176 return new WebInspector.CSPParser.Rule(item, securityState, reason, repo
rtOnly); |
| 177 } |
| 178 } |
| 179 |
| 180 /** |
| 181 * @constructor |
| 182 * @property {string} name - The policy name provided. |
| 183 * @property {!WebInspector.CSPParser.SecurityLevel} securityState - Security st
ate of the policy |
| 184 * @property {!Array<!WebInspector.CSPParser.Rule>} rules - Rules of the policy. |
| 185 * @property {boolean} deprecated - Indicate whether the policy is deprecated. |
| 186 * @property {string|undefined} securityStateReason - Reason for the given secur
ity state. |
| 187 * @property {string} humanReadableSecurityState - A human-readable form of the
security state |
| 188 * |
| 189 * @param {string} name |
| 190 * @param {!WebInspector.CSPParser.SecurityLevel} securityState |
| 191 * @param {!Array<!WebInspector.CSPParser.Rule>} rules |
| 192 * @param {boolean} deprecated |
| 193 */ |
| 194 WebInspector.CSPParser.Policy = class { |
| 195 constructor(name, securityState, rules, deprecated) |
| 196 { |
| 197 this._name = name; |
| 198 this._securityState = securityState; |
| 199 this._rules = rules; |
| 200 this._deprecated = deprecated; |
| 201 } |
| 202 |
| 203 /** |
| 204 * @returns {string} |
| 205 */ |
| 206 get name() { |
| 207 return this._name; |
| 208 } |
| 209 |
| 210 /** |
| 211 * @returns {!WebInspector.CSPParser.SecurityLevel} |
| 212 */ |
| 213 get securityState() { |
| 214 return /** @type {!WebInspector.CSPParser.SecurityLevel} */ (this._secur
ityState); |
| 215 } |
| 216 |
| 217 /** |
| 218 * @returns {boolean} |
| 219 */ |
| 220 get deprecated() { |
| 221 return this._deprecated; |
| 222 } |
| 223 |
| 224 /** |
| 225 * @returns {string} |
| 226 */ |
| 227 get humanReadableSecurityState() { |
| 228 let securityState = this._securityState; |
| 229 if (this._deprecated) { |
| 230 securityState += " and " + WebInspector.CSPParser.SecurityLevel.Depr
ecated; |
| 231 } |
| 232 securityState = securityState.split("-").join(" "); |
| 233 return securityState.charAt(0).toUpperCase() + securityState.slice(1); |
| 234 } |
| 235 |
| 236 /** |
| 237 * @returns {!Array<!WebInspector.CSPParser.Rule>} |
| 238 */ |
| 239 get rules() { |
| 240 return this._rules; |
| 241 } |
| 242 |
| 243 /** |
| 244 * @returns {string|undefined} |
| 245 */ |
| 246 get securityStateReason() { |
| 247 if (this._deprecated) { |
| 248 return WebInspector.CSPParser.DeprecatedRules[this._name]; |
| 249 } |
| 250 return undefined; |
| 251 } |
| 252 |
| 253 /** |
| 254 * @param {string} name |
| 255 * @param {!Array<!WebInspector.CSPParser.Rule>} rules |
| 256 * @return WebInspector.CSPParser.Policy |
| 257 */ |
| 258 static build(name, rules) { |
| 259 let securityState = WebInspector.CSPParser.SecurityLevel.Safe; |
| 260 |
| 261 rules.forEach(item => { |
| 262 // Check if the state is unsafe and the existing policy state is not
unsafe. |
| 263 // We don't want to raise the state if it is already lower. |
| 264 if (item.securityState === WebInspector.CSPParser.SecurityLevel.Poss
iblyUnsafe && |
| 265 securityState !== WebInspector.CSPParser.SecurityLevel.Unsafe) { |
| 266 securityState = WebInspector.CSPParser.SecurityLevel.PossiblyUns
afe; |
| 267 } |
| 268 if (item.securityState === WebInspector.CSPParser.SecurityLevel.Unsa
fe) { |
| 269 securityState = WebInspector.CSPParser.SecurityLevel.Unsafe; |
| 270 } |
| 271 }); |
| 272 |
| 273 return new WebInspector.CSPParser.Policy(name, securityState, rules, Obj
ect.keys(WebInspector.CSPParser.DeprecatedRules).includes(name)); |
| 274 } |
| 275 } |
OLD | NEW |