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 += "/"; |