tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

nsCSPUtils.h (26987B)


      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/. */
      6 
      7 #ifndef nsCSPUtils_h___
      8 #define nsCSPUtils_h___
      9 
     10 #include "mozilla/ErrorResult.h"
     11 #include "nsCOMPtr.h"
     12 #include "nsILoadInfo.h"
     13 #include "nsIURI.h"
     14 #include "nsString.h"
     15 #include "nsTArray.h"
     16 #include "nsUnicharUtils.h"
     17 
     18 class nsIChannel;
     19 
     20 namespace mozilla::dom {
     21 struct CSP;
     22 class Document;
     23 }  // namespace mozilla::dom
     24 
     25 /* =============== Logging =================== */
     26 
     27 void CSP_LogLocalizedStr(const char* aName, const nsTArray<nsString>& aParams,
     28                         const nsACString& aSourceName,
     29                         const nsAString& aSourceLine, uint32_t aLineNumber,
     30                         uint32_t aColumnNumber, uint32_t aFlags,
     31                         const nsACString& aCategory, uint64_t aInnerWindowID,
     32                         bool aFromPrivateWindow);
     33 
     34 void CSP_GetLocalizedStr(const char* aName, const nsTArray<nsString>& aParams,
     35                         nsAString& outResult);
     36 
     37 void CSP_LogStrMessage(const nsAString& aMsg);
     38 
     39 void CSP_LogMessage(const nsAString& aMessage, const nsACString& aSourceName,
     40                    const nsAString& aSourceLine, uint32_t aLineNumber,
     41                    uint32_t aColumnNumber, uint32_t aFlags,
     42                    const nsACString& aCategory, uint64_t aInnerWindowID,
     43                    bool aFromPrivateWindow);
     44 
     45 /* =============== Constant and Type Definitions ================== */
     46 
     47 #define INLINE_STYLE_VIOLATION_OBSERVER_TOPIC \
     48  "violated base restriction: Inline Stylesheets will not apply"
     49 #define INLINE_SCRIPT_VIOLATION_OBSERVER_TOPIC \
     50  "violated base restriction: Inline Scripts will not execute"
     51 #define EVAL_VIOLATION_OBSERVER_TOPIC \
     52  "violated base restriction: Code will not be created from strings"
     53 #define WASM_EVAL_VIOLATION_OBSERVER_TOPIC                                \
     54  "violated base restriction: WebAssembly code will not be created from " \
     55  "dynamically"
     56 #define SCRIPT_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid nonce"
     57 #define STYLE_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid nonce"
     58 #define SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid hash"
     59 #define STYLE_HASH_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid hash"
     60 #define TRUSTED_TYPES_VIOLATION_OBSERVER_TOPIC \
     61  "Tried to create a trusted-types policy with a forbidden policy name"
     62 #define REQUIRE_TRUSTED_TYPES_FOR_SCRIPT_OBSERVER_TOPIC \
     63  "Type mismatch for injection sink"
     64 
     65 // these strings map to the CSPDirectives in nsIContentSecurityPolicy
     66 // NOTE: When implementing a new directive, you will need to add it here but
     67 // also add a corresponding entry to the constants in
     68 // nsIContentSecurityPolicy.idl and also create an entry for the new directive
     69 // in nsCSPDirective::toDomCSPStruct() and add it to CSPDictionaries.webidl.
     70 // Order of elements below important! Make sure it matches the order as in
     71 // nsIContentSecurityPolicy.idl
     72 static const char* CSPStrDirectives[] = {
     73    "-error-",                    // NO_DIRECTIVE
     74    "default-src",                // DEFAULT_SRC_DIRECTIVE
     75    "script-src",                 // SCRIPT_SRC_DIRECTIVE
     76    "object-src",                 // OBJECT_SRC_DIRECTIVE
     77    "style-src",                  // STYLE_SRC_DIRECTIVE
     78    "img-src",                    // IMG_SRC_DIRECTIVE
     79    "media-src",                  // MEDIA_SRC_DIRECTIVE
     80    "frame-src",                  // FRAME_SRC_DIRECTIVE
     81    "font-src",                   // FONT_SRC_DIRECTIVE
     82    "connect-src",                // CONNECT_SRC_DIRECTIVE
     83    "report-uri",                 // REPORT_URI_DIRECTIVE
     84    "frame-ancestors",            // FRAME_ANCESTORS_DIRECTIVE
     85    "reflected-xss",              // REFLECTED_XSS_DIRECTIVE
     86    "base-uri",                   // BASE_URI_DIRECTIVE
     87    "form-action",                // FORM_ACTION_DIRECTIVE
     88    "manifest-src",               // MANIFEST_SRC_DIRECTIVE
     89    "upgrade-insecure-requests",  // UPGRADE_IF_INSECURE_DIRECTIVE
     90    "child-src",                  // CHILD_SRC_DIRECTIVE
     91    "block-all-mixed-content",    // BLOCK_ALL_MIXED_CONTENT
     92    "sandbox",                    // SANDBOX_DIRECTIVE
     93    "worker-src",                 // WORKER_SRC_DIRECTIVE
     94    "script-src-elem",            // SCRIPT_SRC_ELEM_DIRECTIVE
     95    "script-src-attr",            // SCRIPT_SRC_ATTR_DIRECTIVE
     96    "style-src-elem",             // STYLE_SRC_ELEM_DIRECTIVE
     97    "style-src-attr",             // STYLE_SRC_ATTR_DIRECTIVE
     98    "require-trusted-types-for",  // REQUIRE_TRUSTED_TYPES_FOR_DIRECTIVE
     99    "trusted-types",              // TRUSTED_TYPES_DIRECTIVE
    100    "report-to",                  // REPORT_TO_DIRECTIVE
    101 };
    102 
    103 inline const char* CSP_CSPDirectiveToString(CSPDirective aDir) {
    104  return CSPStrDirectives[static_cast<uint32_t>(aDir)];
    105 }
    106 
    107 CSPDirective CSP_StringToCSPDirective(const nsAString& aDir);
    108 
    109 #define FOR_EACH_CSP_KEYWORD(MACRO)                 \
    110  MACRO(CSP_SELF, "'self'")                         \
    111  MACRO(CSP_UNSAFE_INLINE, "'unsafe-inline'")       \
    112  MACRO(CSP_UNSAFE_EVAL, "'unsafe-eval'")           \
    113  MACRO(CSP_UNSAFE_HASHES, "'unsafe-hashes'")       \
    114  MACRO(CSP_NONE, "'none'")                         \
    115  MACRO(CSP_NONCE, "'nonce-")                       \
    116  MACRO(CSP_REPORT_SAMPLE, "'report-sample'")       \
    117  MACRO(CSP_STRICT_DYNAMIC, "'strict-dynamic'")     \
    118  MACRO(CSP_WASM_UNSAFE_EVAL, "'wasm-unsafe-eval'") \
    119  MACRO(CSP_ALLOW_DUPLICATES, "'allow-duplicates'") \
    120  MACRO(CSP_TRUSTED_TYPES_EVAL, "'trusted-types-eval'")
    121 
    122 enum CSPKeyword {
    123 #define KEYWORD_ENUM(id_, string_) id_,
    124  FOR_EACH_CSP_KEYWORD(KEYWORD_ENUM)
    125 #undef KEYWORD_ENUM
    126 
    127  // CSP_LAST_KEYWORD_VALUE always needs to be the last element in the enum
    128  // because we use it to calculate the size for the char* array.
    129  CSP_LAST_KEYWORD_VALUE,
    130 
    131  // Putting CSP_HASH after the delimitor, because CSP_HASH is not a valid
    132  // keyword (hash uses e.g. sha256, sha512) but we use CSP_HASH internally
    133  // to identify allowed hashes in ::allows.
    134  CSP_HASH
    135 };
    136 
    137 // The keywords, in UTF-8 form.
    138 static const char* gCSPUTF8Keywords[] = {
    139 #define KEYWORD_UTF8_LITERAL(id_, string_) string_,
    140    FOR_EACH_CSP_KEYWORD(KEYWORD_UTF8_LITERAL)
    141 #undef KEYWORD_UTF8_LITERAL
    142 };
    143 
    144 // The keywords, in UTF-16 form.
    145 static const char16_t* gCSPUTF16Keywords[] = {
    146 #define KEYWORD_UTF16_LITERAL(id_, string_) u"" string_,
    147    FOR_EACH_CSP_KEYWORD(KEYWORD_UTF16_LITERAL)
    148 #undef KEYWORD_UTF16_LITERAL
    149 };
    150 
    151 #undef FOR_EACH_CSP_KEYWORD
    152 
    153 inline const char* CSP_EnumToUTF8Keyword(enum CSPKeyword aKey) {
    154  // Make sure all elements in enum CSPKeyword got added to gCSPUTF8Keywords.
    155  static_assert((sizeof(gCSPUTF8Keywords) / sizeof(gCSPUTF8Keywords[0]) ==
    156                 CSP_LAST_KEYWORD_VALUE),
    157                "CSP_LAST_KEYWORD_VALUE != length(gCSPUTF8Keywords)");
    158 
    159  if (static_cast<uint32_t>(aKey) <
    160      static_cast<uint32_t>(CSP_LAST_KEYWORD_VALUE)) {
    161    return gCSPUTF8Keywords[static_cast<uint32_t>(aKey)];
    162  }
    163  return "error: invalid keyword in CSP_EnumToUTF8Keyword";
    164 }
    165 
    166 inline const char16_t* CSP_EnumToUTF16Keyword(enum CSPKeyword aKey) {
    167  // Make sure all elements in enum CSPKeyword got added to gCSPUTF16Keywords.
    168  static_assert((sizeof(gCSPUTF16Keywords) / sizeof(gCSPUTF16Keywords[0]) ==
    169                 CSP_LAST_KEYWORD_VALUE),
    170                "CSP_LAST_KEYWORD_VALUE != length(gCSPUTF16Keywords)");
    171 
    172  if (static_cast<uint32_t>(aKey) <
    173      static_cast<uint32_t>(CSP_LAST_KEYWORD_VALUE)) {
    174    return gCSPUTF16Keywords[static_cast<uint32_t>(aKey)];
    175  }
    176  return u"error: invalid keyword in CSP_EnumToUTF16Keyword";
    177 }
    178 
    179 inline CSPKeyword CSP_UTF16KeywordToEnum(const nsAString& aKey) {
    180  nsString lowerKey = PromiseFlatString(aKey);
    181  ToLowerCase(lowerKey);
    182 
    183  for (uint32_t i = 0; i < CSP_LAST_KEYWORD_VALUE; i++) {
    184    if (lowerKey.Equals(gCSPUTF16Keywords[i])) {
    185      return static_cast<CSPKeyword>(i);
    186    }
    187  }
    188  NS_ASSERTION(false, "Can not convert unknown Keyword to Enum");
    189  return CSP_LAST_KEYWORD_VALUE;
    190 }
    191 
    192 nsresult CSP_AppendCSPFromHeader(nsIContentSecurityPolicy* aCsp,
    193                                 const nsAString& aHeaderValue,
    194                                 bool aReportOnly);
    195 
    196 /* =============== Helpers ================== */
    197 
    198 already_AddRefed<nsIContentSecurityPolicy> CSP_CreateFromHeader(
    199    const nsAString& aHeaderValue, nsIURI* aSelfURI,
    200    nsIPrincipal* aLoadingPrincipal, mozilla::ErrorResult& aRv);
    201 
    202 class nsCSPHostSrc;
    203 
    204 nsCSPHostSrc* CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI);
    205 bool CSP_IsEmptyDirective(const nsAString& aValue, const nsAString& aDir);
    206 bool CSP_IsInvalidDirectiveValue(mozilla::Span<const char16_t> aValue);
    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);
    211 
    212 class nsCSPSrcVisitor;
    213 
    214 void CSP_PercentDecodeStr(const nsAString& aEncStr, nsAString& outDecStr);
    215 bool CSP_ShouldResponseInheritCSP(nsIChannel* aChannel);
    216 bool CSP_ShouldURIInheritCSP(nsIURI* aURI);
    217 
    218 void CSP_ApplyMetaCSPToDoc(mozilla::dom::Document& aDoc,
    219                           const nsAString& aPolicyStr);
    220 
    221 // Checks if the URI is "chrome://browser/content/browser.xhtml"
    222 bool CSP_IsBrowserXHTML(nsIURI* aURI);
    223 
    224 /* =============== nsCSPSrc ================== */
    225 
    226 class nsCSPBaseSrc {
    227 public:
    228  nsCSPBaseSrc();
    229  virtual ~nsCSPBaseSrc();
    230 
    231  virtual bool permits(nsIURI* aUri, bool aWasRedirected, bool aReportOnly,
    232                       bool aUpgradeInsecure) const;
    233  virtual bool allows(enum CSPKeyword aKeyword,
    234                      const nsAString& aHashOrNonce) const;
    235  virtual bool visit(nsCSPSrcVisitor* aVisitor) const = 0;
    236  virtual void toString(nsAString& outStr) const = 0;
    237 
    238  virtual bool isReportSample() const { return false; }
    239 
    240  virtual bool isHash() const { return false; }
    241  virtual bool isNonce() const { return false; }
    242  virtual bool isKeyword(CSPKeyword aKeyword) const { return false; }
    243  virtual bool isTrustedTypesDirectivePolicyName() const { return false; }
    244 };
    245 
    246 /* =============== nsCSPSchemeSrc ============ */
    247 
    248 class nsCSPSchemeSrc : public nsCSPBaseSrc {
    249 public:
    250  explicit nsCSPSchemeSrc(const nsAString& aScheme);
    251  virtual ~nsCSPSchemeSrc();
    252 
    253  bool permits(nsIURI* aUri, bool aWasRedirected, bool aReportOnly,
    254               bool aUpgradeInsecure) const override;
    255  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    256  void toString(nsAString& outStr) const override;
    257 
    258  inline void getScheme(nsAString& outStr) const { outStr.Assign(mScheme); };
    259 
    260 private:
    261  nsString mScheme;
    262 };
    263 
    264 /* =============== nsCSPHostSrc ============== */
    265 
    266 class nsCSPHostSrc : public nsCSPBaseSrc {
    267 public:
    268  explicit nsCSPHostSrc(const nsAString& aHost);
    269  virtual ~nsCSPHostSrc();
    270 
    271  bool permits(nsIURI* aUri, bool aWasRedirected, bool aReportOnly,
    272               bool aUpgradeInsecure) const override;
    273  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    274  void toString(nsAString& outStr) const override;
    275 
    276  void setScheme(const nsAString& aScheme);
    277  void setPort(const nsAString& aPort);
    278  void appendPath(const nsAString& aPath);
    279 
    280  inline void setGeneratedFromSelfKeyword() const {
    281    mGeneratedFromSelfKeyword = true;
    282  }
    283 
    284  inline void setIsUniqueOrigin() const { mIsUniqueOrigin = true; }
    285 
    286  inline void setWithinFrameAncestorsDir(bool aValue) const {
    287    mWithinFrameAncstorsDir = aValue;
    288  }
    289 
    290  inline void getScheme(nsAString& outStr) const { outStr.Assign(mScheme); };
    291 
    292  inline void getHost(nsAString& outStr) const { outStr.Assign(mHost); };
    293 
    294  inline void getPort(nsAString& outStr) const { outStr.Assign(mPort); };
    295 
    296  inline void getPath(nsAString& outStr) const { outStr.Assign(mPath); };
    297 
    298 private:
    299  nsString mScheme;
    300  nsString mHost;
    301  nsString mPort;
    302  nsString mPath;
    303  mutable bool mGeneratedFromSelfKeyword;
    304  mutable bool mIsUniqueOrigin;
    305  mutable bool mWithinFrameAncstorsDir;
    306 };
    307 
    308 /* =============== nsCSPKeywordSrc ============ */
    309 
    310 class nsCSPKeywordSrc : public nsCSPBaseSrc {
    311 public:
    312  explicit nsCSPKeywordSrc(CSPKeyword aKeyword);
    313  virtual ~nsCSPKeywordSrc();
    314 
    315  bool allows(enum CSPKeyword aKeyword,
    316              const nsAString& aHashOrNonce) const override;
    317  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    318  void toString(nsAString& outStr) const override;
    319 
    320  inline CSPKeyword getKeyword() const { return mKeyword; };
    321 
    322  bool isReportSample() const override { return mKeyword == CSP_REPORT_SAMPLE; }
    323 
    324  bool isKeyword(CSPKeyword aKeyword) const final {
    325    return mKeyword == aKeyword;
    326  }
    327 
    328 private:
    329  CSPKeyword mKeyword;
    330 };
    331 
    332 /* =============== nsCSPNonceSource =========== */
    333 
    334 class nsCSPNonceSrc : public nsCSPBaseSrc {
    335 public:
    336  explicit nsCSPNonceSrc(const nsAString& aNonce);
    337  virtual ~nsCSPNonceSrc();
    338 
    339  bool allows(enum CSPKeyword aKeyword,
    340              const nsAString& aHashOrNonce) const override;
    341  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    342  void toString(nsAString& outStr) const override;
    343 
    344  inline void getNonce(nsAString& outStr) const { outStr.Assign(mNonce); };
    345 
    346  bool isNonce() const final { return true; }
    347 
    348 private:
    349  nsString mNonce;
    350 };
    351 
    352 /* =============== nsCSPHashSource ============ */
    353 
    354 class nsCSPHashSrc : public nsCSPBaseSrc {
    355 public:
    356  nsCSPHashSrc(const nsAString& algo, const nsAString& hash);
    357  virtual ~nsCSPHashSrc();
    358 
    359  bool allows(enum CSPKeyword aKeyword,
    360              const nsAString& aHashOrNonce) const override;
    361  void toString(nsAString& outStr) const override;
    362  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    363 
    364  inline void getAlgorithm(nsAString& outStr) const {
    365    outStr.Assign(mAlgorithm);
    366  };
    367 
    368  inline void getHash(nsAString& outStr) const { outStr.Assign(mHash); };
    369 
    370  bool isHash() const final { return true; }
    371 
    372 private:
    373  nsString mAlgorithm;
    374  nsString mHash;
    375 };
    376 
    377 /* =============== nsCSPReportURI ============ */
    378 
    379 class nsCSPReportURI : public nsCSPBaseSrc {
    380 public:
    381  explicit nsCSPReportURI(nsIURI* aURI);
    382  virtual ~nsCSPReportURI();
    383 
    384  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    385  void toString(nsAString& outStr) const override;
    386 
    387 private:
    388  nsCOMPtr<nsIURI> mReportURI;
    389 };
    390 
    391 /* =============== nsCSPGroup ============ */
    392 
    393 class nsCSPGroup : public nsCSPBaseSrc {
    394 public:
    395  explicit nsCSPGroup(const nsAString& aGroup);
    396  virtual ~nsCSPGroup();
    397 
    398  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    399  void toString(nsAString& aOutStr) const override;
    400 
    401 private:
    402  nsString mGroup;
    403 };
    404 
    405 /* =============== nsCSPSandboxFlags ================== */
    406 
    407 class nsCSPSandboxFlags : public nsCSPBaseSrc {
    408 public:
    409  explicit nsCSPSandboxFlags(const nsAString& aFlags);
    410  virtual ~nsCSPSandboxFlags();
    411 
    412  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    413  void toString(nsAString& outStr) const override;
    414 
    415 private:
    416  nsString mFlags;
    417 };
    418 
    419 /* =============== nsCSPRequireTrustedTypesForDirectiveValue =============== */
    420 
    421 class nsCSPRequireTrustedTypesForDirectiveValue : public nsCSPBaseSrc {
    422 public:
    423  explicit nsCSPRequireTrustedTypesForDirectiveValue(const nsAString& aValue);
    424  virtual ~nsCSPRequireTrustedTypesForDirectiveValue() = default;
    425 
    426  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    427  void toString(nsAString& aOutStr) const override;
    428 
    429 private:
    430  const nsString mValue;
    431 };
    432 
    433 /* =============== nsCSPTrustedTypesDirectiveExpression =============== */
    434 
    435 class nsCSPTrustedTypesDirectivePolicyName : public nsCSPBaseSrc {
    436 public:
    437  explicit nsCSPTrustedTypesDirectivePolicyName(const nsAString& aName);
    438  virtual ~nsCSPTrustedTypesDirectivePolicyName() = default;
    439 
    440  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    441  void toString(nsAString& aOutStr) const override;
    442 
    443  bool isTrustedTypesDirectivePolicyName() const override { return true; }
    444 
    445  const nsString& GetName() const { return mName; }
    446 
    447 private:
    448  const nsString mName;
    449 };
    450 
    451 class nsCSPTrustedTypesDirectiveInvalidToken : public nsCSPBaseSrc {
    452 public:
    453  explicit nsCSPTrustedTypesDirectiveInvalidToken(
    454      const nsAString& aInvalidToken);
    455  virtual ~nsCSPTrustedTypesDirectiveInvalidToken() = default;
    456 
    457  bool visit(nsCSPSrcVisitor* aVisitor) const override;
    458  void toString(nsAString& aOutStr) const override;
    459 
    460 private:
    461  const nsString mInvalidToken;
    462 };
    463 
    464 /* =============== nsCSPSrcVisitor ================== */
    465 
    466 class nsCSPSrcVisitor {
    467 public:
    468  virtual bool visitSchemeSrc(const nsCSPSchemeSrc& src) = 0;
    469 
    470  virtual bool visitHostSrc(const nsCSPHostSrc& src) = 0;
    471 
    472  virtual bool visitKeywordSrc(const nsCSPKeywordSrc& src) = 0;
    473 
    474  virtual bool visitNonceSrc(const nsCSPNonceSrc& src) = 0;
    475 
    476  virtual bool visitHashSrc(const nsCSPHashSrc& src) = 0;
    477 
    478 protected:
    479  explicit nsCSPSrcVisitor() = default;
    480  virtual ~nsCSPSrcVisitor() = default;
    481 };
    482 
    483 /* =============== nsCSPDirective ============= */
    484 
    485 class nsCSPDirective {
    486 public:
    487  explicit nsCSPDirective(CSPDirective aDirective);
    488  virtual ~nsCSPDirective();
    489 
    490  virtual bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo,
    491                       nsIURI* aUri, bool aWasRedirected, bool aReportOnly,
    492                       bool aUpgradeInsecure) const;
    493  virtual bool allows(enum CSPKeyword aKeyword,
    494                      const nsAString& aHashOrNonce) const;
    495  bool allowsAllInlineBehavior(CSPDirective aDir) const;
    496 
    497  // Implements step 2.1 to 2.7 of
    498  // <https://w3c.github.io/trusted-types/dist/spec/#should-block-create-policy>.
    499  bool ShouldCreateViolationForNewTrustedTypesPolicy(
    500      const nsAString& aPolicyName,
    501      const nsTArray<nsString>& aCreatedPolicyNames) const;
    502 
    503  // Implements step 2.1 to 2.4 of
    504  // <https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-does-sink-type-require-trusted-types>.
    505  bool AreTrustedTypesForSinkGroupRequired(const nsAString& aSinkGroup) const;
    506 
    507  virtual void toString(nsAString& outStr) const;
    508  void toDomCSPStruct(mozilla::dom::CSP& outCSP) const;
    509 
    510  // Takes ownership of the passed sources.
    511  virtual void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) {
    512    mSrcs = aSrcs.Clone();
    513  }
    514 
    515  bool isDefaultDirective() const;
    516 
    517  virtual bool equals(CSPDirective aDirective) const;
    518 
    519  void getReportURIs(nsTArray<nsString>& outReportURIs) const;
    520 
    521  void getReportGroup(nsAString& outReportGroup) const;
    522 
    523  bool visitSrcs(nsCSPSrcVisitor* aVisitor) const;
    524 
    525  virtual void getDirName(nsAString& outStr) const;
    526 
    527  bool hasReportSampleKeyword() const;
    528 
    529 private:
    530  bool ContainsTrustedTypesDirectivePolicyName(
    531      const nsAString& aPolicyName) const;
    532 
    533 protected:
    534  CSPDirective mDirective;
    535  nsTArray<nsCSPBaseSrc*> mSrcs;
    536 };
    537 
    538 /* =============== nsCSPChildSrcDirective ============= */
    539 
    540 /*
    541 * In CSP 3 child-src is deprecated. For backwards compatibility
    542 * child-src needs to restrict:
    543 *   (*) frames, in case frame-src is not expicitly specified
    544 *   (*) workers, in case worker-src is not expicitly specified
    545 */
    546 class nsCSPChildSrcDirective : public nsCSPDirective {
    547 public:
    548  explicit nsCSPChildSrcDirective(CSPDirective aDirective);
    549  virtual ~nsCSPChildSrcDirective();
    550 
    551  void setRestrictFrames() { mRestrictFrames = true; }
    552 
    553  void setRestrictWorkers() { mRestrictWorkers = true; }
    554 
    555  virtual bool equals(CSPDirective aDirective) const override;
    556 
    557 private:
    558  bool mRestrictFrames;
    559  bool mRestrictWorkers;
    560 };
    561 
    562 /* =============== nsCSPScriptSrcDirective ============= */
    563 
    564 /*
    565 * In CSP 3 worker-src restricts workers, for backwards compatibily
    566 * script-src has to restrict workers as the ultimate fallback if
    567 * neither worker-src nor child-src is present in a CSP.
    568 */
    569 class nsCSPScriptSrcDirective : public nsCSPDirective {
    570 public:
    571  explicit nsCSPScriptSrcDirective(CSPDirective aDirective);
    572  virtual ~nsCSPScriptSrcDirective();
    573 
    574  void setRestrictWorkers() { mRestrictWorkers = true; }
    575  void setRestrictScriptElem() { mRestrictScriptElem = true; }
    576  void setRestrictScriptAttr() { mRestrictScriptAttr = true; }
    577 
    578  bool equals(CSPDirective aDirective) const override;
    579 
    580 private:
    581  bool mRestrictWorkers = false;
    582  bool mRestrictScriptElem = false;
    583  bool mRestrictScriptAttr = false;
    584 };
    585 
    586 /* =============== nsCSPStyleSrcDirective ============= */
    587 
    588 /*
    589 * In CSP 3 style-src is use as a fallback for style-src-elem and
    590 * style-src-attr.
    591 */
    592 class nsCSPStyleSrcDirective : public nsCSPDirective {
    593 public:
    594  explicit nsCSPStyleSrcDirective(CSPDirective aDirective);
    595  virtual ~nsCSPStyleSrcDirective();
    596 
    597  void setRestrictStyleElem() { mRestrictStyleElem = true; }
    598  void setRestrictStyleAttr() { mRestrictStyleAttr = true; }
    599 
    600  bool equals(CSPDirective aDirective) const override;
    601 
    602 private:
    603  bool mRestrictStyleElem = false;
    604  bool mRestrictStyleAttr = false;
    605 };
    606 
    607 /* =============== nsBlockAllMixedContentDirective === */
    608 
    609 class nsBlockAllMixedContentDirective : public nsCSPDirective {
    610 public:
    611  explicit nsBlockAllMixedContentDirective(CSPDirective aDirective);
    612  ~nsBlockAllMixedContentDirective();
    613 
    614  bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo, nsIURI* aUri,
    615               bool aWasRedirected, bool aReportOnly,
    616               bool aUpgradeInsecure) const override {
    617    return false;
    618  }
    619 
    620  bool permits(nsIURI* aUri) const { return false; }
    621 
    622  bool allows(enum CSPKeyword aKeyword,
    623              const nsAString& aHashOrNonce) const override {
    624    return false;
    625  }
    626 
    627  void toString(nsAString& outStr) const override;
    628 
    629  void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) override {
    630    MOZ_ASSERT(false, "block-all-mixed-content does not hold any srcs");
    631  }
    632 
    633  void getDirName(nsAString& outStr) const override;
    634 };
    635 
    636 /* =============== nsUpgradeInsecureDirective === */
    637 
    638 /*
    639 * Upgrading insecure requests includes the following actors:
    640 * (1) CSP:
    641 *     The CSP implementation allowlists the http-request
    642 *     in case the policy is executed in enforcement mode.
    643 *     The CSP implementation however does not allow http
    644 *     requests to succeed if executed in report-only mode.
    645 *     In such a case the CSP implementation reports the
    646 *     error back to the page.
    647 *
    648 * (2) MixedContent:
    649 *     The evalution of MixedContent allowlists all http
    650 *     requests with the promise that the http requests
    651 *     gets upgraded to https before any data is fetched
    652 *     from the network.
    653 *
    654 * (3) CORS:
    655 *     Does not consider the http request to be of a
    656 *     different origin in case the scheme is the only
    657 *     difference in otherwise matching URIs.
    658 *
    659 * (4) nsHttpChannel:
    660 *     Before connecting, the channel gets redirected
    661 *     to use https.
    662 *
    663 * (5) WebSocketChannel:
    664 *     Similar to the httpChannel, the websocketchannel
    665 *     gets upgraded from ws to wss.
    666 */
    667 class nsUpgradeInsecureDirective : public nsCSPDirective {
    668 public:
    669  explicit nsUpgradeInsecureDirective(CSPDirective aDirective);
    670  ~nsUpgradeInsecureDirective();
    671 
    672  bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo, nsIURI* aUri,
    673               bool aWasRedirected, bool aReportOnly,
    674               bool aUpgradeInsecure) const override {
    675    return false;
    676  }
    677 
    678  bool permits(nsIURI* aUri) const { return false; }
    679 
    680  bool allows(enum CSPKeyword aKeyword,
    681              const nsAString& aHashOrNonce) const override {
    682    return false;
    683  }
    684 
    685  void toString(nsAString& outStr) const override;
    686 
    687  void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs) override {
    688    MOZ_ASSERT(false, "upgrade-insecure-requests does not hold any srcs");
    689  }
    690 
    691  void getDirName(nsAString& outStr) const override;
    692 };
    693 
    694 /* =============== nsCSPPolicy ================== */
    695 
    696 class nsCSPPolicy {
    697 public:
    698  nsCSPPolicy();
    699  virtual ~nsCSPPolicy();
    700 
    701  bool permits(CSPDirective aDirective, nsILoadInfo* aLoadInfo, nsIURI* aUri,
    702               bool aWasRedirected, bool aSpecific,
    703               nsAString& outViolatedDirective,
    704               nsAString& outViolatedDirectiveString) const;
    705  bool allows(CSPDirective aDirective, enum CSPKeyword aKeyword,
    706              const nsAString& aHashOrNonce) const;
    707  void toString(nsAString& outStr) const;
    708  void toDomCSPStruct(mozilla::dom::CSP& outCSP) const;
    709 
    710  inline void addDirective(nsCSPDirective* aDir) {
    711    if (aDir->equals(
    712            nsIContentSecurityPolicy::REQUIRE_TRUSTED_TYPES_FOR_DIRECTIVE)) {
    713      mHasRequireTrustedTypesForDirective = true;
    714    }
    715    mDirectives.AppendElement(aDir);
    716  }
    717 
    718  inline void addUpgradeInsecDir(nsUpgradeInsecureDirective* aDir) {
    719    mUpgradeInsecDir = aDir;
    720    addDirective(aDir);
    721  }
    722 
    723  bool hasDirective(CSPDirective aDir) const;
    724 
    725  inline void setDeliveredViaMetaTagFlag(bool aFlag) {
    726    mDeliveredViaMetaTag = aFlag;
    727  }
    728 
    729  inline bool getDeliveredViaMetaTagFlag() const {
    730    return mDeliveredViaMetaTag;
    731  }
    732 
    733  inline bool hasRequireTrustedTypesForDirective() const {
    734    return mHasRequireTrustedTypesForDirective;
    735  }
    736 
    737  inline void setReportOnlyFlag(bool aFlag) { mReportOnly = aFlag; }
    738 
    739  // Related to https://w3c.github.io/webappsec-csp/#policy-disposition.
    740  // @return true if disposition is "report", false otherwise.
    741  inline bool getReportOnlyFlag() const { return mReportOnly; }
    742 
    743  enum class Disposition { Enforce, Report };
    744 
    745  Disposition getDisposition() const {
    746    return getReportOnlyFlag() ? Disposition::Report : Disposition::Enforce;
    747  }
    748 
    749  void getReportURIs(nsTArray<nsString>& outReportURIs) const;
    750 
    751  void getReportGroup(nsAString& outReportGroup) const;
    752 
    753  void getViolatedDirectiveInformation(CSPDirective aDirective,
    754                                       nsAString& aDirectiveName,
    755                                       nsAString& aDirectiveNameAndValue,
    756                                       bool* aReportSample) const;
    757 
    758  uint32_t getSandboxFlags() const;
    759 
    760  inline uint32_t getNumDirectives() const { return mDirectives.Length(); }
    761 
    762  void getDirectiveNames(nsTArray<nsString>& outDirectives) const;
    763 
    764  bool visitDirectiveSrcs(CSPDirective aDir, nsCSPSrcVisitor* aVisitor) const;
    765 
    766  bool allowsAllInlineBehavior(CSPDirective aDir) const;
    767 
    768  /*
    769   * Implements step 2.1 to 2.7 of
    770   * <https://w3c.github.io/trusted-types/dist/spec/#should-block-create-policy>.
    771   * and returns the result of "createViolation".
    772   *
    773   * @param aCreatedPolicyNames The already created policy names.
    774   * @return true if a violation for aPolicyName should be created.
    775   */
    776  bool ShouldCreateViolationForNewTrustedTypesPolicy(
    777      const nsAString& aPolicyName,
    778      const nsTArray<nsString>& aCreatedPolicyNames) const;
    779 
    780  /**
    781   * Implements step 2.1 to 2.4 of
    782   * <https://w3c.github.io/trusted-types/dist/spec/#abstract-opdef-does-sink-type-require-trusted-types>.
    783   */
    784  bool AreTrustedTypesForSinkGroupRequired(const nsAString& aSinkGroup) const;
    785 
    786 private:
    787  nsCSPDirective* matchingOrDefaultDirective(CSPDirective aDirective) const;
    788 
    789  nsUpgradeInsecureDirective* mUpgradeInsecDir;
    790  nsTArray<nsCSPDirective*> mDirectives;
    791  bool mHasRequireTrustedTypesForDirective = false;
    792  bool mReportOnly;
    793  bool mDeliveredViaMetaTag;
    794 };
    795 
    796 #endif /* nsCSPUtils_h___ */