Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(68)

Side by Side Diff: chrome/common/extensions/csp_validator.cc

Issue 8773028: Allow extenions to override the default content_security_policy, but require (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 9 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
(Empty)
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/common/extensions/csp_validator.h"
6
7 #include "base/string_split.h"
8 #include "base/string_tokenizer.h"
9 #include "base/string_util.h"
10
11 namespace extensions {
12
13 namespace csp_validator {
14
15 namespace {
16
17 const char kDefaultSrc[] = "default-src";
18 const char kScriptSrc[] = "script-src";
19 const char kObjectSrc[] = "object-src";
20
21 struct DirectiveStatus {
22 explicit DirectiveStatus(const char* name)
23 : directive_name(name)
24 , seen_in_policy(false)
25 , is_secure(false) {
26 }
27
28 const char* directive_name;
29 bool seen_in_policy;
30 bool is_secure;
31 };
32
33 bool HasOnlySecureTokens(StringTokenizer& tokenizer) {
34 while (tokenizer.GetNext()) {
35 std::string source = tokenizer.token();
36 StringToLowerASCII(&source);
37
38 if (EndsWith(source, "*", true))
39 return false;
40
41 // We might need to relax this whitelist over time.
42 if (source == "'self'" ||
43 source == "'none'" ||
44 StartsWithASCII(source, "https://", true) ||
45 StartsWithASCII(source, "chrome://", true) ||
46 StartsWithASCII(source, "chrome-extension://", true)) {
47 continue;
48 }
49
50 return false;
51 }
52
53 return true; // Empty values default to 'none', which is secure.
54 }
55
56 // Returns true if |directive_name| matches |status.directive_name|.
57 bool UpdateStatus(const std::string& directive_name,
58 StringTokenizer& tokenizer,
59 DirectiveStatus* status) {
60 if (status->seen_in_policy)
61 return false;
62 if (directive_name != status->directive_name)
63 return false;
64 status->seen_in_policy = true;
65 status->is_secure = HasOnlySecureTokens(tokenizer);
66 return true;
67 }
68
69 } // namespace
70
71 bool ContentSecurityPolicyIsLegal(const std::string& policy) {
72 // We block these characters to prevent HTTP header injection when
73 // representing the content security policy as an HTTP header.
74 const char kBadChars[] = {'\r', '\n', '\0'};
75
76 return policy.find_first_of(kBadChars, 0, arraysize(kBadChars)) ==
77 std::string::npos;
78 }
79
80 bool ContentSecurityPolicyIsSecure(const std::string& policy) {
81 // See http://www.w3.org/TR/CSP/#parse-a-csp-policy for parsing algorithm.
82 std::vector<std::string> directives;
83 base::SplitString(policy, ';', &directives);
84
85 DirectiveStatus default_src_status(kDefaultSrc);
86 DirectiveStatus script_src_status(kScriptSrc);
87 DirectiveStatus object_src_status(kObjectSrc);
88
89 for (size_t i = 0; i < directives.size(); ++i) {
90 std::string& input = directives[i];
91 StringTokenizer tokenizer(input, " \t\r\n");
92 if (!tokenizer.GetNext())
93 continue;
94
95 std::string directive_name = tokenizer.token();
96 StringToLowerASCII(&directive_name);
97
98 if (UpdateStatus(directive_name, tokenizer, &default_src_status))
99 continue;
100 if (UpdateStatus(directive_name, tokenizer, &script_src_status))
101 continue;
102 if (UpdateStatus(directive_name, tokenizer, &object_src_status))
103 continue;
104 }
105
106 if (script_src_status.seen_in_policy && !script_src_status.is_secure)
107 return false;
108
109 if (object_src_status.seen_in_policy && !object_src_status.is_secure)
110 return false;
111
112 if (default_src_status.seen_in_policy && !default_src_status.is_secure) {
113 return script_src_status.seen_in_policy &&
114 object_src_status.seen_in_policy;
115 }
116
117 return default_src_status.seen_in_policy ||
118 (script_src_status.seen_in_policy && object_src_status.seen_in_policy);
119 }
120
121 } // csp_validator
122
123 } // extensions
OLDNEW
« no previous file with comments | « chrome/common/extensions/csp_validator.h ('k') | chrome/common/extensions/csp_validator_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698