Bug 1795723 - Unified extensions UI should support High Contrast Mode. r=ayeddi,deskt...
[gecko.git] / dom / security / nsCSPUtils.h
blobdd3ea9a1c49388cbd0e4f9299ee68ea13e0a1ab6
1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
3 /* This Source Code Form is subject to the terms of the Mozilla Public
4 * License, v. 2.0. If a copy of the MPL was not distributed with this
5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
7 #ifndef nsCSPUtils_h___
8 #define nsCSPUtils_h___
10 #include "nsCOMPtr.h"
11 #include "nsIContentSecurityPolicy.h"
12 #include "nsIURI.h"
13 #include "nsLiteralString.h"
14 #include "nsString.h"
15 #include "nsTArray.h"
16 #include "nsUnicharUtils.h"
17 #include "mozilla/Logging.h"
19 class nsIChannel;
21 namespace mozilla::dom {
22 struct CSP;
23 class Document;
24 } // namespace mozilla::dom
26 /* =============== Logging =================== */
28 void CSP_LogLocalizedStr(const char* aName, const nsTArray<nsString>& aParams,
29 const nsAString& aSourceName,
30 const nsAString& aSourceLine, uint32_t aLineNumber,
31 uint32_t aColumnNumber, uint32_t aFlags,
32 const nsACString& aCategory, uint64_t aInnerWindowID,
33 bool aFromPrivateWindow);
35 void CSP_GetLocalizedStr(const char* aName, const nsTArray<nsString>& aParams,
36 nsAString& outResult);
38 void CSP_LogStrMessage(const nsAString& aMsg);
40 void CSP_LogMessage(const nsAString& aMessage, const nsAString& aSourceName,
41 const nsAString& aSourceLine, uint32_t aLineNumber,
42 uint32_t aColumnNumber, uint32_t aFlags,
43 const nsACString& aCategory, uint64_t aInnerWindowID,
44 bool aFromPrivateWindow);
46 /* =============== Constant and Type Definitions ================== */
48 #define INLINE_STYLE_VIOLATION_OBSERVER_TOPIC \
49 "violated base restriction: Inline Stylesheets will not apply"
50 #define INLINE_SCRIPT_VIOLATION_OBSERVER_TOPIC \
51 "violated base restriction: Inline Scripts will not execute"
52 #define EVAL_VIOLATION_OBSERVER_TOPIC \
53 "violated base restriction: Code will not be created from strings"
54 #define WASM_EVAL_VIOLATION_OBSERVER_TOPIC \
55 "violated base restriction: WebAssembly code will not be created from " \
56 "dynamically"
57 #define SCRIPT_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid nonce"
58 #define STYLE_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid nonce"
59 #define SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid hash"
60 #define STYLE_HASH_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid hash"
62 // these strings map to the CSPDirectives in nsIContentSecurityPolicy
63 // NOTE: When implementing a new directive, you will need to add it here but
64 // also add a corresponding entry to the constants in
65 // nsIContentSecurityPolicy.idl and also create an entry for the new directive
66 // in nsCSPDirective::toDomCSPStruct() and add it to CSPDictionaries.webidl.
67 // Order of elements below important! Make sure it matches the order as in
68 // nsIContentSecurityPolicy.idl
69 static const char* CSPStrDirectives[] = {
70 "-error-", // NO_DIRECTIVE
71 "default-src", // DEFAULT_SRC_DIRECTIVE
72 "script-src", // SCRIPT_SRC_DIRECTIVE
73 "object-src", // OBJECT_SRC_DIRECTIVE
74 "style-src", // STYLE_SRC_DIRECTIVE
75 "img-src", // IMG_SRC_DIRECTIVE
76 "media-src", // MEDIA_SRC_DIRECTIVE
77 "frame-src", // FRAME_SRC_DIRECTIVE
78 "font-src", // FONT_SRC_DIRECTIVE
79 "connect-src", // CONNECT_SRC_DIRECTIVE
80 "report-uri", // REPORT_URI_DIRECTIVE
81 "frame-ancestors", // FRAME_ANCESTORS_DIRECTIVE
82 "reflected-xss", // REFLECTED_XSS_DIRECTIVE
83 "base-uri", // BASE_URI_DIRECTIVE
84 "form-action", // FORM_ACTION_DIRECTIVE
85 "manifest-src", // MANIFEST_SRC_DIRECTIVE
86 "upgrade-insecure-requests", // UPGRADE_IF_INSECURE_DIRECTIVE
87 "child-src", // CHILD_SRC_DIRECTIVE
88 "block-all-mixed-content", // BLOCK_ALL_MIXED_CONTENT
89 "sandbox", // SANDBOX_DIRECTIVE
90 "worker-src", // WORKER_SRC_DIRECTIVE
91 "navigate-to", // NAVIGATE_TO_DIRECTIVE
92 "script-src-elem", // SCRIPT_SRC_ELEM_DIRECTIVE
93 "script-src-attr", // SCRIPT_SRC_ATTR_DIRECTIVE
94 "style-src-elem", // STYLE_SRC_ELEM_DIRECTIVE
95 "style-src-attr", // STYLE_SRC_ATTR_DIRECTIVE
98 inline const char* CSP_CSPDirectiveToString(CSPDirective aDir) {
99 return CSPStrDirectives[static_cast<uint32_t>(aDir)];
102 inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir) {
103 nsString lowerDir = PromiseFlatString(aDir);
104 ToLowerCase(lowerDir);
106 uint32_t numDirs = (sizeof(CSPStrDirectives) / sizeof(CSPStrDirectives[0]));
107 for (uint32_t i = 1; i < numDirs; i++) {
108 if (lowerDir.EqualsASCII(CSPStrDirectives[i])) {
109 return static_cast<CSPDirective>(i);
112 return nsIContentSecurityPolicy::NO_DIRECTIVE;
115 #define FOR_EACH_CSP_KEYWORD(MACRO) \
116 MACRO(CSP_SELF, "'self'") \
117 MACRO(CSP_UNSAFE_INLINE, "'unsafe-inline'") \
118 MACRO(CSP_UNSAFE_EVAL, "'unsafe-eval'") \
119 MACRO(CSP_UNSAFE_HASHES, "'unsafe-hashes'") \
120 MACRO(CSP_NONE, "'none'") \
121 MACRO(CSP_NONCE, "'nonce-") \
122 MACRO(CSP_REPORT_SAMPLE, "'report-sample'") \
123 MACRO(CSP_STRICT_DYNAMIC, "'strict-dynamic'") \
124 MACRO(CSP_UNSAFE_ALLOW_REDIRECTS, "'unsafe-allow-redirects'") \
125 MACRO(CSP_WASM_UNSAFE_EVAL, "'wasm-unsafe-eval'")
127 enum CSPKeyword {
128 #define KEYWORD_ENUM(id_, string_) id_,
129 FOR_EACH_CSP_KEYWORD(KEYWORD_ENUM)
130 #undef KEYWORD_ENUM
132 // CSP_LAST_KEYWORD_VALUE always needs to be the last element in the enum
133 // because we use it to calculate the size for the char* array.
134 CSP_LAST_KEYWORD_VALUE,
136 // Putting CSP_HASH after the delimitor, because CSP_HASH is not a valid
137 // keyword (hash uses e.g. sha256, sha512) but we use CSP_HASH internally
138 // to identify allowed hashes in ::allows.
139 CSP_HASH
142 // The keywords, in UTF-8 form.
143 static const char* gCSPUTF8Keywords[] = {
144 #define KEYWORD_UTF8_LITERAL(id_, string_) string_,
145 FOR_EACH_CSP_KEYWORD(KEYWORD_UTF8_LITERAL)
146 #undef KEYWORD_UTF8_LITERAL
149 // The keywords, in UTF-16 form.
150 static const char16_t* gCSPUTF16Keywords[] = {
151 #define KEYWORD_UTF16_LITERAL(id_, string_) u"" string_,
152 FOR_EACH_CSP_KEYWORD(KEYWORD_UTF16_LITERAL)
153 #undef KEYWORD_UTF16_LITERAL
156 #undef FOR_EACH_CSP_KEYWORD
158 inline const char* CSP_EnumToUTF8Keyword(enum CSPKeyword aKey) {
159 // Make sure all elements in enum CSPKeyword got added to gCSPUTF8Keywords.
160 static_assert((sizeof(gCSPUTF8Keywords) / sizeof(gCSPUTF8Keywords[0]) ==
161 CSP_LAST_KEYWORD_VALUE),
162 "CSP_LAST_KEYWORD_VALUE != length(gCSPUTF8Keywords)");
164 if (static_cast<uint32_t>(aKey) <
165 static_cast<uint32_t>(CSP_LAST_KEYWORD_VALUE)) {
166 return gCSPUTF8Keywords[static_cast<uint32_t>(aKey)];
168 return "error: invalid keyword in CSP_EnumToUTF8Keyword";
171 inline const char16_t* CSP_EnumToUTF16Keyword(enum CSPKeyword aKey) {
172 // Make sure all elements in enum CSPKeyword got added to gCSPUTF16Keywords.
173 static_assert((sizeof(gCSPUTF16Keywords) / sizeof(gCSPUTF16Keywords[0]) ==
174 CSP_LAST_KEYWORD_VALUE),
175 "CSP_LAST_KEYWORD_VALUE != length(gCSPUTF16Keywords)");
177 if (static_cast<uint32_t>(aKey) <
178 static_cast<uint32_t>(CSP_LAST_KEYWORD_VALUE)) {
179 return gCSPUTF16Keywords[static_cast<uint32_t>(aKey)];
181 return u"error: invalid keyword in CSP_EnumToUTF16Keyword";
184 inline CSPKeyword CSP_UTF16KeywordToEnum(const nsAString& aKey) {
185 nsString lowerKey = PromiseFlatString(aKey);
186 ToLowerCase(lowerKey);
188 for (uint32_t i = 0; i < CSP_LAST_KEYWORD_VALUE; i++) {
189 if (lowerKey.Equals(gCSPUTF16Keywords[i])) {
190 return static_cast<CSPKeyword>(i);
193 NS_ASSERTION(false, "Can not convert unknown Keyword to Enum");
194 return CSP_LAST_KEYWORD_VALUE;
197 nsresult CSP_AppendCSPFromHeader(nsIContentSecurityPolicy* aCsp,
198 const nsAString& aHeaderValue,
199 bool aReportOnly);
201 /* =============== Helpers ================== */
203 class nsCSPHostSrc;
205 nsCSPHostSrc* CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI);
206 bool CSP_IsEmptyDirective(const nsAString& aValue, const nsAString& aDir);
207 bool CSP_IsDirective(const nsAString& aValue, CSPDirective aDir);
208 bool CSP_IsKeyword(const nsAString& aValue, enum CSPKeyword aKey);
209 bool CSP_IsQuotelessKeyword(const nsAString& aKey);
210 CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType);
212 class nsCSPSrcVisitor;
214 void CSP_PercentDecodeStr(const nsAString& aEncStr, nsAString& outDecStr);
215 bool CSP_ShouldResponseInheritCSP(nsIChannel* aChannel);
217 void CSP_ApplyMetaCSPToDoc(mozilla::dom::Document& aDoc,
218 const nsAString& aPolicyStr);
220 /* =============== nsCSPSrc ================== */
222 class nsCSPBaseSrc {
223 public:
224 nsCSPBaseSrc();
225 virtual ~nsCSPBaseSrc();
227 virtual bool permits(nsIURI* aUri, const nsAString& aNonce,
228 bool aWasRedirected, bool aReportOnly,
229 bool aUpgradeInsecure, bool aParserCreated) const;
230 virtual bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
231 bool aParserCreated) const;
232 virtual bool visit(nsCSPSrcVisitor* aVisitor) const = 0;
233 virtual void toString(nsAString& outStr) const = 0;
235 virtual void invalidate() const { mInvalidated = true; }
237 virtual bool isReportSample() const { return false; }
239 protected:
240 // invalidate srcs if 'script-dynamic' is present or also invalidate
241 // unsafe-inline' if nonce- or hash-source specified
242 mutable bool mInvalidated;
245 /* =============== nsCSPSchemeSrc ============ */
247 class nsCSPSchemeSrc : public nsCSPBaseSrc {
248 public:
249 explicit nsCSPSchemeSrc(const nsAString& aScheme);
250 virtual ~nsCSPSchemeSrc();
252 bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
253 bool aReportOnly, bool aUpgradeInsecure,
254 bool aParserCreated) const override;
255 bool visit(nsCSPSrcVisitor* aVisitor) const override;
256 void toString(nsAString& outStr) const override;
258 inline void getScheme(nsAString& outStr) const { outStr.Assign(mScheme); };
260 private:
261 nsString mScheme;
264 /* =============== nsCSPHostSrc ============== */
266 class nsCSPHostSrc : public nsCSPBaseSrc {
267 public:
268 explicit nsCSPHostSrc(const nsAString& aHost);
269 virtual ~nsCSPHostSrc();
271 bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
272 bool aReportOnly, bool aUpgradeInsecure,
273 bool aParserCreated) const override;
274 bool visit(nsCSPSrcVisitor* aVisitor) const override;
275 void toString(nsAString& outStr) const override;
277 void setScheme(const nsAString& aScheme);
278 void setPort(const nsAString& aPort);
279 void appendPath(const nsAString& aPath);
281 inline void setGeneratedFromSelfKeyword() const {
282 mGeneratedFromSelfKeyword = true;
285 inline void setIsUniqueOrigin() const { mIsUniqueOrigin = true; }
287 inline void setWithinFrameAncestorsDir(bool aValue) const {
288 mWithinFrameAncstorsDir = aValue;
291 inline void getScheme(nsAString& outStr) const { outStr.Assign(mScheme); };
293 inline void getHost(nsAString& outStr) const { outStr.Assign(mHost); };
295 inline void getPort(nsAString& outStr) const { outStr.Assign(mPort); };
297 inline void getPath(nsAString& outStr) const { outStr.Assign(mPath); };
299 private:
300 nsString mScheme;
301 nsString mHost;
302 nsString mPort;
303 nsString mPath;
304 mutable bool mGeneratedFromSelfKeyword;
305 mutable bool mIsUniqueOrigin;
306 mutable bool mWithinFrameAncstorsDir;
309 /* =============== nsCSPKeywordSrc ============ */
311 class nsCSPKeywordSrc : public nsCSPBaseSrc {
312 public:
313 explicit nsCSPKeywordSrc(CSPKeyword aKeyword);
314 virtual ~nsCSPKeywordSrc();
316 bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
317 bool aParserCreated) const override;
318 bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
319 bool aReportOnly, bool aUpgradeInsecure,
320 bool aParserCreated) const override;
321 bool visit(nsCSPSrcVisitor* aVisitor) const override;
322 void toString(nsAString& outStr) const override;
324 inline CSPKeyword getKeyword() const { return mKeyword; };
326 inline void invalidate() const override {
327 // keywords that need to invalidated
328 if (mKeyword == CSP_SELF || mKeyword == CSP_UNSAFE_INLINE ||
329 mKeyword == CSP_REPORT_SAMPLE) {
330 mInvalidated = true;
334 bool isReportSample() const override { return mKeyword == CSP_REPORT_SAMPLE; }
336 private:
337 CSPKeyword mKeyword;
340 /* =============== nsCSPNonceSource =========== */
342 class nsCSPNonceSrc : public nsCSPBaseSrc {
343 public:
344 explicit nsCSPNonceSrc(const nsAString& aNonce);
345 virtual ~nsCSPNonceSrc();
347 bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
348 bool aReportOnly, bool aUpgradeInsecure,
349 bool aParserCreated) const override;
350 bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
351 bool aParserCreated) const override;
352 bool visit(nsCSPSrcVisitor* aVisitor) const override;
353 void toString(nsAString& outStr) const override;
355 inline void getNonce(nsAString& outStr) const { outStr.Assign(mNonce); };
357 inline void invalidate() const override {
358 // overwrite nsCSPBaseSRC::invalidate() and explicitily
359 // do *not* invalidate, because 'strict-dynamic' should
360 // not invalidate nonces.
363 private:
364 nsString mNonce;
367 /* =============== nsCSPHashSource ============ */
369 class nsCSPHashSrc : public nsCSPBaseSrc {
370 public:
371 nsCSPHashSrc(const nsAString& algo, const nsAString& hash);
372 virtual ~nsCSPHashSrc();
374 bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
375 bool aParserCreated) const override;
376 void toString(nsAString& outStr) const override;
377 bool visit(nsCSPSrcVisitor* aVisitor) const override;
379 inline void getAlgorithm(nsAString& outStr) const {
380 outStr.Assign(mAlgorithm);
383 inline void getHash(nsAString& outStr) const { outStr.Assign(mHash); };
385 inline void invalidate() const override {
386 // overwrite nsCSPBaseSRC::invalidate() and explicitily
387 // do *not* invalidate, because 'strict-dynamic' should
388 // not invalidate hashes.
391 private:
392 nsString mAlgorithm;
393 nsString mHash;
396 /* =============== nsCSPReportURI ============ */
398 class nsCSPReportURI : public nsCSPBaseSrc {
399 public:
400 explicit nsCSPReportURI(nsIURI* aURI);
401 virtual ~nsCSPReportURI();
403 bool visit(nsCSPSrcVisitor* aVisitor) const override;
404 void toString(nsAString& outStr) const override;
406 private:
407 nsCOMPtr<nsIURI> mReportURI;
410 /* =============== nsCSPSandboxFlags ================== */
412 class nsCSPSandboxFlags : public nsCSPBaseSrc {
413 public:
414 explicit nsCSPSandboxFlags(const nsAString& aFlags);
415 virtual ~nsCSPSandboxFlags();
417 bool visit(nsCSPSrcVisitor* aVisitor) const override;
418 void toString(nsAString& outStr) const override;
420 private:
421 nsString mFlags;
424 /* =============== nsCSPSrcVisitor ================== */
426 class nsCSPSrcVisitor {
427 public:
428 virtual bool visitSchemeSrc(const nsCSPSchemeSrc& src) = 0;
430 virtual bool visitHostSrc(const nsCSPHostSrc& src) = 0;
432 virtual bool visitKeywordSrc(const nsCSPKeywordSrc& src) = 0;
434 virtual bool visitNonceSrc(const nsCSPNonceSrc& src) = 0;
436 virtual bool visitHashSrc(const nsCSPHashSrc& src) = 0;
438 protected:
439 explicit nsCSPSrcVisitor() = default;
440 virtual ~nsCSPSrcVisitor() = default;
443 /* =============== nsCSPDirective ============= */
445 class nsCSPDirective {
446 public:
447 explicit nsCSPDirective(CSPDirective aDirective);
448 virtual ~nsCSPDirective();
450 virtual bool permits(nsIURI* aUri, const nsAString& aNonce,
451 bool aWasRedirected, bool aReportOnly,
452 bool aUpgradeInsecure, bool aParserCreated) const;
453 virtual bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
454 bool aParserCreated) const;
455 virtual void toString(nsAString& outStr) const;
456 void toDomCSPStruct(mozilla::dom::CSP& outCSP) const;
458 virtual void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) {
459 mSrcs = aSrcs.Clone();
462 inline bool isDefaultDirective() const {
463 return mDirective == nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE;
466 virtual bool equals(CSPDirective aDirective) const;
468 void getReportURIs(nsTArray<nsString>& outReportURIs) const;
470 bool visitSrcs(nsCSPSrcVisitor* aVisitor) const;
472 virtual void getDirName(nsAString& outStr) const;
474 bool hasReportSampleKeyword() const;
476 protected:
477 CSPDirective mDirective;
478 nsTArray<nsCSPBaseSrc*> mSrcs;
481 /* =============== nsCSPChildSrcDirective ============= */
484 * In CSP 3 child-src is deprecated. For backwards compatibility
485 * child-src needs to restrict:
486 * (*) frames, in case frame-src is not expicitly specified
487 * (*) workers, in case worker-src is not expicitly specified
489 class nsCSPChildSrcDirective : public nsCSPDirective {
490 public:
491 explicit nsCSPChildSrcDirective(CSPDirective aDirective);
492 virtual ~nsCSPChildSrcDirective();
494 void setRestrictFrames() { mRestrictFrames = true; }
496 void setRestrictWorkers() { mRestrictWorkers = true; }
498 virtual bool equals(CSPDirective aDirective) const override;
500 private:
501 bool mRestrictFrames;
502 bool mRestrictWorkers;
505 /* =============== nsCSPScriptSrcDirective ============= */
508 * In CSP 3 worker-src restricts workers, for backwards compatibily
509 * script-src has to restrict workers as the ultimate fallback if
510 * neither worker-src nor child-src is present in a CSP.
512 class nsCSPScriptSrcDirective : public nsCSPDirective {
513 public:
514 explicit nsCSPScriptSrcDirective(CSPDirective aDirective);
515 virtual ~nsCSPScriptSrcDirective();
517 void setRestrictWorkers() { mRestrictWorkers = true; }
518 void setRestrictScriptElem() { mRestrictScriptElem = true; }
519 void setRestrictScriptAttr() { mRestrictScriptAttr = true; }
521 bool equals(CSPDirective aDirective) const override;
523 private:
524 bool mRestrictWorkers = false;
525 bool mRestrictScriptElem = false;
526 bool mRestrictScriptAttr = false;
529 /* =============== nsCSPStyleSrcDirective ============= */
532 * In CSP 3 style-src is use as a fallback for style-src-elem and
533 * style-src-attr.
535 class nsCSPStyleSrcDirective : public nsCSPDirective {
536 public:
537 explicit nsCSPStyleSrcDirective(CSPDirective aDirective);
538 virtual ~nsCSPStyleSrcDirective();
540 void setRestrictStyleElem() { mRestrictStyleElem = true; }
541 void setRestrictStyleAttr() { mRestrictStyleAttr = true; }
543 bool equals(CSPDirective aDirective) const override;
545 private:
546 bool mRestrictStyleElem = false;
547 bool mRestrictStyleAttr = false;
550 /* =============== nsBlockAllMixedContentDirective === */
552 class nsBlockAllMixedContentDirective : public nsCSPDirective {
553 public:
554 explicit nsBlockAllMixedContentDirective(CSPDirective aDirective);
555 ~nsBlockAllMixedContentDirective();
557 bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
558 bool aReportOnly, bool aUpgradeInsecure,
559 bool aParserCreated) const override {
560 return false;
563 bool permits(nsIURI* aUri) const { return false; }
565 bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
566 bool aParserCreated) const override {
567 return false;
570 void toString(nsAString& outStr) const override;
572 void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) override {
573 MOZ_ASSERT(false, "block-all-mixed-content does not hold any srcs");
576 void getDirName(nsAString& outStr) const override;
579 /* =============== nsUpgradeInsecureDirective === */
582 * Upgrading insecure requests includes the following actors:
583 * (1) CSP:
584 * The CSP implementation allowlists the http-request
585 * in case the policy is executed in enforcement mode.
586 * The CSP implementation however does not allow http
587 * requests to succeed if executed in report-only mode.
588 * In such a case the CSP implementation reports the
589 * error back to the page.
591 * (2) MixedContent:
592 * The evalution of MixedContent allowlists all http
593 * requests with the promise that the http requests
594 * gets upgraded to https before any data is fetched
595 * from the network.
597 * (3) CORS:
598 * Does not consider the http request to be of a
599 * different origin in case the scheme is the only
600 * difference in otherwise matching URIs.
602 * (4) nsHttpChannel:
603 * Before connecting, the channel gets redirected
604 * to use https.
606 * (5) WebSocketChannel:
607 * Similar to the httpChannel, the websocketchannel
608 * gets upgraded from ws to wss.
610 class nsUpgradeInsecureDirective : public nsCSPDirective {
611 public:
612 explicit nsUpgradeInsecureDirective(CSPDirective aDirective);
613 ~nsUpgradeInsecureDirective();
615 bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
616 bool aReportOnly, bool aUpgradeInsecure,
617 bool aParserCreated) const override {
618 return false;
621 bool permits(nsIURI* aUri) const { return false; }
623 bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
624 bool aParserCreated) const override {
625 return false;
628 void toString(nsAString& outStr) const override;
630 void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) override {
631 MOZ_ASSERT(false, "upgrade-insecure-requests does not hold any srcs");
634 void getDirName(nsAString& outStr) const override;
637 /* =============== nsCSPPolicy ================== */
639 class nsCSPPolicy {
640 public:
641 nsCSPPolicy();
642 virtual ~nsCSPPolicy();
644 bool permits(CSPDirective aDirective, nsIURI* aUri, const nsAString& aNonce,
645 bool aWasRedirected, bool aSpecific, bool aParserCreated,
646 nsAString& outViolatedDirective) const;
647 bool allows(CSPDirective aDirective, enum CSPKeyword aKeyword,
648 const nsAString& aHashOrNonce, bool aParserCreated) const;
649 void toString(nsAString& outStr) const;
650 void toDomCSPStruct(mozilla::dom::CSP& outCSP) const;
652 inline void addDirective(nsCSPDirective* aDir) {
653 mDirectives.AppendElement(aDir);
656 inline void addUpgradeInsecDir(nsUpgradeInsecureDirective* aDir) {
657 mUpgradeInsecDir = aDir;
658 addDirective(aDir);
661 bool hasDirective(CSPDirective aDir) const;
663 inline void setDeliveredViaMetaTagFlag(bool aFlag) {
664 mDeliveredViaMetaTag = aFlag;
667 inline bool getDeliveredViaMetaTagFlag() const {
668 return mDeliveredViaMetaTag;
671 inline void setReportOnlyFlag(bool aFlag) { mReportOnly = aFlag; }
673 inline bool getReportOnlyFlag() const { return mReportOnly; }
675 void getReportURIs(nsTArray<nsString>& outReportURIs) const;
677 void getDirectiveStringAndReportSampleForContentType(
678 CSPDirective aDirective, nsAString& outDirective,
679 bool* aReportSample) const;
681 void getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const;
683 uint32_t getSandboxFlags() const;
685 inline uint32_t getNumDirectives() const { return mDirectives.Length(); }
687 bool visitDirectiveSrcs(CSPDirective aDir, nsCSPSrcVisitor* aVisitor) const;
689 bool allowsNavigateTo(nsIURI* aURI, bool aWasRedirected,
690 bool aEnforceAllowlist) const;
692 private:
693 nsUpgradeInsecureDirective* mUpgradeInsecDir;
694 nsTArray<nsCSPDirective*> mDirectives;
695 bool mReportOnly;
696 bool mDeliveredViaMetaTag;
699 #endif /* nsCSPUtils_h___ */