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

Side by Side Diff: chrome/browser/search/local_ntp_source.cc

Issue 2805133004: Local NTP: Deploy strict-dynamic CSP (Closed)
Patch Set: Created 3 years, 8 months 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
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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/browser/search/local_ntp_source.h" 5 #include "chrome/browser/search/local_ntp_source.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <memory> 9 #include <memory>
10 10
11 #include "base/base64.h"
11 #include "base/command_line.h" 12 #include "base/command_line.h"
12 #include "base/json/json_string_value_serializer.h" 13 #include "base/json/json_string_value_serializer.h"
13 #include "base/logging.h" 14 #include "base/logging.h"
14 #include "base/memory/ptr_util.h" 15 #include "base/memory/ptr_util.h"
15 #include "base/memory/ref_counted_memory.h" 16 #include "base/memory/ref_counted_memory.h"
16 #include "base/metrics/field_trial.h" 17 #include "base/metrics/field_trial.h"
17 #include "base/strings/string_util.h" 18 #include "base/strings/string_util.h"
18 #include "base/strings/stringprintf.h" 19 #include "base/strings/stringprintf.h"
19 #include "base/values.h" 20 #include "base/values.h"
20 #include "build/build_config.h" 21 #include "build/build_config.h"
21 #include "chrome/browser/search/instant_io_context.h" 22 #include "chrome/browser/search/instant_io_context.h"
22 #include "chrome/browser/search/local_files_ntp_source.h" 23 #include "chrome/browser/search/local_files_ntp_source.h"
23 #include "chrome/browser/search_engines/template_url_service_factory.h" 24 #include "chrome/browser/search_engines/template_url_service_factory.h"
24 #include "chrome/browser/themes/theme_properties.h" 25 #include "chrome/browser/themes/theme_properties.h"
25 #include "chrome/browser/themes/theme_service.h" 26 #include "chrome/browser/themes/theme_service.h"
26 #include "chrome/browser/themes/theme_service_factory.h" 27 #include "chrome/browser/themes/theme_service_factory.h"
27 #include "chrome/common/chrome_switches.h" 28 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/url_constants.h" 29 #include "chrome/common/url_constants.h"
29 #include "chrome/grit/browser_resources.h" 30 #include "chrome/grit/browser_resources.h"
30 #include "chrome/grit/generated_resources.h" 31 #include "chrome/grit/generated_resources.h"
31 #include "chrome/grit/theme_resources.h" 32 #include "chrome/grit/theme_resources.h"
32 #include "components/search_engines/template_url_service.h" 33 #include "components/search_engines/template_url_service.h"
33 #include "components/strings/grit/components_strings.h" 34 #include "components/strings/grit/components_strings.h"
35 #include "crypto/secure_hash.h"
36 #include "net/base/hash_value.h"
34 #include "net/url_request/url_request.h" 37 #include "net/url_request/url_request.h"
35 #include "third_party/skia/include/core/SkColor.h" 38 #include "third_party/skia/include/core/SkColor.h"
36 #include "ui/base/l10n/l10n_util.h" 39 #include "ui/base/l10n/l10n_util.h"
37 #include "ui/base/resource/resource_bundle.h" 40 #include "ui/base/resource/resource_bundle.h"
38 #include "ui/base/webui/web_ui_util.h" 41 #include "ui/base/webui/web_ui_util.h"
39 #include "ui/resources/grit/ui_resources.h" 42 #include "ui/resources/grit/ui_resources.h"
40 #include "url/gurl.h" 43 #include "url/gurl.h"
41 44
42 namespace { 45 namespace {
43 46
44 // Signifies a locally constructed resource, i.e. not from grit/. 47 // Signifies a locally constructed resource, i.e. not from grit/.
45 const int kLocalResource = -1; 48 const int kLocalResource = -1;
46 49
47 const char kConfigDataFilename[] = "config.js"; 50 const char kConfigDataFilename[] = "config.js";
48 const char kThemeCSSFilename[] = "theme.css"; 51 const char kThemeCSSFilename[] = "theme.css";
52 const char kMainHtmlFilename[] = "local-ntp.html";
49 53
50 const struct Resource{ 54 const struct Resource{
51 const char* filename; 55 const char* filename;
52 int identifier; 56 int identifier;
53 const char* mime_type; 57 const char* mime_type;
54 } kResources[] = { 58 } kResources[] = {
55 {"local-ntp.html", IDR_LOCAL_NTP_HTML, "text/html"}, 59 {kMainHtmlFilename, kLocalResource, "text/html"},
56 {"local-ntp.js", IDR_LOCAL_NTP_JS, "application/javascript"}, 60 {"local-ntp.js", IDR_LOCAL_NTP_JS, "application/javascript"},
57 {kConfigDataFilename, kLocalResource, "application/javascript"}, 61 {kConfigDataFilename, kLocalResource, "application/javascript"},
58 {kThemeCSSFilename, kLocalResource, "text/css"}, 62 {kThemeCSSFilename, kLocalResource, "text/css"},
59 {"local-ntp.css", IDR_LOCAL_NTP_CSS, "text/css"}, 63 {"local-ntp.css", IDR_LOCAL_NTP_CSS, "text/css"},
60 {"images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png"}, 64 {"images/close_3_mask.png", IDR_CLOSE_3_MASK, "image/png"},
61 {"images/close_4_button.png", IDR_CLOSE_4_BUTTON, "image/png"}, 65 {"images/close_4_button.png", IDR_CLOSE_4_BUTTON, "image/png"},
62 {"images/ntp_default_favicon.png", IDR_NTP_DEFAULT_FAVICON, "image/png"}, 66 {"images/ntp_default_favicon.png", IDR_NTP_DEFAULT_FAVICON, "image/png"},
63 }; 67 };
64 68
65 // Strips any query parameters from the specified path. 69 // Strips any query parameters from the specified path.
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after
127 JSONStringValueSerializer serializer(&js_text); 131 JSONStringValueSerializer serializer(&js_text);
128 serializer.Serialize(config_data); 132 serializer.Serialize(config_data);
129 133
130 std::string config_data_js; 134 std::string config_data_js;
131 config_data_js.append("var configData = "); 135 config_data_js.append("var configData = ");
132 config_data_js.append(js_text); 136 config_data_js.append(js_text);
133 config_data_js.append(";"); 137 config_data_js.append(";");
134 return config_data_js; 138 return config_data_js;
135 } 139 }
136 140
141 std::string GetIntegritySha256Value(const std::string& data) {
142 // Compute the sha256 hash.
143 net::SHA256HashValue hash_value;
144 std::unique_ptr<crypto::SecureHash> hash(
145 crypto::SecureHash::Create(crypto::SecureHash::SHA256));
146 hash->Update(data.data(), data.size());
147 hash->Finish(&hash_value, sizeof(hash_value));
148
149 // Base64-encode it.
150 base::StringPiece hash_value_str(reinterpret_cast<char*>(hash_value.data),
151 sizeof(hash_value));
152 std::string result;
153 base::Base64Encode(hash_value_str, &result);
154 return result;
155 }
156
137 std::string GetThemeCSS(Profile* profile) { 157 std::string GetThemeCSS(Profile* profile) {
138 SkColor background_color = 158 SkColor background_color =
139 ThemeService::GetThemeProviderForProfile(profile) 159 ThemeService::GetThemeProviderForProfile(profile)
140 .GetColor(ThemeProperties::COLOR_NTP_BACKGROUND); 160 .GetColor(ThemeProperties::COLOR_NTP_BACKGROUND);
141 161
142 return base::StringPrintf("body { background-color: #%02X%02X%02X; }", 162 return base::StringPrintf("body { background-color: #%02X%02X%02X; }",
143 SkColorGetR(background_color), 163 SkColorGetR(background_color),
144 SkColorGetG(background_color), 164 SkColorGetG(background_color),
145 SkColorGetB(background_color)); 165 SkColorGetB(background_color));
146 } 166 }
(...skipping 27 matching lines...) Expand all
174 std::string theme_css = GetThemeCSS(profile_); 194 std::string theme_css = GetThemeCSS(profile_);
175 callback.Run(base::RefCountedString::TakeString(&theme_css)); 195 callback.Run(base::RefCountedString::TakeString(&theme_css));
176 return; 196 return;
177 } 197 }
178 198
179 #if !defined(GOOGLE_CHROME_BUILD) 199 #if !defined(GOOGLE_CHROME_BUILD)
180 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess(); 200 base::CommandLine* command_line = base::CommandLine::ForCurrentProcess();
181 if (command_line->HasSwitch(switches::kLocalNtpReload)) { 201 if (command_line->HasSwitch(switches::kLocalNtpReload)) {
182 if (stripped_path == "local-ntp.html" || stripped_path == "local-ntp.js" || 202 if (stripped_path == "local-ntp.html" || stripped_path == "local-ntp.js" ||
183 stripped_path == "local-ntp.css") { 203 stripped_path == "local-ntp.css") {
204 // TODO(treib): This is now broken for the html file - need to insert the
205 // config hash.
Marc Treib 2017/04/07 16:46:15 ...which would be somewhat annoying in terms of pl
sfiera 2017/04/10 08:53:21 What's it actually for? Live-editing the files in
Marc Treib 2017/04/10 10:11:18 Yup, it's for live-editing. Good idea, I'll turn o
184 base::ReplaceChars(stripped_path, "-", "_", &stripped_path); 206 base::ReplaceChars(stripped_path, "-", "_", &stripped_path);
185 local_ntp::SendLocalFileResource(stripped_path, callback); 207 local_ntp::SendLocalFileResource(stripped_path, callback);
186 return; 208 return;
187 } 209 }
188 } 210 }
189 #endif // !defined(GOOGLE_CHROME_BUILD) 211 #endif // !defined(GOOGLE_CHROME_BUILD)
190 212
213 if (stripped_path == kMainHtmlFilename) {
214 std::string html = ResourceBundle::GetSharedInstance()
215 .GetRawDataResource(IDR_LOCAL_NTP_HTML)
216 .as_string();
217 std::string config_sha256 =
218 "sha256-" + GetIntegritySha256Value(GetConfigData(profile_));
219 base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{CONFIG_INTEGRITY}}",
220 config_sha256);
221 callback.Run(base::RefCountedString::TakeString(&html));
222 return;
223 }
224
191 float scale = 1.0f; 225 float scale = 1.0f;
192 std::string filename; 226 std::string filename;
193 webui::ParsePathAndScale( 227 webui::ParsePathAndScale(
194 GURL(GetLocalNtpPath() + stripped_path), &filename, &scale); 228 GURL(GetLocalNtpPath() + stripped_path), &filename, &scale);
195 ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactor(scale); 229 ui::ScaleFactor scale_factor = ui::GetSupportedScaleFactor(scale);
196 230
197 for (size_t i = 0; i < arraysize(kResources); ++i) { 231 for (size_t i = 0; i < arraysize(kResources); ++i) {
198 if (filename == kResources[i].filename) { 232 if (filename == kResources[i].filename) {
199 scoped_refptr<base::RefCountedMemory> response( 233 scoped_refptr<base::RefCountedMemory> response(
200 ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale( 234 ResourceBundle::GetSharedInstance().LoadDataResourceBytesForScale(
201 kResources[i].identifier, scale_factor)); 235 kResources[i].identifier, scale_factor));
202 callback.Run(response.get()); 236 callback.Run(response.get());
203 return; 237 return;
204 } 238 }
205 } 239 }
206 callback.Run(NULL); 240 callback.Run(nullptr);
207 } 241 }
208 242
209 std::string LocalNtpSource::GetMimeType( 243 std::string LocalNtpSource::GetMimeType(
210 const std::string& path) const { 244 const std::string& path) const {
211 const std::string stripped_path = StripParameters(path); 245 const std::string stripped_path = StripParameters(path);
212 for (size_t i = 0; i < arraysize(kResources); ++i) { 246 for (size_t i = 0; i < arraysize(kResources); ++i) {
213 if (stripped_path == kResources[i].filename) 247 if (stripped_path == kResources[i].filename)
214 return kResources[i].mime_type; 248 return kResources[i].mime_type;
215 } 249 }
216 return std::string(); 250 return std::string();
217 } 251 }
218 252
219 bool LocalNtpSource::AllowCaching() const { 253 bool LocalNtpSource::AllowCaching() const {
220 // Some resources served by LocalNtpSource, i.e. config.js, are dynamically 254 // Some resources served by LocalNtpSource, i.e. config.js, are dynamically
221 // generated and could differ on each access. To avoid using old cached 255 // generated and could differ on each access. To avoid using old cached
222 // content on reload, disallow caching here. Otherwise, it fails to reflect 256 // content on reload, disallow caching here. Otherwise, it fails to reflect
223 // newly revised user configurations in the page. 257 // newly revised user configurations in the page.
224 return false; 258 return false;
225 } 259 }
226 260
227 bool LocalNtpSource::ShouldServiceRequest( 261 bool LocalNtpSource::ShouldServiceRequest(
228 const net::URLRequest* request) const { 262 const net::URLRequest* request) const {
229 DCHECK(request->url().host_piece() == chrome::kChromeSearchLocalNtpHost); 263 DCHECK(request->url().host_piece() == chrome::kChromeSearchLocalNtpHost);
230 if (!InstantIOContext::ShouldServiceRequest(request)) 264 if (!InstantIOContext::ShouldServiceRequest(request))
231 return false; 265 return false;
232 266
233 if (request->url().SchemeIs(chrome::kChromeSearchScheme)) { 267 if (request->url().SchemeIs(chrome::kChromeSearchScheme)) {
234 std::string filename; 268 std::string filename;
235 webui::ParsePathAndScale(request->url(), &filename, NULL); 269 webui::ParsePathAndScale(request->url(), &filename, nullptr);
236 for (size_t i = 0; i < arraysize(kResources); ++i) { 270 for (size_t i = 0; i < arraysize(kResources); ++i) {
237 if (filename == kResources[i].filename) 271 if (filename == kResources[i].filename)
238 return true; 272 return true;
239 } 273 }
240 } 274 }
241 return false; 275 return false;
242 } 276 }
243 277
278 std::string LocalNtpSource::GetContentSecurityPolicyScriptSrc() const {
279 return "script-src 'strict-dynamic' "
Marc Treib 2017/04/07 16:46:15 Could hide this behind a (default-enabled) feature
sfiera 2017/04/10 08:53:21 Right now, users only land on the local NTP if the
Marc Treib 2017/04/10 10:11:18 Even while offline, there should usually be a cach
280 "'sha256-" +
281 GetIntegritySha256Value(GetConfigData(profile_)) +
sfiera 2017/04/10 08:53:21 Are we going to be computing this hash multiple ti
Marc Treib 2017/04/10 10:11:18 Yes; twice at the very least, probably even more o
sfiera 2017/04/10 10:28:53 I was thinking about computing once when the HTML
Marc Treib 2017/04/10 11:44:03 The CSP is served through HTTP headers, so that ac
282 "' "
283 "'sha256-g38WaUaxnOIWY7E2LtLZ5ff9r5sn1dBj80jevt/kmx0=';";
284 }
285
244 std::string LocalNtpSource::GetContentSecurityPolicyChildSrc() const { 286 std::string LocalNtpSource::GetContentSecurityPolicyChildSrc() const {
245 // Allow embedding of most visited iframes. 287 // Allow embedding of most visited iframes.
246 return base::StringPrintf("child-src %s;", 288 return base::StringPrintf("child-src %s;",
247 chrome::kChromeSearchMostVisitedUrl); 289 chrome::kChromeSearchMostVisitedUrl);
248 } 290 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698