| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/common/extensions/csp_validator.h" | 5 #include "chrome/common/extensions/csp_validator.h" |
| 6 | 6 |
| 7 #include "base/string_split.h" | 7 #include "base/string_split.h" |
| 8 #include "base/string_tokenizer.h" | |
| 9 #include "base/string_util.h" | 8 #include "base/string_util.h" |
| 9 #include "base/strings/string_tokenizer.h" |
| 10 | 10 |
| 11 namespace extensions { | 11 namespace extensions { |
| 12 | 12 |
| 13 namespace csp_validator { | 13 namespace csp_validator { |
| 14 | 14 |
| 15 namespace { | 15 namespace { |
| 16 | 16 |
| 17 const char kDefaultSrc[] = "default-src"; | 17 const char kDefaultSrc[] = "default-src"; |
| 18 const char kScriptSrc[] = "script-src"; | 18 const char kScriptSrc[] = "script-src"; |
| 19 const char kObjectSrc[] = "object-src"; | 19 const char kObjectSrc[] = "object-src"; |
| 20 | 20 |
| 21 const char kSandboxDirectiveName[] = "sandbox"; | 21 const char kSandboxDirectiveName[] = "sandbox"; |
| 22 const char kAllowSameOriginToken[] = "allow-same-origin"; | 22 const char kAllowSameOriginToken[] = "allow-same-origin"; |
| 23 const char kAllowTopNavigation[] = "allow-top-navigation"; | 23 const char kAllowTopNavigation[] = "allow-top-navigation"; |
| 24 const char kAllowPopups[] = "allow-popups"; | 24 const char kAllowPopups[] = "allow-popups"; |
| 25 | 25 |
| 26 struct DirectiveStatus { | 26 struct DirectiveStatus { |
| 27 explicit DirectiveStatus(const char* name) | 27 explicit DirectiveStatus(const char* name) |
| 28 : directive_name(name) | 28 : directive_name(name) |
| 29 , seen_in_policy(false) | 29 , seen_in_policy(false) |
| 30 , is_secure(false) { | 30 , is_secure(false) { |
| 31 } | 31 } |
| 32 | 32 |
| 33 const char* directive_name; | 33 const char* directive_name; |
| 34 bool seen_in_policy; | 34 bool seen_in_policy; |
| 35 bool is_secure; | 35 bool is_secure; |
| 36 }; | 36 }; |
| 37 | 37 |
| 38 bool HasOnlySecureTokens(StringTokenizer& tokenizer, Manifest::Type type) { | 38 bool HasOnlySecureTokens(base::StringTokenizer& tokenizer, |
| 39 Manifest::Type type) { |
| 39 while (tokenizer.GetNext()) { | 40 while (tokenizer.GetNext()) { |
| 40 std::string source = tokenizer.token(); | 41 std::string source = tokenizer.token(); |
| 41 StringToLowerASCII(&source); | 42 StringToLowerASCII(&source); |
| 42 | 43 |
| 43 // Don't alow whitelisting of all hosts. This boils down to: | 44 // Don't alow whitelisting of all hosts. This boils down to: |
| 44 // 1. Maximum of 2 '*' characters. | 45 // 1. Maximum of 2 '*' characters. |
| 45 // 2. Each '*' is either followed by a '.' or preceded by a ':' | 46 // 2. Each '*' is either followed by a '.' or preceded by a ':' |
| 46 int wildcards = 0; | 47 int wildcards = 0; |
| 47 size_t length = source.length(); | 48 size_t length = source.length(); |
| 48 for (size_t i = 0; i < length; ++i) { | 49 for (size_t i = 0; i < length; ++i) { |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 } | 83 } |
| 83 | 84 |
| 84 return false; | 85 return false; |
| 85 } | 86 } |
| 86 | 87 |
| 87 return true; // Empty values default to 'none', which is secure. | 88 return true; // Empty values default to 'none', which is secure. |
| 88 } | 89 } |
| 89 | 90 |
| 90 // Returns true if |directive_name| matches |status.directive_name|. | 91 // Returns true if |directive_name| matches |status.directive_name|. |
| 91 bool UpdateStatus(const std::string& directive_name, | 92 bool UpdateStatus(const std::string& directive_name, |
| 92 StringTokenizer& tokenizer, | 93 base::StringTokenizer& tokenizer, |
| 93 DirectiveStatus* status, | 94 DirectiveStatus* status, |
| 94 Manifest::Type type) { | 95 Manifest::Type type) { |
| 95 if (status->seen_in_policy) | 96 if (status->seen_in_policy) |
| 96 return false; | 97 return false; |
| 97 if (directive_name != status->directive_name) | 98 if (directive_name != status->directive_name) |
| 98 return false; | 99 return false; |
| 99 status->seen_in_policy = true; | 100 status->seen_in_policy = true; |
| 100 status->is_secure = HasOnlySecureTokens(tokenizer, type); | 101 status->is_secure = HasOnlySecureTokens(tokenizer, type); |
| 101 return true; | 102 return true; |
| 102 } | 103 } |
| (...skipping 14 matching lines...) Expand all Loading... |
| 117 // See http://www.w3.org/TR/CSP/#parse-a-csp-policy for parsing algorithm. | 118 // See http://www.w3.org/TR/CSP/#parse-a-csp-policy for parsing algorithm. |
| 118 std::vector<std::string> directives; | 119 std::vector<std::string> directives; |
| 119 base::SplitString(policy, ';', &directives); | 120 base::SplitString(policy, ';', &directives); |
| 120 | 121 |
| 121 DirectiveStatus default_src_status(kDefaultSrc); | 122 DirectiveStatus default_src_status(kDefaultSrc); |
| 122 DirectiveStatus script_src_status(kScriptSrc); | 123 DirectiveStatus script_src_status(kScriptSrc); |
| 123 DirectiveStatus object_src_status(kObjectSrc); | 124 DirectiveStatus object_src_status(kObjectSrc); |
| 124 | 125 |
| 125 for (size_t i = 0; i < directives.size(); ++i) { | 126 for (size_t i = 0; i < directives.size(); ++i) { |
| 126 std::string& input = directives[i]; | 127 std::string& input = directives[i]; |
| 127 StringTokenizer tokenizer(input, " \t\r\n"); | 128 base::StringTokenizer tokenizer(input, " \t\r\n"); |
| 128 if (!tokenizer.GetNext()) | 129 if (!tokenizer.GetNext()) |
| 129 continue; | 130 continue; |
| 130 | 131 |
| 131 std::string directive_name = tokenizer.token(); | 132 std::string directive_name = tokenizer.token(); |
| 132 StringToLowerASCII(&directive_name); | 133 StringToLowerASCII(&directive_name); |
| 133 | 134 |
| 134 if (UpdateStatus(directive_name, tokenizer, &default_src_status, type)) | 135 if (UpdateStatus(directive_name, tokenizer, &default_src_status, type)) |
| 135 continue; | 136 continue; |
| 136 if (UpdateStatus(directive_name, tokenizer, &script_src_status, type)) | 137 if (UpdateStatus(directive_name, tokenizer, &script_src_status, type)) |
| 137 continue; | 138 continue; |
| (...skipping 19 matching lines...) Expand all Loading... |
| 157 bool ContentSecurityPolicyIsSandboxed( | 158 bool ContentSecurityPolicyIsSandboxed( |
| 158 const std::string& policy, Manifest::Type type) { | 159 const std::string& policy, Manifest::Type type) { |
| 159 // See http://www.w3.org/TR/CSP/#parse-a-csp-policy for parsing algorithm. | 160 // See http://www.w3.org/TR/CSP/#parse-a-csp-policy for parsing algorithm. |
| 160 std::vector<std::string> directives; | 161 std::vector<std::string> directives; |
| 161 base::SplitString(policy, ';', &directives); | 162 base::SplitString(policy, ';', &directives); |
| 162 | 163 |
| 163 bool seen_sandbox = false; | 164 bool seen_sandbox = false; |
| 164 | 165 |
| 165 for (size_t i = 0; i < directives.size(); ++i) { | 166 for (size_t i = 0; i < directives.size(); ++i) { |
| 166 std::string& input = directives[i]; | 167 std::string& input = directives[i]; |
| 167 StringTokenizer tokenizer(input, " \t\r\n"); | 168 base::StringTokenizer tokenizer(input, " \t\r\n"); |
| 168 if (!tokenizer.GetNext()) | 169 if (!tokenizer.GetNext()) |
| 169 continue; | 170 continue; |
| 170 | 171 |
| 171 std::string directive_name = tokenizer.token(); | 172 std::string directive_name = tokenizer.token(); |
| 172 StringToLowerASCII(&directive_name); | 173 StringToLowerASCII(&directive_name); |
| 173 | 174 |
| 174 if (directive_name != kSandboxDirectiveName) | 175 if (directive_name != kSandboxDirectiveName) |
| 175 continue; | 176 continue; |
| 176 | 177 |
| 177 seen_sandbox = true; | 178 seen_sandbox = true; |
| (...skipping 13 matching lines...) Expand all Loading... |
| 191 } | 192 } |
| 192 } | 193 } |
| 193 } | 194 } |
| 194 | 195 |
| 195 return seen_sandbox; | 196 return seen_sandbox; |
| 196 } | 197 } |
| 197 | 198 |
| 198 } // csp_validator | 199 } // csp_validator |
| 199 | 200 |
| 200 } // extensions | 201 } // extensions |
| OLD | NEW |