1 // Copyright 2014 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 #ifndef THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CSP_DIRECTIVE_LIST_H_ 6 #define THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CSP_DIRECTIVE_LIST_H_ 7 8 #include "base/macros.h" 9 #include "third_party/blink/renderer/core/frame/csp/content_security_policy.h" 10 #include "third_party/blink/renderer/core/frame/csp/media_list_directive.h" 11 #include "third_party/blink/renderer/core/frame/csp/require_trusted_types_for_directive.h" 12 #include "third_party/blink/renderer/core/frame/csp/source_list_directive.h" 13 #include "third_party/blink/renderer/core/frame/csp/string_list_directive.h" 14 #include "third_party/blink/renderer/platform/heap/handle.h" 15 #include "third_party/blink/renderer/platform/loader/fetch/resource_request.h" 16 #include "third_party/blink/renderer/platform/network/content_security_policy_parsers.h" 17 #include "third_party/blink/renderer/platform/network/http_parsers.h" 18 #include "third_party/blink/renderer/platform/weborigin/kurl.h" 19 #include "third_party/blink/renderer/platform/weborigin/reporting_disposition.h" 20 #include "third_party/blink/renderer/platform/wtf/text/atomic_string.h" 21 #include "third_party/blink/renderer/platform/wtf/text/wtf_string.h" 22 #include "third_party/blink/renderer/platform/wtf/vector.h" 23 24 namespace blink { 25 26 class ContentSecurityPolicy; 27 enum class ResourceType : uint8_t; 28 29 typedef HeapVector<Member<SourceListDirective>> SourceListDirectiveVector; 30 31 class CORE_EXPORT CSPDirectiveList final 32 : public GarbageCollected<CSPDirectiveList> { 33 public: 34 static CSPDirectiveList* Create(ContentSecurityPolicy*, 35 const UChar* begin, 36 const UChar* end, 37 network::mojom::ContentSecurityPolicyType, 38 network::mojom::ContentSecurityPolicySource, 39 bool should_parse_wasm_eval = false); 40 41 CSPDirectiveList(ContentSecurityPolicy*, 42 network::mojom::ContentSecurityPolicyType, 43 network::mojom::ContentSecurityPolicySource); 44 45 void Parse(const UChar* begin, 46 const UChar* end, 47 bool should_parse_wasm_eval = false); 48 Header()49 const String& Header() const { return header_; } HeaderType()50 network::mojom::ContentSecurityPolicyType HeaderType() const { 51 return header_type_; 52 } HeaderSource()53 network::mojom::ContentSecurityPolicySource HeaderSource() const { 54 return header_source_; 55 } 56 57 bool AllowInline(ContentSecurityPolicy::InlineType, 58 Element*, 59 const String& content, 60 const String& nonce, 61 const String& context_url, 62 const WTF::OrdinalNumber& context_line, 63 ReportingDisposition) const; 64 65 // Returns whether or not the Javascript code generation should call back the 66 // CSP checker before any script evaluation from a string is being made. 67 bool ShouldCheckEval() const; 68 69 bool AllowEval(ReportingDisposition, 70 ContentSecurityPolicy::ExceptionStatus, 71 const String& script_content) const; 72 bool AllowWasmEval(ReportingDisposition, 73 ContentSecurityPolicy::ExceptionStatus, 74 const String& script_content) const; 75 bool AllowPluginType(const String& type, 76 const String& type_attribute, 77 const KURL&, 78 ReportingDisposition) const; 79 80 bool AllowFromSource(ContentSecurityPolicy::DirectiveType, 81 const KURL&, 82 const KURL& url_before_redirects, 83 ResourceRequest::RedirectStatus, 84 ReportingDisposition, 85 const String& nonce = String(), 86 const IntegrityMetadataSet& = IntegrityMetadataSet(), 87 ParserDisposition = kParserInserted) const; 88 89 bool AllowTrustedTypePolicy(const String& policy_name, 90 bool is_duplicate) const; 91 92 bool AllowDynamic(ContentSecurityPolicy::DirectiveType) const; 93 bool AllowDynamicWorker() const; 94 95 bool AllowTrustedTypeAssignmentFailure(const String& message, 96 const String& sample, 97 const String& sample_prefix) const; 98 StrictMixedContentChecking()99 bool StrictMixedContentChecking() const { 100 return strict_mixed_content_checking_enforced_; 101 } 102 void ReportMixedContent(const KURL& blocked_url, 103 ResourceRequest::RedirectStatus) const; 104 ShouldDisableEval()105 bool ShouldDisableEval() const { 106 return ShouldDisableEvalBecauseScriptSrc() || 107 ShouldDisableEvalBecauseTrustedTypes(); 108 } 109 bool ShouldDisableEvalBecauseScriptSrc() const; 110 bool ShouldDisableEvalBecauseTrustedTypes() const; EvalDisabledErrorMessage()111 const String& EvalDisabledErrorMessage() const { 112 return eval_disabled_error_message_; 113 } IsReportOnly()114 bool IsReportOnly() const { 115 return header_type_ == network::mojom::ContentSecurityPolicyType::kReport; 116 } IsActiveForConnections()117 bool IsActiveForConnections() const { 118 return OperativeDirective( 119 ContentSecurityPolicy::DirectiveType::kConnectSrc); 120 } ReportEndpoints()121 const Vector<String>& ReportEndpoints() const { return report_endpoints_; } UseReportingApi()122 bool UseReportingApi() const { return use_reporting_api_; } 123 124 // Used to copy plugin-types into a plugin document in a nested 125 // browsing context. HasPluginTypes()126 bool HasPluginTypes() const { return !!plugin_types_; } 127 const String& PluginTypesText() const; 128 129 bool ShouldSendCSPHeader(ResourceType) const; 130 131 bool AllowHash(const CSPHashValue& hash_value, 132 const ContentSecurityPolicy::InlineType inline_type) const; 133 134 // The algorithm is described here: 135 // https://w3c.github.io/webappsec-csp/embedded/#subsume-policy 136 bool Subsumes(const CSPDirectiveListVector&); 137 138 // Export a subset of the Policy. The primary goal of this method is to make 139 // the embedders aware of the directives that affect navigation, as the 140 // embedder is responsible for navigational enforcement. 141 // It currently contains the following ones: 142 // * default-src 143 // * child-src 144 // * frame-src 145 // * form-action 146 // * upgrade-insecure-requests 147 // * navigate-to 148 // The exported directives only contains sources that affect navigation. For 149 // instance it doesn't contains 'unsafe-inline' or 'unsafe-eval' 150 network::mojom::blink::ContentSecurityPolicyPtr ExposeForNavigationalChecks() 151 const; 152 153 // We consider `object-src` restrictions to be reasonable iff they're 154 // equivalent to `object-src 'none'`. 155 bool IsObjectRestrictionReasonable() const; 156 157 // We consider `base-uri` restrictions to be reasonable iff they're equivalent 158 // to `base-uri 'none'` or `base-uri 'self'`. 159 bool IsBaseRestrictionReasonable() const; 160 161 // We consider `script-src` restrictions to be reasonable iff they're not 162 // URL-based (e.g. they contain only nonces and hashes, or they use 163 // 'strict-dynamic'). Neither `'unsafe-eval'` nor `'unsafe-hashes'` affect 164 // this judgement. 165 bool IsScriptRestrictionReasonable() const; 166 RequiresTrustedTypes()167 bool RequiresTrustedTypes() const { 168 return require_trusted_types_for_ && require_trusted_types_for_->require(); 169 } TrustedTypesAllowDuplicates()170 bool TrustedTypesAllowDuplicates() const { 171 return trusted_types_ && trusted_types_->IsAllowDuplicates(); 172 } 173 174 void Trace(Visitor*) const; 175 176 private: 177 FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, IsMatchingNoncePresent); 178 FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, GetSourceVector); 179 FRIEND_TEST_ALL_PREFIXES(CSPDirectiveListTest, OperativeDirectiveGivenType); 180 181 bool ParseDirective(const UChar* begin, 182 const UChar* end, 183 String* name, 184 String* value); 185 void ParseReportURI(const String& name, const String& value); 186 void ParseReportTo(const String& name, const String& value); 187 void ParseAndAppendReportEndpoints(const String& value); 188 void ParsePluginTypes(const String& name, const String& value); 189 void AddDirective(const String& name, const String& value); 190 void ApplySandboxPolicy(const String& name, const String& sandbox_policy); 191 void ApplyTreatAsPublicAddress(); 192 void EnforceStrictMixedContentChecking(const String& name, 193 const String& value); 194 void EnableInsecureRequestsUpgrade(const String& name, const String& value); 195 void AddTrustedTypes(const String& name, const String& value); 196 void RequireTrustedTypesFor(const String& name, const String& value); 197 198 template <class CSPDirectiveType> 199 void SetCSPDirective(const String& name, 200 const String& value, 201 Member<CSPDirectiveType>&, 202 bool should_parse_wasm_eval = false); 203 204 ContentSecurityPolicy::DirectiveType FallbackDirective( 205 const ContentSecurityPolicy::DirectiveType current_directive, 206 const ContentSecurityPolicy::DirectiveType original_directive) const; 207 void ReportViolation( 208 const String& directive_text, 209 const ContentSecurityPolicy::DirectiveType, 210 const String& console_message, 211 const KURL& blocked_url, 212 ResourceRequest::RedirectStatus, 213 ContentSecurityPolicy::ContentSecurityPolicyViolationType violation_type = 214 ContentSecurityPolicy::kURLViolation, 215 const String& sample = String(), 216 const String& sample_prefix = String()) const; 217 void ReportViolationWithFrame(const String& directive_text, 218 const ContentSecurityPolicy::DirectiveType, 219 const String& console_message, 220 const KURL& blocked_url, 221 LocalFrame*) const; 222 void ReportViolationWithLocation(const String& directive_text, 223 const ContentSecurityPolicy::DirectiveType, 224 const String& console_message, 225 const KURL& blocked_url, 226 const String& context_url, 227 const WTF::OrdinalNumber& context_line, 228 Element*, 229 const String& source) const; 230 void ReportEvalViolation(const String& directive_text, 231 const ContentSecurityPolicy::DirectiveType, 232 const String& message, 233 const KURL& blocked_url, 234 const ContentSecurityPolicy::ExceptionStatus, 235 const String& content) const; 236 237 bool CheckEval(SourceListDirective*) const; 238 bool CheckWasmEval(SourceListDirective*) const; 239 bool CheckDynamic(SourceListDirective*) const; 240 bool IsMatchingNoncePresent(SourceListDirective*, const String&) const; 241 bool AreAllMatchingHashesPresent(SourceListDirective*, 242 const IntegrityMetadataSet&) const; 243 bool CheckHash(SourceListDirective*, const CSPHashValue&) const; 244 bool CheckUnsafeHashesAllowed(SourceListDirective*) const; 245 bool CheckSource(SourceListDirective*, 246 const KURL&, 247 ResourceRequest::RedirectStatus) const; 248 bool CheckMediaType(MediaListDirective*, 249 const String& type, 250 const String& type_attribute) const; 251 SetEvalDisabledErrorMessage(const String & error_message)252 void SetEvalDisabledErrorMessage(const String& error_message) { 253 eval_disabled_error_message_ = error_message; 254 } 255 256 bool CheckEvalAndReportViolation(SourceListDirective*, 257 const String& console_message, 258 ContentSecurityPolicy::ExceptionStatus, 259 const String& script_content) const; 260 bool CheckWasmEvalAndReportViolation(SourceListDirective*, 261 const String& console_message, 262 ContentSecurityPolicy::ExceptionStatus, 263 const String& script_content) const; 264 bool CheckInlineAndReportViolation( 265 SourceListDirective*, 266 const String& console_message, 267 Element*, 268 const String& source, 269 const String& context_url, 270 const WTF::OrdinalNumber& context_line, 271 bool is_script, 272 const String& hash_value, 273 ContentSecurityPolicy::DirectiveType effective_type) const; 274 275 bool CheckSourceAndReportViolation(SourceListDirective*, 276 const KURL&, 277 const ContentSecurityPolicy::DirectiveType, 278 const KURL& url_before_redirects, 279 ResourceRequest::RedirectStatus) const; 280 bool CheckMediaTypeAndReportViolation(MediaListDirective*, 281 const String& type, 282 const String& type_attribute, 283 const String& console_message) const; 284 DenyIfEnforcingPolicy()285 bool DenyIfEnforcingPolicy() const { return IsReportOnly(); } 286 287 // This function returns a SourceListDirective of a given type 288 // or if it is not defined, the fallback SourceListDirective for that type. 289 SourceListDirective* OperativeDirective( 290 const ContentSecurityPolicy::DirectiveType type, 291 ContentSecurityPolicy::DirectiveType original_type = 292 ContentSecurityPolicy::DirectiveType::kUndefined) const; 293 294 // This function aggregates from a vector of policies all operative 295 // SourceListDirectives of a given type into a vector. 296 static SourceListDirectiveVector GetSourceVector( 297 const ContentSecurityPolicy::DirectiveType, 298 const CSPDirectiveListVector& policies); 299 300 Member<ContentSecurityPolicy> policy_; 301 302 String header_; 303 network::mojom::ContentSecurityPolicyType header_type_; 304 network::mojom::ContentSecurityPolicySource header_source_; 305 306 bool has_sandbox_policy_; 307 308 bool strict_mixed_content_checking_enforced_; 309 310 bool upgrade_insecure_requests_; 311 312 Member<MediaListDirective> plugin_types_; 313 Member<SourceListDirective> base_uri_; 314 Member<SourceListDirective> child_src_; 315 Member<SourceListDirective> connect_src_; 316 Member<SourceListDirective> default_src_; 317 Member<SourceListDirective> font_src_; 318 Member<SourceListDirective> form_action_; 319 Member<SourceListDirective> frame_ancestors_; 320 Member<SourceListDirective> frame_src_; 321 Member<SourceListDirective> img_src_; 322 Member<SourceListDirective> media_src_; 323 Member<SourceListDirective> manifest_src_; 324 Member<SourceListDirective> object_src_; 325 Member<SourceListDirective> prefetch_src_; 326 Member<SourceListDirective> script_src_; 327 Member<SourceListDirective> script_src_attr_; 328 Member<SourceListDirective> script_src_elem_; 329 Member<SourceListDirective> style_src_; 330 Member<SourceListDirective> style_src_attr_; 331 Member<SourceListDirective> style_src_elem_; 332 Member<SourceListDirective> worker_src_; 333 Member<SourceListDirective> navigate_to_; 334 Member<StringListDirective> trusted_types_; 335 Member<RequireTrustedTypesForDirective> require_trusted_types_for_; 336 337 // If a "report-to" directive is used: 338 // - |report_endpoints_| is a list of token parsed from the "report-to" 339 // directive's value, and 340 // - |use_reporting_api_| is true. 341 // Otherwise, 342 // - |report_endpoints_| is a list of uri-reference parsed from a 343 // "report-uri" directive's value if any, and 344 // - |use_reporting_api_| is false. 345 Vector<String> report_endpoints_; 346 bool use_reporting_api_; 347 348 String eval_disabled_error_message_; 349 350 DISALLOW_COPY_AND_ASSIGN(CSPDirectiveList); 351 }; 352 353 } // namespace blink 354 355 #endif // THIRD_PARTY_BLINK_RENDERER_CORE_FRAME_CSP_CSP_DIRECTIVE_LIST_H_ 356