Index: chrome/browser/search/local_ntp_source.cc |
diff --git a/chrome/browser/search/local_ntp_source.cc b/chrome/browser/search/local_ntp_source.cc |
index 4388e6a087d92e4c31ea3e1b8a9f11f371836eb7..efa9576765afd6fad18458d1a2df425f86e3e044 100644 |
--- a/chrome/browser/search/local_ntp_source.cc |
+++ b/chrome/browser/search/local_ntp_source.cc |
@@ -8,6 +8,7 @@ |
#include <memory> |
+#include "base/base64.h" |
#include "base/command_line.h" |
#include "base/json/json_string_value_serializer.h" |
#include "base/logging.h" |
@@ -31,6 +32,8 @@ |
#include "chrome/grit/theme_resources.h" |
#include "components/search_engines/template_url_service.h" |
#include "components/strings/grit/components_strings.h" |
+#include "crypto/secure_hash.h" |
+#include "net/base/hash_value.h" |
#include "net/url_request/url_request.h" |
#include "third_party/skia/include/core/SkColor.h" |
#include "ui/base/l10n/l10n_util.h" |
@@ -46,13 +49,14 @@ const int kLocalResource = -1; |
const char kConfigDataFilename[] = "config.js"; |
const char kThemeCSSFilename[] = "theme.css"; |
+const char kMainHtmlFilename[] = "local-ntp.html"; |
const struct Resource{ |
const char* filename; |
int identifier; |
const char* mime_type; |
} kResources[] = { |
- {"local-ntp.html", IDR_LOCAL_NTP_HTML, "text/html"}, |
+ {kMainHtmlFilename, kLocalResource, "text/html"}, |
{"local-ntp.js", IDR_LOCAL_NTP_JS, "application/javascript"}, |
{kConfigDataFilename, kLocalResource, "application/javascript"}, |
{kThemeCSSFilename, kLocalResource, "text/css"}, |
@@ -134,6 +138,22 @@ std::string GetConfigData(Profile* profile) { |
return config_data_js; |
} |
+std::string GetIntegritySha256Value(const std::string& data) { |
+ // Compute the sha256 hash. |
+ net::SHA256HashValue hash_value; |
+ std::unique_ptr<crypto::SecureHash> hash( |
+ crypto::SecureHash::Create(crypto::SecureHash::SHA256)); |
+ hash->Update(data.data(), data.size()); |
+ hash->Finish(&hash_value, sizeof(hash_value)); |
+ |
+ // Base64-encode it. |
+ base::StringPiece hash_value_str(reinterpret_cast<char*>(hash_value.data), |
+ sizeof(hash_value)); |
+ std::string result; |
+ base::Base64Encode(hash_value_str, &result); |
+ return result; |
+} |
+ |
std::string GetThemeCSS(Profile* profile) { |
SkColor background_color = |
ThemeService::GetThemeProviderForProfile(profile) |
@@ -181,6 +201,8 @@ void LocalNtpSource::StartDataRequest( |
if (command_line->HasSwitch(switches::kLocalNtpReload)) { |
if (stripped_path == "local-ntp.html" || stripped_path == "local-ntp.js" || |
stripped_path == "local-ntp.css") { |
+ // TODO(treib): This is now broken for the html file - need to insert the |
+ // 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
|
base::ReplaceChars(stripped_path, "-", "_", &stripped_path); |
local_ntp::SendLocalFileResource(stripped_path, callback); |
return; |
@@ -188,6 +210,18 @@ void LocalNtpSource::StartDataRequest( |
} |
#endif // !defined(GOOGLE_CHROME_BUILD) |
+ if (stripped_path == kMainHtmlFilename) { |
+ std::string html = ResourceBundle::GetSharedInstance() |
+ .GetRawDataResource(IDR_LOCAL_NTP_HTML) |
+ .as_string(); |
+ std::string config_sha256 = |
+ "sha256-" + GetIntegritySha256Value(GetConfigData(profile_)); |
+ base::ReplaceFirstSubstringAfterOffset(&html, 0, "{{CONFIG_INTEGRITY}}", |
+ config_sha256); |
+ callback.Run(base::RefCountedString::TakeString(&html)); |
+ return; |
+ } |
+ |
float scale = 1.0f; |
std::string filename; |
webui::ParsePathAndScale( |
@@ -203,7 +237,7 @@ void LocalNtpSource::StartDataRequest( |
return; |
} |
} |
- callback.Run(NULL); |
+ callback.Run(nullptr); |
} |
std::string LocalNtpSource::GetMimeType( |
@@ -232,7 +266,7 @@ bool LocalNtpSource::ShouldServiceRequest( |
if (request->url().SchemeIs(chrome::kChromeSearchScheme)) { |
std::string filename; |
- webui::ParsePathAndScale(request->url(), &filename, NULL); |
+ webui::ParsePathAndScale(request->url(), &filename, nullptr); |
for (size_t i = 0; i < arraysize(kResources); ++i) { |
if (filename == kResources[i].filename) |
return true; |
@@ -241,6 +275,14 @@ bool LocalNtpSource::ShouldServiceRequest( |
return false; |
} |
+std::string LocalNtpSource::GetContentSecurityPolicyScriptSrc() const { |
+ 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
|
+ "'sha256-" + |
+ 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
|
+ "' " |
+ "'sha256-g38WaUaxnOIWY7E2LtLZ5ff9r5sn1dBj80jevt/kmx0=';"; |
+} |
+ |
std::string LocalNtpSource::GetContentSecurityPolicyChildSrc() const { |
// Allow embedding of most visited iframes. |
return base::StringPrintf("child-src %s;", |