30 #ifndef NET_INSTAWEB_REWRITER_PUBLIC_CSP_H_
31 #define NET_INSTAWEB_REWRITER_PUBLIC_CSP_H_
42 namespace net_instaweb {
47 kSelf, kSchemeSource, kHostSource,
48 kUnsafeInline, kUnsafeEval, kStrictDynamic, kUnsafeHashedAttributes,
49 kHashOrNonce, kUnknown
53 UrlData() : path_exact_match(
false) {}
55 UrlData(StringPiece in_scheme, StringPiece in_host,
56 StringPiece in_port, StringPiece in_path,
57 bool exact_match =
false)
59 host_part(in_host.as_string()),
60 port_part(in_port.as_string()),
61 path_exact_match(exact_match) {
62 StringPieceVector portions;
64 for (StringPiece p : portions) {
81 bool path_exact_match;
84 return StrCat(
"scheme:",
scheme_part,
" host:", host_part,
93 host_part == other.host_part &&
94 port_part == other.port_part &&
96 path_exact_match == other.path_exact_match;
101 explicit CspSourceExpression(Kind kind): kind_(kind) {}
102 CspSourceExpression(Kind kind,
const UrlData& url_data) : kind_(kind) {
103 *mutable_url_data() = url_data;
106 static CspSourceExpression Parse(StringPiece input);
108 bool Matches(
const GoogleUrl& origin_url,
const GoogleUrl& url)
const;
111 return StrCat(
"kind:", IntegerToString(kind_),
112 " url_data:{", url_data().DebugString(),
"}");
115 bool operator==(
const CspSourceExpression& other)
const {
116 return (kind_ == other.kind_) && (url_data() == other.url_data());
119 Kind kind()
const {
return kind_; }
121 const UrlData& url_data()
const {
122 if (url_data_.get() ==
nullptr) {
123 url_data_.reset(
new UrlData());
125 return *url_data_.get();
130 static CspSourceExpression ParseQuoted(StringPiece input);
133 static bool ParseBase64(StringPiece input);
138 bool TryParseScheme(StringPiece* input);
140 static bool HasDefaultPortForScheme(
const GoogleUrl& url);
142 UrlData* mutable_url_data() {
143 if (url_data_.get() ==
nullptr) {
144 url_data_.reset(
new UrlData());
146 return url_data_.get();
150 mutable std::unique_ptr<UrlData> url_data_;
156 : saw_unsafe_inline_(
false), saw_unsafe_eval_(
false),
157 saw_strict_dynamic_(
false), saw_unsafe_hashed_attributes_(
false),
158 saw_hash_or_nonce_(
false) {}
160 static std::unique_ptr<CspSourceList> Parse(StringPiece input);
161 const std::vector<CspSourceExpression>& expressions()
const {
165 bool saw_unsafe_inline()
const {
return saw_unsafe_inline_; }
166 bool saw_unsafe_eval()
const {
return saw_unsafe_eval_; }
167 bool saw_strict_dynamic()
const {
return saw_strict_dynamic_; }
168 bool saw_unsafe_hashed_attributes()
const {
169 return saw_unsafe_hashed_attributes_;
172 bool saw_hash_or_nonce()
const {
return saw_hash_or_nonce_; }
177 std::vector<CspSourceExpression> expressions_;
178 bool saw_unsafe_inline_;
179 bool saw_unsafe_eval_;
180 bool saw_strict_dynamic_;
181 bool saw_unsafe_hashed_attributes_;
182 bool saw_hash_or_nonce_;
192 static std::unique_ptr<CspPolicy>
Parse(StringPiece input);
196 return policies_[
static_cast<int>(directive)].
get();
199 bool PermitsEval()
const;
200 bool PermitsInlineScript()
const;
201 bool PermitsInlineScriptAttribute()
const;
202 bool PermitsInlineStyle()
const;
203 bool PermitsInlineStyleAttribute()
const;
210 bool IsBasePermitted(
const GoogleUrl& previous_origin,
215 std::vector<std::unique_ptr<CspSourceList>> policies_;
223 bool PermitsEval()
const {
224 return AllPermit(&CspPolicy::PermitsEval);
227 bool PermitsInlineScript()
const {
228 return AllPermit(&CspPolicy::PermitsInlineScript);
231 bool PermitsInlineScriptAttribute()
const {
232 return AllPermit(&CspPolicy::PermitsInlineScriptAttribute);
235 bool PermitsInlineStyle()
const {
236 return AllPermit(&CspPolicy::PermitsInlineStyle);
239 bool PermitsInlineStyleAttribute()
const {
240 return AllPermit(&CspPolicy::PermitsInlineStyleAttribute);
246 for (
const auto& policy : policies_) {
247 if (!policy->CanLoadUrl(role, origin_url, url)) {
254 bool IsBasePermitted(
const GoogleUrl& previous_origin,
256 for (
const auto& policy : policies_) {
257 if (!policy->IsBasePermitted(previous_origin, base_candidate)) {
265 for (
const auto& policy : policies_) {
266 if (policy->SourceListFor(directive) !=
nullptr) {
273 bool HasDirectiveOrDefaultSrc(
CspDirective directive)
const {
274 for (
const auto& policy : policies_) {
275 if (policy->SourceListFor(directive) !=
nullptr ||
276 policy->SourceListFor(CspDirective::kDefaultSrc) !=
nullptr) {
283 void AddPolicy(std::unique_ptr<CspPolicy> policy);
284 void Clear() { policies_.clear(); }
285 size_t policies_size()
const {
return policies_.size(); }
286 bool empty()
const {
return policies_.empty(); }
289 typedef bool (CspPolicy::*SimplePredicateFn)()
const;
291 bool AllPermit(SimplePredicateFn predicate)
const {
295 for (
const auto& policy : policies_) {
296 if (!(policy.get()->*predicate)()) {
303 std::vector<std::unique_ptr<CspPolicy>> policies_;
class GoogleUrl
Definition: google_url.h:58
const char * BoolToString(bool b)
Converts a boolean to string.
Definition: string_util.h:741
GoogleString scheme_part
doesn't include :
Definition: csp.h:76
bool operator==(const UrlData &other) const
For convenience of unit testing.
Definition: csp.h:91
CspDirective
Definition: csp_directive.h:37
std::string GoogleString
PAGESPEED_KERNEL_BASE_STRING_H_.
Definition: string.h:24
bool CanLoadUrl(CspDirective role, const GoogleUrl &origin_url, const GoogleUrl &url)
Definition: csp.h:243
const CspSourceList * SourceListFor(CspDirective directive) const
May return null.
Definition: csp.h:195
static std::unique_ptr< CspPolicy > Parse(StringPiece input)
May return null.
UrlData(StringPiece in_scheme, StringPiece in_host, StringPiece in_port, StringPiece in_path, bool exact_match=false)
Constructor for tests, assumes already normalized.
Definition: csp.h:55
std::vector< GoogleString > path_part
separated by /
Definition: csp.h:80
bool CanLoadUrl(CspDirective role, const GoogleUrl &origin_url, const GoogleUrl &url) const
void SplitStringPieceToVector(StringPiece sp, StringPiece separators, StringPieceVector *components, bool omit_empty_strings)