Line data Source code
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 "nsCOMPtr.h"
11 : #include "nsIContentPolicy.h"
12 : #include "nsIContentSecurityPolicy.h"
13 : #include "nsIURI.h"
14 : #include "nsString.h"
15 : #include "nsTArray.h"
16 : #include "nsUnicharUtils.h"
17 : #include "mozilla/Logging.h"
18 :
19 : namespace mozilla {
20 : namespace dom {
21 : struct CSP;
22 : } // namespace dom
23 : } // namespace mozilla
24 :
25 : /* =============== Logging =================== */
26 :
27 : void CSP_LogLocalizedStr(const char16_t* aName,
28 : const char16_t** aParams,
29 : uint32_t aLength,
30 : const nsAString& aSourceName,
31 : const nsAString& aSourceLine,
32 : uint32_t aLineNumber,
33 : uint32_t aColumnNumber,
34 : uint32_t aFlags,
35 : const char* aCategory,
36 : uint64_t aInnerWindowID);
37 :
38 : void CSP_GetLocalizedStr(const char16_t* aName,
39 : const char16_t** aParams,
40 : uint32_t aLength,
41 : char16_t** outResult);
42 :
43 : void CSP_LogStrMessage(const nsAString& aMsg);
44 :
45 : void CSP_LogMessage(const nsAString& aMessage,
46 : const nsAString& aSourceName,
47 : const nsAString& aSourceLine,
48 : uint32_t aLineNumber,
49 : uint32_t aColumnNumber,
50 : uint32_t aFlags,
51 : const char* aCategory,
52 : uint64_t aInnerWindowID);
53 :
54 :
55 : /* =============== Constant and Type Definitions ================== */
56 :
57 : #define INLINE_STYLE_VIOLATION_OBSERVER_TOPIC "violated base restriction: Inline Stylesheets will not apply"
58 : #define INLINE_SCRIPT_VIOLATION_OBSERVER_TOPIC "violated base restriction: Inline Scripts will not execute"
59 : #define EVAL_VIOLATION_OBSERVER_TOPIC "violated base restriction: Code will not be created from strings"
60 : #define SCRIPT_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid nonce"
61 : #define STYLE_NONCE_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid nonce"
62 : #define SCRIPT_HASH_VIOLATION_OBSERVER_TOPIC "Inline Script had invalid hash"
63 : #define STYLE_HASH_VIOLATION_OBSERVER_TOPIC "Inline Style had invalid hash"
64 : #define REQUIRE_SRI_SCRIPT_VIOLATION_OBSERVER_TOPIC "Missing required Subresource Integrity for Script"
65 : #define REQUIRE_SRI_STYLE_VIOLATION_OBSERVER_TOPIC "Missing required Subresource Integrity for Style"
66 :
67 : // these strings map to the CSPDirectives in nsIContentSecurityPolicy
68 : // NOTE: When implementing a new directive, you will need to add it here but also
69 : // add a corresponding entry to the constants in nsIContentSecurityPolicy.idl
70 : // and also create an entry for the new directive in
71 : // nsCSPDirective::toDomCSPStruct() and add it to CSPDictionaries.webidl.
72 : // Order of elements below important! Make sure it matches the order as in
73 : // nsIContentSecurityPolicy.idl
74 : static const char* CSPStrDirectives[] = {
75 : "-error-", // NO_DIRECTIVE
76 : "default-src", // DEFAULT_SRC_DIRECTIVE
77 : "script-src", // SCRIPT_SRC_DIRECTIVE
78 : "object-src", // OBJECT_SRC_DIRECTIVE
79 : "style-src", // STYLE_SRC_DIRECTIVE
80 : "img-src", // IMG_SRC_DIRECTIVE
81 : "media-src", // MEDIA_SRC_DIRECTIVE
82 : "frame-src", // FRAME_SRC_DIRECTIVE
83 : "font-src", // FONT_SRC_DIRECTIVE
84 : "connect-src", // CONNECT_SRC_DIRECTIVE
85 : "report-uri", // REPORT_URI_DIRECTIVE
86 : "frame-ancestors", // FRAME_ANCESTORS_DIRECTIVE
87 : "reflected-xss", // REFLECTED_XSS_DIRECTIVE
88 : "base-uri", // BASE_URI_DIRECTIVE
89 : "form-action", // FORM_ACTION_DIRECTIVE
90 : "referrer", // REFERRER_DIRECTIVE
91 : "manifest-src", // MANIFEST_SRC_DIRECTIVE
92 : "upgrade-insecure-requests", // UPGRADE_IF_INSECURE_DIRECTIVE
93 : "child-src", // CHILD_SRC_DIRECTIVE
94 : "block-all-mixed-content", // BLOCK_ALL_MIXED_CONTENT
95 : "require-sri-for", // REQUIRE_SRI_FOR
96 : "sandbox" // SANDBOX_DIRECTIVE
97 : };
98 :
99 0 : inline const char* CSP_CSPDirectiveToString(CSPDirective aDir)
100 : {
101 0 : return CSPStrDirectives[static_cast<uint32_t>(aDir)];
102 : }
103 :
104 0 : inline CSPDirective CSP_StringToCSPDirective(const nsAString& aDir)
105 : {
106 0 : nsString lowerDir = PromiseFlatString(aDir);
107 0 : ToLowerCase(lowerDir);
108 :
109 0 : uint32_t numDirs = (sizeof(CSPStrDirectives) / sizeof(CSPStrDirectives[0]));
110 0 : for (uint32_t i = 1; i < numDirs; i++) {
111 0 : if (lowerDir.EqualsASCII(CSPStrDirectives[i])) {
112 0 : return static_cast<CSPDirective>(i);
113 : }
114 : }
115 0 : NS_ASSERTION(false, "Can not convert unknown Directive to Integer");
116 0 : return nsIContentSecurityPolicy::NO_DIRECTIVE;
117 : }
118 :
119 : // Please add any new enum items not only to CSPKeyword, but also add
120 : // a string version for every enum >> using the same index << to
121 : // CSPStrKeywords underneath.
122 : enum CSPKeyword {
123 : CSP_SELF = 0,
124 : CSP_UNSAFE_INLINE,
125 : CSP_UNSAFE_EVAL,
126 : CSP_NONE,
127 : CSP_NONCE,
128 : CSP_REQUIRE_SRI_FOR,
129 : CSP_STRICT_DYNAMIC,
130 : // CSP_LAST_KEYWORD_VALUE always needs to be the last element in the enum
131 : // because we use it to calculate the size for the char* array.
132 : CSP_LAST_KEYWORD_VALUE,
133 : // Putting CSP_HASH after the delimitor, because CSP_HASH is not a valid
134 : // keyword (hash uses e.g. sha256, sha512) but we use CSP_HASH internally
135 : // to identify allowed hashes in ::allows.
136 : CSP_HASH
137 : };
138 :
139 : static const char* CSPStrKeywords[] = {
140 : "'self'", // CSP_SELF = 0
141 : "'unsafe-inline'", // CSP_UNSAFE_INLINE
142 : "'unsafe-eval'", // CSP_UNSAFE_EVAL
143 : "'none'", // CSP_NONE
144 : "'nonce-", // CSP_NONCE
145 : "require-sri-for", // CSP_REQUIRE_SRI_FOR
146 : "'strict-dynamic'" // CSP_STRICT_DYNAMIC
147 : // Remember: CSP_HASH is not supposed to be used
148 : };
149 :
150 0 : inline const char* CSP_EnumToKeyword(enum CSPKeyword aKey)
151 : {
152 : // Make sure all elements in enum CSPKeyword got added to CSPStrKeywords.
153 : static_assert((sizeof(CSPStrKeywords) / sizeof(CSPStrKeywords[0]) ==
154 : static_cast<uint32_t>(CSP_LAST_KEYWORD_VALUE)),
155 : "CSP_LAST_KEYWORD_VALUE does not match length of CSPStrKeywords");
156 :
157 0 : if (static_cast<uint32_t>(aKey) < static_cast<uint32_t>(CSP_LAST_KEYWORD_VALUE)) {
158 0 : return CSPStrKeywords[static_cast<uint32_t>(aKey)];
159 : }
160 0 : return "error: invalid keyword in CSP_EnumToKeyword";
161 : }
162 :
163 0 : inline CSPKeyword CSP_KeywordToEnum(const nsAString& aKey)
164 : {
165 0 : nsString lowerKey = PromiseFlatString(aKey);
166 0 : ToLowerCase(lowerKey);
167 :
168 : static_assert(CSP_LAST_KEYWORD_VALUE ==
169 : (sizeof(CSPStrKeywords) / sizeof(CSPStrKeywords[0])),
170 : "CSP_LAST_KEYWORD_VALUE does not match length of CSPStrKeywords");
171 :
172 0 : for (uint32_t i = 0; i < CSP_LAST_KEYWORD_VALUE; i++) {
173 0 : if (lowerKey.EqualsASCII(CSPStrKeywords[i])) {
174 0 : return static_cast<CSPKeyword>(i);
175 : }
176 : }
177 0 : NS_ASSERTION(false, "Can not convert unknown Keyword to Enum");
178 0 : return CSP_LAST_KEYWORD_VALUE;
179 : }
180 :
181 : nsresult CSP_AppendCSPFromHeader(nsIContentSecurityPolicy* aCsp,
182 : const nsAString& aHeaderValue,
183 : bool aReportOnly);
184 :
185 : /* =============== Helpers ================== */
186 :
187 : class nsCSPHostSrc;
188 :
189 : nsCSPHostSrc* CSP_CreateHostSrcFromSelfURI(nsIURI* aSelfURI);
190 : bool CSP_IsValidDirective(const nsAString& aDir);
191 : bool CSP_IsDirective(const nsAString& aValue, CSPDirective aDir);
192 : bool CSP_IsKeyword(const nsAString& aValue, enum CSPKeyword aKey);
193 : bool CSP_IsQuotelessKeyword(const nsAString& aKey);
194 : CSPDirective CSP_ContentTypeToDirective(nsContentPolicyType aType);
195 :
196 : class nsCSPSrcVisitor;
197 :
198 : void CSP_PercentDecodeStr(const nsAString& aEncStr, nsAString& outDecStr);
199 :
200 : /* =============== nsCSPSrc ================== */
201 :
202 : class nsCSPBaseSrc {
203 : public:
204 : nsCSPBaseSrc();
205 : virtual ~nsCSPBaseSrc();
206 :
207 : virtual bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
208 : bool aReportOnly, bool aUpgradeInsecure, bool aParserCreated) const;
209 : virtual bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
210 : bool aParserCreated) const;
211 : virtual bool visit(nsCSPSrcVisitor* aVisitor) const = 0;
212 : virtual void toString(nsAString& outStr) const = 0;
213 :
214 0 : virtual void invalidate() const
215 0 : { mInvalidated = true; }
216 :
217 : protected:
218 : // invalidate srcs if 'script-dynamic' is present or also invalidate
219 : // unsafe-inline' if nonce- or hash-source specified
220 : mutable bool mInvalidated;
221 :
222 : };
223 :
224 : /* =============== nsCSPSchemeSrc ============ */
225 :
226 : class nsCSPSchemeSrc : public nsCSPBaseSrc {
227 : public:
228 : explicit nsCSPSchemeSrc(const nsAString& aScheme);
229 : virtual ~nsCSPSchemeSrc();
230 :
231 : bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
232 : bool aReportOnly, bool aUpgradeInsecure, bool aParserCreated) const;
233 : bool visit(nsCSPSrcVisitor* aVisitor) const;
234 : void toString(nsAString& outStr) const;
235 :
236 0 : inline void getScheme(nsAString& outStr) const
237 0 : { outStr.Assign(mScheme); };
238 :
239 : private:
240 : nsString mScheme;
241 : };
242 :
243 : /* =============== nsCSPHostSrc ============== */
244 :
245 : class nsCSPHostSrc : public nsCSPBaseSrc {
246 : public:
247 : explicit nsCSPHostSrc(const nsAString& aHost);
248 : virtual ~nsCSPHostSrc();
249 :
250 : bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
251 : bool aReportOnly, bool aUpgradeInsecure, bool aParserCreated) const;
252 : bool visit(nsCSPSrcVisitor* aVisitor) const;
253 : void toString(nsAString& outStr) const;
254 :
255 : void setScheme(const nsAString& aScheme);
256 : void setPort(const nsAString& aPort);
257 : void appendPath(const nsAString &aPath);
258 :
259 0 : inline void setGeneratedFromSelfKeyword() const
260 0 : { mGeneratedFromSelfKeyword = true; }
261 :
262 0 : inline void setWithinFrameAncestorsDir(bool aValue) const
263 0 : { mWithinFrameAncstorsDir = aValue; }
264 :
265 0 : inline void getScheme(nsAString& outStr) const
266 0 : { outStr.Assign(mScheme); };
267 :
268 0 : inline void getHost(nsAString& outStr) const
269 0 : { outStr.Assign(mHost); };
270 :
271 : inline void getPort(nsAString& outStr) const
272 : { outStr.Assign(mPort); };
273 :
274 : inline void getPath(nsAString& outStr) const
275 : { outStr.Assign(mPath); };
276 :
277 : private:
278 : nsString mScheme;
279 : nsString mHost;
280 : nsString mPort;
281 : nsString mPath;
282 : mutable bool mGeneratedFromSelfKeyword;
283 : mutable bool mWithinFrameAncstorsDir;
284 : };
285 :
286 : /* =============== nsCSPKeywordSrc ============ */
287 :
288 : class nsCSPKeywordSrc : public nsCSPBaseSrc {
289 : public:
290 : explicit nsCSPKeywordSrc(CSPKeyword aKeyword);
291 : virtual ~nsCSPKeywordSrc();
292 :
293 : bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
294 : bool aParserCreated) const;
295 : bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
296 : bool aReportOnly, bool aUpgradeInsecure, bool aParserCreated) const;
297 : bool visit(nsCSPSrcVisitor* aVisitor) const;
298 : void toString(nsAString& outStr) const;
299 :
300 0 : inline CSPKeyword getKeyword() const
301 0 : { return mKeyword; };
302 :
303 0 : inline void invalidate() const
304 : {
305 : // keywords that need to invalidated
306 0 : if (mKeyword == CSP_SELF || mKeyword == CSP_UNSAFE_INLINE) {
307 0 : mInvalidated = true;
308 : }
309 0 : }
310 :
311 : private:
312 : CSPKeyword mKeyword;
313 : };
314 :
315 : /* =============== nsCSPNonceSource =========== */
316 :
317 : class nsCSPNonceSrc : public nsCSPBaseSrc {
318 : public:
319 : explicit nsCSPNonceSrc(const nsAString& aNonce);
320 : virtual ~nsCSPNonceSrc();
321 :
322 : bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
323 : bool aReportOnly, bool aUpgradeInsecure, bool aParserCreated) const;
324 : bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
325 : bool aParserCreated) const;
326 : bool visit(nsCSPSrcVisitor* aVisitor) const;
327 : void toString(nsAString& outStr) const;
328 :
329 : inline void getNonce(nsAString& outStr) const
330 : { outStr.Assign(mNonce); };
331 :
332 0 : inline void invalidate() const
333 : {
334 : // overwrite nsCSPBaseSRC::invalidate() and explicitily
335 : // do *not* invalidate, because 'strict-dynamic' should
336 : // not invalidate nonces.
337 0 : }
338 :
339 : private:
340 : nsString mNonce;
341 : };
342 :
343 : /* =============== nsCSPHashSource ============ */
344 :
345 : class nsCSPHashSrc : public nsCSPBaseSrc {
346 : public:
347 : nsCSPHashSrc(const nsAString& algo, const nsAString& hash);
348 : virtual ~nsCSPHashSrc();
349 :
350 : bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
351 : bool aParserCreated) const;
352 : void toString(nsAString& outStr) const;
353 : bool visit(nsCSPSrcVisitor* aVisitor) const;
354 :
355 : inline void getAlgorithm(nsAString& outStr) const
356 : { outStr.Assign(mAlgorithm); };
357 :
358 : inline void getHash(nsAString& outStr) const
359 : { outStr.Assign(mHash); };
360 :
361 0 : inline void invalidate() const
362 : {
363 : // overwrite nsCSPBaseSRC::invalidate() and explicitily
364 : // do *not* invalidate, because 'strict-dynamic' should
365 : // not invalidate hashes.
366 0 : }
367 :
368 : private:
369 : nsString mAlgorithm;
370 : nsString mHash;
371 : };
372 :
373 : /* =============== nsCSPReportURI ============ */
374 :
375 : class nsCSPReportURI : public nsCSPBaseSrc {
376 : public:
377 : explicit nsCSPReportURI(nsIURI* aURI);
378 : virtual ~nsCSPReportURI();
379 :
380 : bool visit(nsCSPSrcVisitor* aVisitor) const;
381 : void toString(nsAString& outStr) const;
382 :
383 : private:
384 : nsCOMPtr<nsIURI> mReportURI;
385 : };
386 :
387 : /* =============== nsCSPSandboxFlags ================== */
388 :
389 : class nsCSPSandboxFlags : public nsCSPBaseSrc {
390 : public:
391 : explicit nsCSPSandboxFlags(const nsAString& aFlags);
392 : virtual ~nsCSPSandboxFlags();
393 :
394 : bool visit(nsCSPSrcVisitor* aVisitor) const;
395 : void toString(nsAString& outStr) const;
396 :
397 : private:
398 : nsString mFlags;
399 : };
400 :
401 : /* =============== nsCSPSrcVisitor ================== */
402 :
403 : class nsCSPSrcVisitor {
404 : public:
405 : virtual bool visitSchemeSrc(const nsCSPSchemeSrc& src) = 0;
406 :
407 : virtual bool visitHostSrc(const nsCSPHostSrc& src) = 0;
408 :
409 : virtual bool visitKeywordSrc(const nsCSPKeywordSrc& src) = 0;
410 :
411 : virtual bool visitNonceSrc(const nsCSPNonceSrc& src) = 0;
412 :
413 : virtual bool visitHashSrc(const nsCSPHashSrc& src) = 0;
414 :
415 : protected:
416 0 : explicit nsCSPSrcVisitor() {};
417 0 : virtual ~nsCSPSrcVisitor() {};
418 : };
419 :
420 : /* =============== nsCSPDirective ============= */
421 :
422 : class nsCSPDirective {
423 : public:
424 : explicit nsCSPDirective(CSPDirective aDirective);
425 : virtual ~nsCSPDirective();
426 :
427 : virtual bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
428 : bool aReportOnly, bool aUpgradeInsecure, bool aParserCreated) const;
429 : virtual bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
430 : bool aParserCreated) const;
431 : virtual void toString(nsAString& outStr) const;
432 : void toDomCSPStruct(mozilla::dom::CSP& outCSP) const;
433 :
434 0 : virtual void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs)
435 0 : { mSrcs = aSrcs; }
436 :
437 : virtual bool restrictsContentType(nsContentPolicyType aContentType) const;
438 :
439 0 : inline bool isDefaultDirective() const
440 0 : { return mDirective == nsIContentSecurityPolicy::DEFAULT_SRC_DIRECTIVE; }
441 :
442 : virtual bool equals(CSPDirective aDirective) const;
443 :
444 : void getReportURIs(nsTArray<nsString> &outReportURIs) const;
445 :
446 : bool visitSrcs(nsCSPSrcVisitor* aVisitor) const;
447 :
448 : private:
449 : CSPDirective mDirective;
450 : nsTArray<nsCSPBaseSrc*> mSrcs;
451 : };
452 :
453 : /* =============== nsCSPChildSrcDirective ============= */
454 :
455 : /*
456 : * In CSP 2, the child-src directive covers both workers and
457 : * subdocuments (i.e., frames and iframes). Workers were removed
458 : * from script-src, but frames can be controlled by either child-src
459 : * or frame-src directives, so child-src needs to know whether it should
460 : * also restrict frames. When both are present the frame-src directive
461 : * takes precedent.
462 : */
463 : class nsCSPChildSrcDirective : public nsCSPDirective {
464 : public:
465 : explicit nsCSPChildSrcDirective(CSPDirective aDirective);
466 : virtual ~nsCSPChildSrcDirective();
467 :
468 : void setHandleFrameSrc();
469 :
470 : virtual bool restrictsContentType(nsContentPolicyType aContentType) const;
471 :
472 : virtual bool equals(CSPDirective aDirective) const;
473 :
474 : private:
475 : bool mHandleFrameSrc;
476 : };
477 :
478 : /* =============== nsBlockAllMixedContentDirective === */
479 :
480 : class nsBlockAllMixedContentDirective : public nsCSPDirective {
481 : public:
482 : explicit nsBlockAllMixedContentDirective(CSPDirective aDirective);
483 : ~nsBlockAllMixedContentDirective();
484 :
485 0 : bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
486 : bool aReportOnly, bool aUpgradeInsecure, bool aParserCreated) const
487 0 : { return false; }
488 :
489 : bool permits(nsIURI* aUri) const
490 : { return false; }
491 :
492 0 : bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
493 : bool aParserCreated) const
494 0 : { return false; }
495 :
496 : void toString(nsAString& outStr) const;
497 :
498 0 : void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs)
499 0 : { MOZ_ASSERT(false, "block-all-mixed-content does not hold any srcs"); }
500 : };
501 :
502 : /* =============== nsUpgradeInsecureDirective === */
503 :
504 : /*
505 : * Upgrading insecure requests includes the following actors:
506 : * (1) CSP:
507 : * The CSP implementation whitelists the http-request
508 : * in case the policy is executed in enforcement mode.
509 : * The CSP implementation however does not allow http
510 : * requests to succeed if executed in report-only mode.
511 : * In such a case the CSP implementation reports the
512 : * error back to the page.
513 : *
514 : * (2) MixedContent:
515 : * The evalution of MixedContent whitelists all http
516 : * requests with the promise that the http requests
517 : * gets upgraded to https before any data is fetched
518 : * from the network.
519 : *
520 : * (3) CORS:
521 : * Does not consider the http request to be of a
522 : * different origin in case the scheme is the only
523 : * difference in otherwise matching URIs.
524 : *
525 : * (4) nsHttpChannel:
526 : * Before connecting, the channel gets redirected
527 : * to use https.
528 : *
529 : * (5) WebSocketChannel:
530 : * Similar to the httpChannel, the websocketchannel
531 : * gets upgraded from ws to wss.
532 : */
533 : class nsUpgradeInsecureDirective : public nsCSPDirective {
534 : public:
535 : explicit nsUpgradeInsecureDirective(CSPDirective aDirective);
536 : ~nsUpgradeInsecureDirective();
537 :
538 0 : bool permits(nsIURI* aUri, const nsAString& aNonce, bool aWasRedirected,
539 : bool aReportOnly, bool aUpgradeInsecure, bool aParserCreated) const
540 0 : { return false; }
541 :
542 : bool permits(nsIURI* aUri) const
543 : { return false; }
544 :
545 0 : bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
546 : bool aParserCreated) const
547 0 : { return false; }
548 :
549 : void toString(nsAString& outStr) const;
550 :
551 0 : void addSrcs(const nsTArray<nsCSPBaseSrc*>& aSrcs)
552 0 : { MOZ_ASSERT(false, "upgrade-insecure-requests does not hold any srcs"); }
553 : };
554 :
555 : /* ===== nsRequireSRIForDirective ========================= */
556 :
557 : class nsRequireSRIForDirective : public nsCSPDirective {
558 : public:
559 : explicit nsRequireSRIForDirective(CSPDirective aDirective);
560 : ~nsRequireSRIForDirective();
561 :
562 : void toString(nsAString& outStr) const;
563 :
564 0 : void addType(nsContentPolicyType aType)
565 0 : { mTypes.AppendElement(aType); }
566 : bool hasType(nsContentPolicyType aType) const;
567 : bool restrictsContentType(nsContentPolicyType aType) const;
568 : bool allows(enum CSPKeyword aKeyword, const nsAString& aHashOrNonce,
569 : bool aParserCreated) const;
570 :
571 : private:
572 : nsTArray<nsContentPolicyType> mTypes;
573 : };
574 :
575 : /* =============== nsCSPPolicy ================== */
576 :
577 : class nsCSPPolicy {
578 : public:
579 : nsCSPPolicy();
580 : virtual ~nsCSPPolicy();
581 :
582 : bool permits(CSPDirective aDirective,
583 : nsIURI* aUri,
584 : const nsAString& aNonce,
585 : bool aWasRedirected,
586 : bool aSpecific,
587 : bool aParserCreated,
588 : nsAString& outViolatedDirective) const;
589 : bool permits(CSPDirective aDir,
590 : nsIURI* aUri,
591 : bool aSpecific) const;
592 : bool allows(nsContentPolicyType aContentType,
593 : enum CSPKeyword aKeyword,
594 : const nsAString& aHashOrNonce,
595 : bool aParserCreated) const;
596 : bool allows(nsContentPolicyType aContentType,
597 : enum CSPKeyword aKeyword) const;
598 : void toString(nsAString& outStr) const;
599 : void toDomCSPStruct(mozilla::dom::CSP& outCSP) const;
600 :
601 0 : inline void addDirective(nsCSPDirective* aDir)
602 0 : { mDirectives.AppendElement(aDir); }
603 :
604 0 : inline void addUpgradeInsecDir(nsUpgradeInsecureDirective* aDir)
605 : {
606 0 : mUpgradeInsecDir = aDir;
607 0 : addDirective(aDir);
608 0 : }
609 :
610 : bool hasDirective(CSPDirective aDir) const;
611 :
612 0 : inline void setReportOnlyFlag(bool aFlag)
613 0 : { mReportOnly = aFlag; }
614 :
615 0 : inline bool getReportOnlyFlag() const
616 0 : { return mReportOnly; }
617 :
618 0 : inline void setReferrerPolicy(const nsAString* aValue)
619 : {
620 0 : mReferrerPolicy = *aValue;
621 0 : ToLowerCase(mReferrerPolicy);
622 0 : }
623 :
624 0 : inline void getReferrerPolicy(nsAString& outPolicy) const
625 0 : { outPolicy.Assign(mReferrerPolicy); }
626 :
627 : void getReportURIs(nsTArray<nsString> &outReportURIs) const;
628 :
629 : void getDirectiveStringForContentType(nsContentPolicyType aContentType,
630 : nsAString& outDirective) const;
631 :
632 : void getDirectiveAsString(CSPDirective aDir, nsAString& outDirective) const;
633 :
634 : uint32_t getSandboxFlags() const;
635 :
636 : bool requireSRIForType(nsContentPolicyType aContentType);
637 :
638 0 : inline uint32_t getNumDirectives() const
639 0 : { return mDirectives.Length(); }
640 :
641 : bool visitDirectiveSrcs(CSPDirective aDir, nsCSPSrcVisitor* aVisitor) const;
642 :
643 : private:
644 : nsUpgradeInsecureDirective* mUpgradeInsecDir;
645 : nsTArray<nsCSPDirective*> mDirectives;
646 : bool mReportOnly;
647 : nsString mReferrerPolicy;
648 : };
649 :
650 : #endif /* nsCSPUtils_h___ */
|