Bug 1892041 - Part 1: Update test262 features. r=spidermonkey-reviewers,dminor
[gecko.git] / dom / security / nsCSPParser.h
blob28c24440d026f8f9ea8f62dbd8f101e169edd71d
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 nsCSPParser_h___
8 #define nsCSPParser_h___
10 #include "nsCSPUtils.h"
11 #include "nsCSPContext.h"
12 #include "nsIURI.h"
13 #include "PolicyTokenizer.h"
15 bool isNumberToken(char16_t aSymbol);
16 bool isValidHexDig(char16_t aHexDig);
18 // clang-format off
19 const char16_t COLON = ':';
20 const char16_t SEMICOLON = ';';
21 const char16_t SLASH = '/';
22 const char16_t PLUS = '+';
23 const char16_t DASH = '-';
24 const char16_t DOT = '.';
25 const char16_t UNDERLINE = '_';
26 const char16_t TILDE = '~';
27 const char16_t WILDCARD = '*';
28 const char16_t SINGLEQUOTE = '\'';
29 const char16_t NUMBER_SIGN = '#';
30 const char16_t QUESTIONMARK = '?';
31 const char16_t PERCENT_SIGN = '%';
32 const char16_t EXCLAMATION = '!';
33 const char16_t DOLLAR = '$';
34 const char16_t AMPERSAND = '&';
35 const char16_t OPENBRACE = '(';
36 const char16_t CLOSINGBRACE = ')';
37 const char16_t EQUALS = '=';
38 const char16_t ATSYMBOL = '@';
39 // clang-format on
41 class nsCSPParser {
42 public:
43 /**
44 * The CSP parser only has one publicly accessible function, which is
45 * parseContentSecurityPolicy. Internally the input string is separated into
46 * string tokens and policy() is called, which starts parsing the policy. The
47 * parser calls one function after the other according the the source-list
48 * from http://www.w3.org/TR/CSP11/#source-list. E.g., the parser can only
49 * call port() after the parser has already processed any possible host in
50 * host(), similar to a finite state machine.
52 static nsCSPPolicy* parseContentSecurityPolicy(const nsAString& aPolicyString,
53 nsIURI* aSelfURI,
54 bool aReportOnly,
55 nsCSPContext* aCSPContext,
56 bool aDeliveredViaMetaTag,
57 bool aSuppressLogMessages);
59 private:
60 nsCSPParser(policyTokens& aTokens, nsIURI* aSelfURI,
61 nsCSPContext* aCSPContext, bool aDeliveredViaMetaTag,
62 bool aSuppressLogMessages);
64 ~nsCSPParser();
66 // Parsing the CSP using the source-list from
67 // http://www.w3.org/TR/CSP11/#source-list
68 nsCSPPolicy* policy();
69 void directive();
70 nsCSPDirective* directiveName();
71 void directiveValue(nsTArray<nsCSPBaseSrc*>& outSrcs);
72 void referrerDirectiveValue(nsCSPDirective* aDir);
73 void reportURIList(nsCSPDirective* aDir);
74 void sandboxFlagList(nsCSPDirective* aDir);
75 void sourceList(nsTArray<nsCSPBaseSrc*>& outSrcs);
76 nsCSPBaseSrc* sourceExpression();
77 nsCSPSchemeSrc* schemeSource();
78 nsCSPHostSrc* hostSource();
79 nsCSPBaseSrc* keywordSource();
80 nsCSPNonceSrc* nonceSource();
81 nsCSPHashSrc* hashSource();
82 nsCSPHostSrc* host();
83 bool hostChar();
84 bool schemeChar();
85 bool port();
86 bool path(nsCSPHostSrc* aCspHost);
88 bool subHost(); // helper function to parse subDomains
89 bool atValidUnreservedChar(); // helper function to parse unreserved
90 bool atValidSubDelimChar(); // helper function to parse sub-delims
91 bool atValidPctEncodedChar(); // helper function to parse pct-encoded
92 bool subPath(nsCSPHostSrc* aCspHost); // helper function to parse paths
94 inline bool atEnd() { return mCurChar >= mEndChar; }
96 inline bool accept(char16_t aSymbol) {
97 if (atEnd()) {
98 return false;
100 return (*mCurChar == aSymbol) && advance();
103 inline bool accept(bool (*aClassifier)(char16_t)) {
104 if (atEnd()) {
105 return false;
107 return (aClassifier(*mCurChar)) && advance();
110 inline bool peek(char16_t aSymbol) {
111 if (atEnd()) {
112 return false;
114 return *mCurChar == aSymbol;
117 inline bool peek(bool (*aClassifier)(char16_t)) {
118 if (atEnd()) {
119 return false;
121 return aClassifier(*mCurChar);
124 inline bool advance() {
125 if (atEnd()) {
126 return false;
128 mCurValue.Append(*mCurChar++);
129 return true;
132 inline void resetCurValue() { mCurValue.Truncate(); }
134 bool atEndOfPath();
135 bool atValidPathChar();
137 void resetCurChar(const nsAString& aToken);
139 void logWarningErrorToConsole(uint32_t aSeverityFlag, const char* aProperty,
140 const nsTArray<nsString>& aParams);
142 void MaybeWarnAboutIgnoredSources(const nsTArray<nsCSPBaseSrc*>& aSrcs);
143 void MaybeWarnAboutUnsafeInline(const nsCSPDirective& aDirective);
144 void MaybeWarnAboutUnsafeEval(const nsCSPDirective& aDirective);
147 * When parsing the policy, the parser internally uses the following helper
148 * variables/members which are used/reset during parsing. The following
149 * example explains how they are used.
150 * The tokenizer separats all input into arrays of arrays of strings, which
151 * are stored in mTokens, for example:
152 * mTokens = [ [ script-src, http://www.example.com, 'self' ], ... ]
154 * When parsing starts, mCurdir always holds the currently processed array of
155 * strings.
156 * In our example:
157 * mCurDir = [ script-src, http://www.example.com, 'self' ]
159 * During parsing, we process/consume one string at a time of that array.
160 * We set mCurToken to the string we are currently processing; in the first
161 * case that would be: mCurToken = script-src which allows to do simple string
162 * comparisons to see if mCurToken is a valid directive.
164 * Continuing parsing, the parser consumes the next string of that array,
165 * resetting:
166 * mCurToken = "http://www.example.com"
167 * ^ ^
168 * mCurChar mEndChar (points *after* the 'm')
169 * mCurValue = ""
171 * After calling advance() the first time, helpers would hold the following
172 * values:
173 * mCurToken = "http://www.example.com"
174 * ^ ^
175 * mCurChar mEndChar (points *after* the 'm')
176 * mCurValue = "h"
178 * We continue parsing till all strings of one directive are consumed, then we
179 * reset mCurDir to hold the next array of strings and start the process all
180 * over.
183 const char16_t* mCurChar;
184 const char16_t* mEndChar;
185 nsString mCurValue;
186 nsString mCurToken;
187 nsTArray<nsString> mCurDir;
189 // helpers to allow invalidation of srcs within script-src and style-src
190 // if either 'strict-dynamic' or at least a hash or nonce is present.
191 bool mHasHashOrNonce; // false, if no hash or nonce is defined
192 bool mHasAnyUnsafeEval; // false, if no (wasm-)unsafe-eval keyword is used.
193 bool mStrictDynamic; // false, if 'strict-dynamic' is not defined
194 nsCSPKeywordSrc* mUnsafeInlineKeywordSrc; // null, otherwise invlidate()
196 // cache variables for child-src, frame-src and worker-src handling;
197 // in CSP 3 child-src is deprecated. For backwards compatibility
198 // child-src needs to restrict:
199 // (*) frames, in case frame-src is not expicitly specified
200 // (*) workers, in case worker-src is not expicitly specified
201 // If neither worker-src, nor child-src is present, then script-src
202 // needs to govern workers.
203 nsCSPChildSrcDirective* mChildSrc;
204 nsCSPDirective* mFrameSrc;
205 nsCSPDirective* mWorkerSrc;
206 nsCSPScriptSrcDirective* mScriptSrc;
207 nsCSPStyleSrcDirective* mStyleSrc;
209 // cache variable to let nsCSPHostSrc know that it's within
210 // the frame-ancestors directive.
211 bool mParsingFrameAncestorsDir;
213 policyTokens mTokens;
214 nsIURI* mSelfURI;
215 nsCSPPolicy* mPolicy;
216 nsCSPContext* mCSPContext; // used for console logging
217 bool mDeliveredViaMetaTag;
218 bool mSuppressLogMessages;
221 #endif /* nsCSPParser_h___ */