Chromium Code Reviews| Index: chrome/browser/ui/webui/devtools_ui.cc |
| diff --git a/chrome/browser/ui/webui/devtools_ui.cc b/chrome/browser/ui/webui/devtools_ui.cc |
| index de76e8b3e0bfc6cf980febc4a0a89c0954199684..454456eb6c5c53d74ee59eeac88d423076def3b7 100644 |
| --- a/chrome/browser/ui/webui/devtools_ui.cc |
| +++ b/chrome/browser/ui/webui/devtools_ui.cc |
| @@ -16,6 +16,7 @@ |
| #include "content/public/browser/web_contents.h" |
| #include "content/public/browser/web_ui.h" |
| #include "content/public/common/user_agent.h" |
| +#include "net/base/url_util.h" |
| #include "net/url_request/url_fetcher.h" |
| #include "net/url_request/url_fetcher_delegate.h" |
| #include "net/url_request/url_request_context_getter.h" |
| @@ -25,9 +26,40 @@ using content::WebContents; |
| namespace { |
| +GURL FullURLForPath(const std::string& path) { |
| + return GURL(std::string("chrome-devtools://devtools/") + path); |
| +} |
| + |
| std::string PathWithoutParams(const std::string& path) { |
| - return GURL(std::string("chrome-devtools://devtools/") + path) |
| - .path().substr(1); |
| + return FullURLForPath(path).path().substr(1); |
| +} |
| + |
| +bool AllowURL( |
| + const std::string& prefix, |
| + const std::string& value, |
| + const std::string& suffix) { |
| + // https://chrome-devtools-frontend.appspot.com/serve_(file|rev)/ |
| + // [@0-9a-zA-Z]*/(devtools.html|inspector.html|/|) |
| + std::string s = value; |
| + if (s.length() < prefix.length()) |
| + return false; |
| + if (s.substr(0, prefix.length()) != prefix) |
| + return false; |
| + s = s.substr(prefix.length()); |
| + if (s.length() < suffix.length()) |
| + return false; |
| + if (s.substr(s.length() - suffix.length()) != suffix) |
| + return false; |
| + s = s.substr(0, s.length() - suffix.length()); |
| + for (size_t i = 0; i < s.length(); i++) { |
| + if (s[i] != '@' |
| + && (s[i] < '0' || s[i] > '9') |
| + && (s[i] < 'a' || s[i] > 'z') |
| + && (s[i] < 'A' || s[i] > 'Z')) { |
| + return false; |
| + } |
| + } |
| + return true; |
| } |
| const char kRemoteFrontendDomain[] = "chrome-devtools-frontend.appspot.com"; |
| @@ -35,6 +67,12 @@ const char kRemoteFrontendBase[] = |
| "https://chrome-devtools-frontend.appspot.com/"; |
| const char kRemoteFrontendPath[] = "serve_file"; |
| const char kHttpNotFound[] = "HTTP/1.1 404 Not Found\n\n"; |
| +const char kRemoteBasePrefix[] = |
| + "https://chrome-devtools-frontend.appspot.com/serve_file/"; |
| +const char kRemoteFrontendUrlPrefix[] = |
| + "https://chrome-devtools-frontend.appspot.com/serve_rev/"; |
| +const char kRemoteFrontendUrlSuffix1[] = "/devtools.html"; |
| +const char kRemoteFrontendUrlSuffix2[] = "/inspector.html"; |
| #if defined(DEBUG_DEVTOOLS) |
| // Local frontend url provided by InspectUI. |
| @@ -142,6 +180,28 @@ void DevToolsDataSource::StartDataRequest( |
| const std::string& path, |
| const content::ResourceRequestInfo::WebContentsGetter& wc_getter, |
| const content::URLDataSource::GotDataCallback& callback) { |
| + GURL fullUrl = FullURLForPath(path); |
|
pfeldman
2016/10/08 01:01:44
Lets introduce
GURL sanitizeFrontendURL(GURL)
{
dgozman
2016/10/10 23:27:27
Done.
|
| + for (net::QueryIterator it(fullUrl); !it.IsAtEnd(); it.Advance()) { |
| + bool allow = true; |
| + if (it.GetKey() == "settings") |
|
pfeldman
2016/10/08 01:01:44
Extract each of these and provide descriptions on
|
| + allow = false; |
| + if (it.GetKey() == "remoteBase") { |
| + allow = AllowURL(kRemoteBasePrefix, it.GetUnescapedValue(), "") || |
| + AllowURL(kRemoteBasePrefix, it.GetUnescapedValue(), "\\"); |
| + } |
| + if (it.GetKey() == "remoteFrontendUrl") { |
| + allow = |
| + AllowURL(kRemoteFrontendUrlPrefix, it.GetUnescapedValue(), |
| + kRemoteFrontendUrlSuffix1) |
| + || AllowURL(kRemoteFrontendUrlPrefix, it.GetUnescapedValue(), |
| + kRemoteFrontendUrlSuffix2); |
| + } |
| + if (!allow) { |
| + callback.Run(nullptr); |
| + return; |
| + } |
| + } |
| + |
| // Serve request from local bundle. |
| std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath); |
| bundled_path_prefix += "/"; |