From: csagan5 <32685696+csagan5@users.noreply.github.com> Date: Wed, 30 Oct 2019 11:50:13 +0100 Subject: Block 'qjz9zk' or 'trk:' requests An info bar is displayed unless the --disable-trkbar command-line flag or the chrome://flag option is used. This patch is based on Iridium's 'net: add "trk:" scheme and help identify URLs being retrieved' License: GPL-3.0-only - https://spdx.org/licenses/GPL-3.0-only.html --- .../chrome_autocomplete_scheme_classifier.cc | 1 + chrome/browser/history/history_utils.cc | 1 + chrome/browser/ui/singleton_tabs.cc | 5 ++++ .../omnibox/browser/autocomplete_input.cc | 8 ++++- components/url_formatter/url_fixer.cc | 4 +++ .../child_process_security_policy_impl.cc | 1 + net/BUILD.gn | 2 ++ net/url_request/trk_protocol_handler.cc | 25 ++++++++++++++++ net/url_request/trk_protocol_handler.h | 30 +++++++++++++++++++ net/url_request/url_request.cc | 8 +++++ .../url_request_context_builder.cc | 3 ++ url/url_constants.cc | 1 + url/url_constants.h | 1 + url/url_util.cc | 2 ++ 14 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 net/url_request/trk_protocol_handler.cc create mode 100644 net/url_request/trk_protocol_handler.h diff --git a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc --- a/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc +++ b/chrome/browser/autocomplete/chrome_autocomplete_scheme_classifier.cc @@ -58,6 +58,7 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme( if (base::IsStringASCII(scheme) && (ProfileIOData::IsHandledProtocol(scheme) || base::EqualsCaseInsensitiveASCII(scheme, content::kViewSourceScheme) || + base::EqualsCaseInsensitiveASCII(scheme, url::kTraceScheme) || base::EqualsCaseInsensitiveASCII(scheme, url::kJavaScriptScheme) || base::EqualsCaseInsensitiveASCII(scheme, url::kDataScheme))) { return metrics::OmniboxInputType::URL; diff --git a/chrome/browser/history/history_utils.cc b/chrome/browser/history/history_utils.cc --- a/chrome/browser/history/history_utils.cc +++ b/chrome/browser/history/history_utils.cc @@ -22,6 +22,7 @@ bool CanAddURLToHistory(const GURL& url) { url.SchemeIs(content::kChromeUIScheme) || url.SchemeIs(content::kChromeUIUntrustedScheme) || url.SchemeIs(content::kViewSourceScheme) || + url.SchemeIs(url::kTraceScheme) || url.SchemeIs(chrome::kChromeNativeScheme) || url.SchemeIs(chrome::kChromeSearchScheme) || url.SchemeIs(dom_distiller::kDomDistillerScheme)) diff --git a/chrome/browser/ui/singleton_tabs.cc b/chrome/browser/ui/singleton_tabs.cc --- a/chrome/browser/ui/singleton_tabs.cc +++ b/chrome/browser/ui/singleton_tabs.cc @@ -174,6 +174,11 @@ int GetIndexOfExistingTab(Browser* browser, const NavigateParams& params) { continue; } + // trk: URLs must not be rewritten + if (tab_url.SchemeIs(url::kTraceScheme)) { + continue; + } + GURL rewritten_tab_url = tab_url; content::BrowserURLHandler::GetInstance()->RewriteURLIfNecessary( &rewritten_tab_url, browser->profile()); diff --git a/components/omnibox/browser/autocomplete_input.cc b/components/omnibox/browser/autocomplete_input.cc --- a/components/omnibox/browser/autocomplete_input.cc +++ b/components/omnibox/browser/autocomplete_input.cc @@ -90,10 +90,15 @@ void OffsetComponentsExcludingScheme(url::Parsed* parts, int offset) { bool HasScheme(const std::u16string& input, const char* scheme) { std::string utf8_input(base::UTF16ToUTF8(input)); url::Component view_source_scheme; + + if (url::FindAndCompareScheme(utf8_input, url::kTraceScheme, &view_source_scheme)) { + return false; + } if (url::FindAndCompareScheme(utf8_input, kViewSourceScheme, &view_source_scheme)) { utf8_input.erase(0, view_source_scheme.end() + 1); } + return url::FindAndCompareScheme(utf8_input, scheme, nullptr); } @@ -581,7 +586,8 @@ void AutocompleteInput::ParseForEmphasizeComponents( // For the view-source and blob schemes, we should emphasize the host of the // URL qualified by the view-source or blob prefix. if ((base::EqualsCaseInsensitiveASCII(scheme_str, kViewSourceScheme) || - base::EqualsCaseInsensitiveASCII(scheme_str, url::kBlobScheme)) && + base::EqualsCaseInsensitiveASCII(scheme_str, url::kBlobScheme) || + base::EqualsCaseInsensitiveASCII(scheme_str, url::kTraceScheme)) && (static_cast(text.length()) > after_scheme_and_colon)) { // Obtain the URL prefixed by view-source or blob and parse it. std::u16string real_url(text.substr(after_scheme_and_colon)); diff --git a/components/url_formatter/url_fixer.cc b/components/url_formatter/url_fixer.cc --- a/components/url_formatter/url_fixer.cc +++ b/components/url_formatter/url_fixer.cc @@ -563,6 +563,10 @@ GURL FixupURL(const std::string& text, const std::string& desired_tld) { } } + if (scheme == url::kTraceScheme) { + return GURL(); + } + // We handle the file scheme separately. if (scheme == url::kFileScheme) return GURL(parts.scheme.is_valid() ? text : FixupPath(text)); diff --git a/content/browser/child_process_security_policy_impl.cc b/content/browser/child_process_security_policy_impl.cc --- a/content/browser/child_process_security_policy_impl.cc +++ b/content/browser/child_process_security_policy_impl.cc @@ -829,6 +829,7 @@ ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() RegisterPseudoScheme(url::kJavaScriptScheme); RegisterPseudoScheme(kViewSourceScheme); RegisterPseudoScheme(kGoogleChromeScheme); + RegisterWebSafeScheme(url::kTraceScheme); } ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() { diff --git a/net/BUILD.gn b/net/BUILD.gn --- a/net/BUILD.gn +++ b/net/BUILD.gn @@ -1056,6 +1056,8 @@ component("net") { "url_request/url_request_http_job.cc", "url_request/url_request_http_job.h", "url_request/url_request_interceptor.cc", + "url_request/trk_protocol_handler.cc", + "url_request/trk_protocol_handler.h", "url_request/url_request_interceptor.h", "url_request/url_request_job.cc", "url_request/url_request_job.h", diff --git a/net/url_request/trk_protocol_handler.cc b/net/url_request/trk_protocol_handler.cc new file mode 100644 --- /dev/null +++ b/net/url_request/trk_protocol_handler.cc @@ -0,0 +1,25 @@ +// Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "net/url_request/trk_protocol_handler.h" + +#include "base/logging.h" +#include "net/base/net_errors.h" +#include "net/url_request/url_request_error_job.h" + +namespace net { + +TrkProtocolHandler::TrkProtocolHandler() = default; + +std::unique_ptr TrkProtocolHandler::CreateJob( + URLRequest* request) const { + LOG(ERROR) << "Blocked URL in TrkProtocolHandler: " << request->original_url(); + return std::make_unique(request, ERR_BLOCKED_BY_CLIENT); +} + +bool TrkProtocolHandler::IsSafeRedirectTarget(const GURL& location) const { + return true; +} + +} // namespace net diff --git a/net/url_request/trk_protocol_handler.h b/net/url_request/trk_protocol_handler.h new file mode 100644 --- /dev/null +++ b/net/url_request/trk_protocol_handler.h @@ -0,0 +1,30 @@ +// Copyright (c) 2018 The ungoogled-chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef NET_URL_REQUEST_TRK_PROTOCOL_HANDLER_H_ +#define NET_URL_REQUEST_TRK_PROTOCOL_HANDLER_H_ + +#include "base/compiler_specific.h" +#include "net/base/net_export.h" +#include "net/url_request/url_request_job_factory.h" + +namespace net { + +class URLRequestJob; + +// Implements a ProtocolHandler for Trk jobs. +class NET_EXPORT TrkProtocolHandler + : public URLRequestJobFactory::ProtocolHandler { + public: + TrkProtocolHandler(const TrkProtocolHandler&) = delete; + TrkProtocolHandler& operator=(const TrkProtocolHandler&) = delete; + + TrkProtocolHandler(); + std::unique_ptr CreateJob(URLRequest* request) const override; + bool IsSafeRedirectTarget(const GURL& location) const override; +}; + +} // namespace net + +#endif // NET_URL_REQUEST_TRK_PROTOCOL_HANDLER_H_ diff --git a/net/url_request/url_request.cc b/net/url_request/url_request.cc --- a/net/url_request/url_request.cc +++ b/net/url_request/url_request.cc @@ -13,6 +13,7 @@ #include "base/metrics/histogram_macros.h" #include "base/rand_util.h" #include "base/strings/utf_string_conversions.h" +#include "base/strings/string_util.h" #include "base/synchronization/lock.h" #include "base/task/single_thread_task_runner.h" #include "base/types/pass_key.h" @@ -47,6 +48,7 @@ #include "net/url_request/url_request_redirect_job.h" #include "url/gurl.h" #include "url/origin.h" +#include "url/url_constants.h" namespace net { @@ -597,6 +599,12 @@ URLRequest::URLRequest(base::PassKey pass_key, // Sanity check out environment. DCHECK(base::SingleThreadTaskRunner::HasCurrentDefault()); + if (!url.SchemeIs(url::kTraceScheme) && + base::EndsWith(url.host(), "qjz9zk", base::CompareCase::INSENSITIVE_ASCII)) { + LOG(ERROR) << "Block URL in URLRequest: " << url; + url_chain_[0] = GURL(url::kTraceScheme + (":" + url.possibly_invalid_spec())); + } + context->url_requests()->insert(this); net_log_.BeginEvent(NetLogEventType::REQUEST_ALIVE, [&] { return NetLogURLRequestConstructorParams(url, priority_, diff --git a/net/url_request/url_request_context_builder.cc b/net/url_request/url_request_context_builder.cc --- a/net/url_request/url_request_context_builder.cc +++ b/net/url_request/url_request_context_builder.cc @@ -48,6 +48,7 @@ #include "net/socket/network_binding_client_socket_factory.h" #include "net/ssl/ssl_config_service_defaults.h" #include "net/url_request/static_http_user_agent_settings.h" +#include "net/url_request/trk_protocol_handler.h" #include "net/url_request/url_request_context.h" #include "net/url_request/url_request_job_factory.h" #include "net/url_request/url_request_throttler_manager.h" @@ -574,6 +575,8 @@ std::unique_ptr URLRequestContextBuilder::Build() { job_factory->SetProtocolHandler(scheme_handler.first, std::move(scheme_handler.second)); } + job_factory->SetProtocolHandler(url::kTraceScheme, + std::make_unique()); protocol_handlers_.clear(); context->set_job_factory(std::move(job_factory)); diff --git a/url/url_constants.cc b/url/url_constants.cc --- a/url/url_constants.cc +++ b/url/url_constants.cc @@ -29,6 +29,7 @@ const char16_t kDataScheme16[] = u"data"; const char kFileScheme[] = "file"; const char16_t kFileScheme16[] = u"file"; const char kFileSystemScheme[] = "filesystem"; +const char kTraceScheme[] = "trk"; const char16_t kFileSystemScheme16[] = u"filesystem"; const char kFtpScheme[] = "ftp"; const char16_t kFtpScheme16[] = u"ftp"; diff --git a/url/url_constants.h b/url/url_constants.h --- a/url/url_constants.h +++ b/url/url_constants.h @@ -33,6 +33,7 @@ COMPONENT_EXPORT(URL) extern const char16_t kContentIDScheme16[]; COMPONENT_EXPORT(URL) extern const char kDataScheme[]; COMPONENT_EXPORT(URL) extern const char16_t kDataScheme16[]; COMPONENT_EXPORT(URL) extern const char kFileScheme[]; +COMPONENT_EXPORT(URL) extern const char kTraceScheme[]; COMPONENT_EXPORT(URL) extern const char16_t kFileScheme16[]; COMPONENT_EXPORT(URL) extern const char kFileSystemScheme[]; COMPONENT_EXPORT(URL) extern const char16_t kFileSystemScheme16[]; diff --git a/url/url_util.cc b/url/url_util.cc --- a/url/url_util.cc +++ b/url/url_util.cc @@ -46,6 +46,7 @@ struct SchemeRegistry { std::vector standard_schemes = { {kHttpsScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, {kHttpScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, + {kTraceScheme, SCHEME_WITH_HOST_PORT_AND_USER_INFORMATION}, // Yes, file URLs can have a hostname, so file URLs should be handled as // "standard". File URLs never have a port as specified by the SchemeType // field. Unlike other SCHEME_WITH_HOST schemes, the 'host' in a file @@ -91,6 +92,7 @@ struct SchemeRegistry { kAboutScheme, kJavaScriptScheme, kDataScheme, + kTraceScheme, }; // Schemes that can be sent CORS requests. -- 2.25.1