Skip to content
Permalink
Browse files

net: add "trk:" scheme and help identify URLs being retrieved

The Chromium codebase has left us with a number of suspect URLs, and
we want to know if the browser attempts to contact those sites.

This patch introduces a new scheme, "trk:", which, when attempted to
being processed, will dump a warning onto the screen as the resource
is loaded. All URLs we think are suspect are "blacklisted" by
prepending the new scheme to an existing URL:

	trk🔢https://clients4.google.com/
	trk:https://clients4.google.com/ (unnumbered old variant)
	trk:0.1234:https://... (stderr only, no UI reporting)

Upon seeing a warning, we then know to investigate further, and either
(a) whitelist the URL, that is, remove the trk: prefix and not show
the warning, and/or (b) disable the particular feature which caused
the loading of the URL in the first place, by default.

Implementation:

We hack up the URLFetcher class which sits in the network stack, and
most of the URL that get loaded pass through here. The trk: prefix is
stripped and processing continues with the inner URL.
  • Loading branch information
jengelh committed May 19, 2015
1 parent 0fda883 commit 8bc1e51844d0c9af4316c413f11b9c822696e328
@@ -253,6 +253,8 @@ if (!is_android && !is_mac) {
sources += [ "app/chrome_exe_main_aura.cc" ]
}

deps += ["//iridium:trknotify"]

