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/browser/ui/webui/devtools_ui.h" | 5 #include "chrome/browser/ui/webui/devtools_ui.h" |
6 | 6 |
7 #include "base/macros.h" | 7 #include "base/macros.h" |
8 #include "base/memory/ref_counted_memory.h" | 8 #include "base/memory/ref_counted_memory.h" |
9 #include "base/strings/string_util.h" | 9 #include "base/strings/string_util.h" |
10 #include "base/strings/stringprintf.h" | 10 #include "base/strings/stringprintf.h" |
11 #include "chrome/browser/profiles/profile.h" | 11 #include "chrome/browser/profiles/profile.h" |
12 #include "chrome/common/url_constants.h" | 12 #include "chrome/common/url_constants.h" |
13 #include "content/public/browser/browser_thread.h" | 13 #include "content/public/browser/browser_thread.h" |
14 #include "content/public/browser/devtools_frontend_host.h" | 14 #include "content/public/browser/devtools_frontend_host.h" |
15 #include "content/public/browser/url_data_source.h" | 15 #include "content/public/browser/url_data_source.h" |
16 #include "content/public/browser/web_contents.h" | 16 #include "content/public/browser/web_contents.h" |
17 #include "content/public/browser/web_ui.h" | 17 #include "content/public/browser/web_ui.h" |
18 #include "content/public/common/user_agent.h" | 18 #include "content/public/common/user_agent.h" |
19 #include "net/base/url_util.h" | |
19 #include "net/url_request/url_fetcher.h" | 20 #include "net/url_request/url_fetcher.h" |
20 #include "net/url_request/url_fetcher_delegate.h" | 21 #include "net/url_request/url_fetcher_delegate.h" |
21 #include "net/url_request/url_request_context_getter.h" | 22 #include "net/url_request/url_request_context_getter.h" |
22 | 23 |
23 using content::BrowserThread; | 24 using content::BrowserThread; |
24 using content::WebContents; | 25 using content::WebContents; |
25 | 26 |
26 namespace { | 27 namespace { |
27 | 28 |
29 GURL FullURLForPath(const std::string& path) { | |
30 return GURL(std::string("chrome-devtools://devtools/") + path); | |
31 } | |
32 | |
28 std::string PathWithoutParams(const std::string& path) { | 33 std::string PathWithoutParams(const std::string& path) { |
29 return GURL(std::string("chrome-devtools://devtools/") + path) | 34 return FullURLForPath(path).path().substr(1); |
30 .path().substr(1); | 35 } |
36 | |
37 bool AllowURL( | |
38 const std::string& prefix, | |
39 const std::string& value, | |
40 const std::string& suffix) { | |
41 // https://chrome-devtools-frontend.appspot.com/serve_(file|rev)/ | |
42 // [@0-9a-zA-Z]*/(devtools.html|inspector.html|/|) | |
43 std::string s = value; | |
44 if (s.length() < prefix.length()) | |
45 return false; | |
46 if (s.substr(0, prefix.length()) != prefix) | |
47 return false; | |
48 s = s.substr(prefix.length()); | |
49 if (s.length() < suffix.length()) | |
50 return false; | |
51 if (s.substr(s.length() - suffix.length()) != suffix) | |
52 return false; | |
53 s = s.substr(0, s.length() - suffix.length()); | |
54 for (size_t i = 0; i < s.length(); i++) { | |
55 if (s[i] != '@' | |
56 && (s[i] < '0' || s[i] > '9') | |
57 && (s[i] < 'a' || s[i] > 'z') | |
58 && (s[i] < 'A' || s[i] > 'Z')) { | |
59 return false; | |
60 } | |
61 } | |
62 return true; | |
31 } | 63 } |
32 | 64 |
33 const char kRemoteFrontendDomain[] = "chrome-devtools-frontend.appspot.com"; | 65 const char kRemoteFrontendDomain[] = "chrome-devtools-frontend.appspot.com"; |
34 const char kRemoteFrontendBase[] = | 66 const char kRemoteFrontendBase[] = |
35 "https://chrome-devtools-frontend.appspot.com/"; | 67 "https://chrome-devtools-frontend.appspot.com/"; |
36 const char kRemoteFrontendPath[] = "serve_file"; | 68 const char kRemoteFrontendPath[] = "serve_file"; |
37 const char kHttpNotFound[] = "HTTP/1.1 404 Not Found\n\n"; | 69 const char kHttpNotFound[] = "HTTP/1.1 404 Not Found\n\n"; |
70 const char kRemoteBasePrefix[] = | |
71 "https://chrome-devtools-frontend.appspot.com/serve_file/"; | |
72 const char kRemoteFrontendUrlPrefix[] = | |
73 "https://chrome-devtools-frontend.appspot.com/serve_rev/"; | |
74 const char kRemoteFrontendUrlSuffix1[] = "/devtools.html"; | |
75 const char kRemoteFrontendUrlSuffix2[] = "/inspector.html"; | |
38 | 76 |
39 #if defined(DEBUG_DEVTOOLS) | 77 #if defined(DEBUG_DEVTOOLS) |
40 // Local frontend url provided by InspectUI. | 78 // Local frontend url provided by InspectUI. |
41 const char kFallbackFrontendURL[] = | 79 const char kFallbackFrontendURL[] = |
42 "chrome-devtools://devtools/bundled/inspector.html"; | 80 "chrome-devtools://devtools/bundled/inspector.html"; |
43 #else | 81 #else |
44 // URL causing the DevTools window to display a plain text warning. | 82 // URL causing the DevTools window to display a plain text warning. |
45 const char kFallbackFrontendURL[] = | 83 const char kFallbackFrontendURL[] = |
46 "data:text/plain,Cannot load DevTools frontend from an untrusted origin"; | 84 "data:text/plain,Cannot load DevTools frontend from an untrusted origin"; |
47 #endif // defined(DEBUG_DEVTOOLS) | 85 #endif // defined(DEBUG_DEVTOOLS) |
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
135 } | 173 } |
136 | 174 |
137 std::string DevToolsDataSource::GetSource() const { | 175 std::string DevToolsDataSource::GetSource() const { |
138 return chrome::kChromeUIDevToolsHost; | 176 return chrome::kChromeUIDevToolsHost; |
139 } | 177 } |
140 | 178 |
141 void DevToolsDataSource::StartDataRequest( | 179 void DevToolsDataSource::StartDataRequest( |
142 const std::string& path, | 180 const std::string& path, |
143 const content::ResourceRequestInfo::WebContentsGetter& wc_getter, | 181 const content::ResourceRequestInfo::WebContentsGetter& wc_getter, |
144 const content::URLDataSource::GotDataCallback& callback) { | 182 const content::URLDataSource::GotDataCallback& callback) { |
183 GURL fullUrl = FullURLForPath(path); | |
pfeldman
2016/10/08 01:01:44
Lets introduce
GURL sanitizeFrontendURL(GURL)
{
dgozman
2016/10/10 23:27:27
Done.
| |
184 for (net::QueryIterator it(fullUrl); !it.IsAtEnd(); it.Advance()) { | |
185 bool allow = true; | |
186 if (it.GetKey() == "settings") | |
pfeldman
2016/10/08 01:01:44
Extract each of these and provide descriptions on
| |
187 allow = false; | |
188 if (it.GetKey() == "remoteBase") { | |
189 allow = AllowURL(kRemoteBasePrefix, it.GetUnescapedValue(), "") || | |
190 AllowURL(kRemoteBasePrefix, it.GetUnescapedValue(), "\\"); | |
191 } | |
192 if (it.GetKey() == "remoteFrontendUrl") { | |
193 allow = | |
194 AllowURL(kRemoteFrontendUrlPrefix, it.GetUnescapedValue(), | |
195 kRemoteFrontendUrlSuffix1) | |
196 || AllowURL(kRemoteFrontendUrlPrefix, it.GetUnescapedValue(), | |
197 kRemoteFrontendUrlSuffix2); | |
198 } | |
199 if (!allow) { | |
200 callback.Run(nullptr); | |
201 return; | |
202 } | |
203 } | |
204 | |
145 // Serve request from local bundle. | 205 // Serve request from local bundle. |
146 std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath); | 206 std::string bundled_path_prefix(chrome::kChromeUIDevToolsBundledPath); |
147 bundled_path_prefix += "/"; | 207 bundled_path_prefix += "/"; |
148 if (base::StartsWith(path, bundled_path_prefix, | 208 if (base::StartsWith(path, bundled_path_prefix, |
149 base::CompareCase::INSENSITIVE_ASCII)) { | 209 base::CompareCase::INSENSITIVE_ASCII)) { |
150 StartBundledDataRequest(path.substr(bundled_path_prefix.length()), | 210 StartBundledDataRequest(path.substr(bundled_path_prefix.length()), |
151 callback); | 211 callback); |
152 return; | 212 return; |
153 } | 213 } |
154 | 214 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
255 bindings_(web_ui->GetWebContents()) { | 315 bindings_(web_ui->GetWebContents()) { |
256 web_ui->SetBindings(0); | 316 web_ui->SetBindings(0); |
257 Profile* profile = Profile::FromWebUI(web_ui); | 317 Profile* profile = Profile::FromWebUI(web_ui); |
258 content::URLDataSource::Add( | 318 content::URLDataSource::Add( |
259 profile, | 319 profile, |
260 new DevToolsDataSource(profile->GetRequestContext())); | 320 new DevToolsDataSource(profile->GetRequestContext())); |
261 } | 321 } |
262 | 322 |
263 DevToolsUI::~DevToolsUI() { | 323 DevToolsUI::~DevToolsUI() { |
264 } | 324 } |
OLD | NEW |