if (is_linux) {
sources += [
"app/chrome_dll_resource.h",
@@ -473,6 +475,7 @@ if (is_win) {
"//content/public/app:child",
"//content/public/common:service_names",
"//headless:headless_shell_child_lib",
"//iridium:trknotify",
"//services/service_manager/embedder",
]

@@ -17,6 +17,10 @@
#include "content/public/common/content_switches.h"
#include "headless/public/headless_shell.h"
#include "ui/gfx/switches.h"
#if !defined(CHROME_MULTIPLE_DLL_CHILD)
# include "net/url_request/url_request.h"
# include "iridium/trknotify.h"
#endif

#if defined(OS_MACOSX)
#include "chrome/app/chrome_main_mac.h"
@@ -45,6 +49,19 @@ int ChromeMain(int argc, const char** argv);
}
#endif

#if !defined(CHROME_MULTIPLE_DLL_CHILD)
static void trace_url_request(const std::string &caller, const GURL &url)
{
iridium::log_url_request(caller, url);
if (url.scheme() != url::kTraceScheme)
/* Do not show infobar for non-trk URLs */
return;
if (url.is_trq())
return;
iridium::trace_url_request(caller, url);
}
#endif

#if defined(OS_WIN)
DLLEXPORT int __cdecl ChromeMain(HINSTANCE instance,
sandbox::SandboxInterfaceInfo* sandbox_info,
@@ -107,6 +124,10 @@ int ChromeMain(int argc, const char** argv) {
}
#endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_WIN)

#if !defined(CHROME_MULTIPLE_DLL_CHILD)
net::trace_urlreq_cb = &trace_url_request;
#endif

int rv = content::ContentMain(params);

return rv;
@@ -28,6 +28,7 @@ ChromeAutocompleteSchemeClassifier::GetInputTypeForScheme(
if (base::IsStringASCII(scheme) &&
(ProfileIOData::IsHandledProtocol(scheme) ||
base::LowerCaseEqualsASCII(scheme, content::kViewSourceScheme) ||
base::LowerCaseEqualsASCII(scheme, url::kTraceScheme) ||
base::LowerCaseEqualsASCII(scheme, url::kJavaScriptScheme) ||
base::LowerCaseEqualsASCII(scheme, url::kDataScheme))) {
return metrics::OmniboxInputType::URL;
@@ -22,6 +22,7 @@ bool CanAddURLToHistory(const GURL& url) {
url.SchemeIs(content::kChromeDevToolsScheme) ||
url.SchemeIs(content::kChromeUIScheme) ||
url.SchemeIs(content::kViewSourceScheme) ||
url.SchemeIs(url::kTraceScheme) ||
url.SchemeIs(chrome::kChromeNativeScheme) ||
url.SchemeIs(chrome::kChromeSearchScheme) ||
url.SchemeIs(dom_distiller::kDomDistillerScheme) ||
@@ -796,6 +796,11 @@ bool IsURLAllowedInIncognito(const GURL& url,
return stripped_url.is_valid() &&
IsURLAllowedInIncognito(stripped_url, browser_context);
}

if (url.SchemeIs(url::kTraceScheme)) {
/* Same as view-source:, strip prefix and re-check. */
auto url2 = url.strip_trk();
return url2.is_valid() &&
IsURLAllowedInIncognito(url2, browser_context);
}
return IsHostAllowedInIncognito(url);
}
@@ -100,7 +100,8 @@ int GetIndexOfExistingTab(Browser* browser, const NavigateParams& params) {

// Skip view-source tabs. This is needed because RewriteURLIfNecessary
// removes the "view-source:" scheme which leads to incorrect matching.
if (tab_url.SchemeIs(content::kViewSourceScheme))
if (tab_url.SchemeIs(content::kViewSourceScheme) ||
tab_url.SchemeIs(url::kTraceScheme))
continue;

GURL rewritten_tab_url = tab_url;
@@ -159,6 +159,7 @@ class InfoBarDelegate {
TAB_SHARING_INFOBAR_DELEGATE = 93,
SAFETY_TIP_INFOBAR_DELEGATE = 94,
SMS_RECEIVER_INFOBAR_DELEGATE = 95,
TRACKING_ALERT_INFOBAR_DELEGATE = 9001,
};

// Describes navigation events, used to decide whether infobars should be
@@ -496,6 +496,7 @@ 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::LowerCaseEqualsASCII(scheme_str, kViewSourceScheme) ||
base::LowerCaseEqualsASCII(scheme_str, url::kTraceScheme) ||
base::LowerCaseEqualsASCII(scheme_str, url::kBlobScheme)) &&
(static_cast<int>(text.length()) > after_scheme_and_colon)) {
// Obtain the URL prefixed by view-source or blob and parse it.
@@ -569,9 +570,10 @@ int AutocompleteInput::NumNonHostComponents(const url::Parsed& parts) {
bool AutocompleteInput::HasHTTPScheme(const base::string16& input) {
std::string utf8_input(base::UTF16ToUTF8(input));
url::Component scheme;
if (url::FindAndCompareScheme(utf8_input, kViewSourceScheme, &scheme)) {
if (url::FindAndCompareScheme(utf8_input, url::kTraceScheme, &scheme))
gurl_strip_trk(utf8_input);
else if (url::FindAndCompareScheme(utf8_input, kViewSourceScheme, &scheme))
utf8_input.erase(0, scheme.end() + 1);
}
return url::FindAndCompareScheme(utf8_input, url::kHttpScheme, nullptr);
}

@@ -15,9 +15,28 @@
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "url/gurl.h"
#include "net/url_request/url_request.h"

namespace content {

static bool handle_trace_scheme(GURL *url, BrowserContext *)
{
if (!url->SchemeIs(url::kTraceScheme))
return false;
if (net::trace_urlreq_cb != NULL)
(*net::trace_urlreq_cb)("handle_trace_scheme", *url);
*url = url->strip_trk();
return false;
}

static bool trace_scheme_revlookup(GURL *url, BrowserContext *)
{
if (url->SchemeIs(url::kTraceScheme))
return false;
*url = GURL(url::kTraceScheme + (":" + url->spec()));
return true;
}

// Handles rewriting view-source URLs for what we'll actually load.
static bool HandleViewSource(GURL* url, BrowserContext* browser_context) {
if (url->SchemeIs(kViewSourceScheme)) {
@@ -101,6 +120,7 @@ BrowserURLHandlerImpl::BrowserURLHandlerImpl() :
AddHandlerPair(&HandleViewSource, &ReverseViewSource);

GetContentClient()->browser()->BrowserURLHandlerCreated(this);
AddHandlerPair(&handle_trace_scheme, &trace_scheme_revlookup);
}

BrowserURLHandlerImpl::~BrowserURLHandlerImpl() {
@@ -526,6 +526,7 @@ ChildProcessSecurityPolicyImpl::ChildProcessSecurityPolicyImpl() {
RegisterPseudoScheme(url::kJavaScriptScheme);
RegisterPseudoScheme(kViewSourceScheme);
RegisterPseudoScheme(kGoogleChromeScheme);
RegisterPseudoScheme(url::kTraceScheme);
}

ChildProcessSecurityPolicyImpl::~ChildProcessSecurityPolicyImpl() {
@@ -0,0 +1,9 @@
config("trknotify_c") {
include_dirs = ["..", "../third_party/skia/include/config", "../third_party/skia/include/core"]
}

component("trknotify") {
sources = ["trkbar.cpp", "trkbar.h", "trknotify.cpp", "trknotify.h"]
public_configs = [":trknotify_c"]
deps = ["//chrome/browser/ui"]
}
@@ -0,0 +1,45 @@
/*
* Copyright 2015 The Iridium Authors
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include "base/strings/utf_string_conversions.h"
#include "components/infobars/core/infobar.h"
#include "iridium/trkbar.h"

namespace content {

void TrkBar::Create(InfoBarService *s, const GURL &url)
{
s->AddInfoBar(s->CreateConfirmInfoBar(
std::unique_ptr<ConfirmInfoBarDelegate>(new TrkBar(url))
));
}

bool TrkBar::ShouldExpire(const NavigationDetails &) const
{
return false;
}

TrkBar::TrkBar(const GURL &url) :
ConfirmInfoBarDelegate(), m_url(url)
{
}

base::string16 TrkBar::GetMessageText(void) const
{
return base::ASCIIToUTF16("Loading traced URL: " + m_url.spec());
}

int TrkBar::GetButtons(void) const
{
return BUTTON_NONE;
}

infobars::InfoBarDelegate::InfoBarIdentifier TrkBar::GetIdentifier(void) const
{
return TRACKING_ALERT_INFOBAR_DELEGATE;
}

}; /* namespace content */
@@ -0,0 +1,33 @@
/*
* Copyright 2015 The Iridium Authors.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef IRIDIUM_TRKBAR_H
#define IRIDIUM_TRKBAR_H 1

#include "chrome/browser/infobars/infobar_service.h"
#include "components/infobars/core/confirm_infobar_delegate.h"
#include "url/gurl.h"

namespace content {

class TrkBar : public ConfirmInfoBarDelegate {
public:
static void Create(InfoBarService *, const GURL &);
bool ShouldExpire(const NavigationDetails &) const override;

private:
TrkBar(const GURL &);
base::string16 GetMessageText(void) const override;
int GetButtons(void) const override;
infobars::InfoBarDelegate::InfoBarIdentifier GetIdentifier(void) const override;

GURL m_url;
DISALLOW_COPY_AND_ASSIGN(TrkBar);
};

}; /* namespace content */

#endif /* IRIDIUM_TRKBAR_H */
@@ -0,0 +1,62 @@
/*
* Copyright 2015 The Iridium Authors.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#include <cstdio>
#ifdef __linux__
# include <unistd.h>
#endif
#include "base/task/post_task.h"
#include "base/task/task_traits.h"
#include "chrome/browser/infobars/infobar_service.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_finder.h"
#include "chrome/browser/ui/tabs/tab_strip_model.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/browser_task_traits.h"
#include "url/url_constants.h"
#include "iridium/trkbar.h"
#include "iridium/trknotify.h"

namespace iridium {

void log_url_request(const std::string &caller, const GURL &url)
{
#ifdef __linux__
bool tty = isatty(fileno(stderr));
#else
bool tty = false;
#endif
const char *xred = tty ? "\033[1;37;41m" : ""; // ]
const char *xfruit = tty ? "\033[33m" : ""; // ]
const char *xdark = tty ? "\033[1;30m" : ""; // ]
const char *xreset = tty ? "\033[0m" : ""; // ]

if (url.scheme() == url::kTraceScheme)
fprintf(stderr, "%s*** %s(%s)%s\n", xred, caller.c_str(),
url.possibly_invalid_spec().c_str(), xreset);
else
fprintf(stderr, "%s***%s %s(%s)%s\n", xfruit, xdark,
caller.c_str(), url.possibly_invalid_spec().c_str(),
xreset);
}

static void __trace_url_request(const std::string &caller, const GURL &url)
{
auto browser = chrome::FindLastActive();
if (browser == NULL)
return;

auto service = InfoBarService::FromWebContents(browser->tab_strip_model()->GetActiveWebContents());
content::TrkBar::Create(service, url);
}

void trace_url_request(const std::string &caller, const GURL &url)
{
base::PostTask(FROM_HERE, {content::BrowserThread::UI},
base::Bind(&__trace_url_request, caller, url));
}

}; /* namespace iridium */
@@ -0,0 +1,20 @@
/*
* Copyright 2015 The Iridium Authors.
*
* Use of this source code is governed by a BSD-style license that can be
* found in the LICENSE file.
*/
#ifndef IRIDIUM_TRKNOTIFY_H
#define IRIDIUM_TRKNOTIFY_H 1

#include <string>
#include "url/gurl.h"

namespace iridium {

extern void log_url_request(const std::string &, const GURL &);
extern void trace_url_request(const std::string &, const GURL &);

}; /* namespace iridium */

#endif /* IRIDIUM_TRKNOTIFY_H */
@@ -46,6 +46,8 @@ using std::string;

namespace net {

void (*trace_urlreq_cb)(const std::string &, const GURL &);

namespace {

// True once the first URLRequest was started.
@@ -592,6 +594,10 @@ URLRequest::URLRequest(const GURL& url,
// Sanity check out environment.
DCHECK(base::ThreadTaskRunnerHandle::IsSet());

if (trace_urlreq_cb != NULL)
(*trace_urlreq_cb)("URLRequest", url);
if (url.scheme() == url::kTraceScheme)
url_chain_[0] = url.strip_trk();
context->url_requests()->insert(this);
net_log_.BeginEvent(NetLogEventType::REQUEST_ALIVE, [&] {
return NetLogURLRequestConstructorParams(url, priority_,
@@ -960,6 +960,8 @@ class NET_EXPORT URLRequest : public base::SupportsUserData {
DISALLOW_COPY_AND_ASSIGN(URLRequest);
};

extern void NET_EXPORT (*trace_urlreq_cb)(const std::string &, const GURL &);

} // namespace net

#endif // NET_URL_REQUEST_URL_REQUEST_H_
<int value="93" label="TAB_SHARING_INFOBAR_DELEGATE"/>
<int value="94" label="SAFETY_TIP_INFOBAR_DELEGATE"/>
<int value="95" label="SMS_RECEIVER_INFOBAR_DELEGATE"/>
<int value="9001" label="TRACKING_ALERT_INFOBAR_DELEGATE"/>
</enum>

<enum name="InfoBarResponse">

0 comments on commit 8bc1e51

Please sign in to comment.
You can’t perform that action at this time.