diff options
author | idanan@google.com <idanan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-01 14:00:02 +0000 |
---|---|---|
committer | idanan@google.com <idanan@google.com@0039d316-1c4b-4281-b951-d872f2087c98> | 2009-10-01 14:00:02 +0000 |
commit | e3d2b690d1e9294050376e73c1a9b5c87dcd47ec (patch) | |
tree | 54899b7fa379e1eee4841cf2ef017e6a3a59d68a /chrome/browser | |
parent | d64b54376d74e8759b764d2f34c85d7377cb44ab (diff) | |
download | chromium_src-e3d2b690d1e9294050376e73c1a9b5c87dcd47ec.zip chromium_src-e3d2b690d1e9294050376e73c1a9b5c87dcd47ec.tar.gz chromium_src-e3d2b690d1e9294050376e73c1a9b5c87dcd47ec.tar.bz2 |
Privacy Blacklist Unblock
Summary
-------
Mostly implemented the unblocking for visual resources for the Privacy Blacklist.
Merging now before I leave. Eveything here only has effect if the --privacy-blacklist
flag specifies a Privacy Blacklist.
Detailed Changes
----------------
[chrome/browser/resources/privacy_blacklist.html]
- Replaced the about:blank place-holder with variable to set the unblock link.
- Open the Privacy Blacklist provider page in a new tab. This works around an
issue where such request for a full-page (rather than a sub-resource) gets
blocked indefinitely.
[chrome/browser/render_host/resource_dispatcher_host.h]
- Added a BlockedResponse member which is now a class rather than a namespace,
see below for more information.
[chrome/browser/render_host/resource_dispatcher_host.cc]
- Generate headers for the blocked response to redirect to the chrome-blocked URL
which prevents an enclosing page from reading the URL of the unblock link. This
was suggested by Darin to avoid scripted bypassing of blocked contents.
- Recover the original URL for blocked content, in order to fetch it during
unblocking.
- Do not create CrossSiteResourceHandler when an unblocked link is requested.
Otherwise the request never resumes as the blocked page never gets closed
since it is not a real page.
[chrome/browser/privacy_blacklist/blocked_response.cc]
- Defined chrome-block and chrome-unblock URL schemes. The block scheme is used
to return the blocked response. The unblock scheme is used request a blocked
resource's URL without being intercepted by the Privacy Blacklist.
- Defined a hash function for a blocked resource as its address in memory.
Function to reverse the hash is therefore trivial.
- Added a function to return headers for a blocked response.
- Added a function to generate a block URL from a requested one.
- Added a function to get an unblock URL from a requested one.
- Added a function to return the original URL for a blocked one.
[chrome/browser/privacy_blacklist/blocked_response.h]
- Made the BlockedResponse namespace into a class.
- Created a member set to keep all the blocked resources URL.
BUG=16932
TEST=none
TBR=darin
Review URL: http://codereview.chromium.org/252001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@27719 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser')
5 files changed, 115 insertions, 24 deletions
diff --git a/chrome/browser/privacy_blacklist/blocked_response.cc b/chrome/browser/privacy_blacklist/blocked_response.cc index 228886a..b4e94d9 100644 --- a/chrome/browser/privacy_blacklist/blocked_response.cc +++ b/chrome/browser/privacy_blacklist/blocked_response.cc @@ -7,15 +7,34 @@ #include "app/l10n_util.h" #include "app/resource_bundle.h" #include "base/logging.h" +#include "base/string_util.h" #include "base/values.h" #include "chrome/browser/privacy_blacklist/blacklist.h" #include "chrome/common/jstemplate_builder.h" +#include "chrome/common/url_constants.h" #include "grit/browser_resources.h" #include "grit/generated_resources.h" -namespace BlockedResponse { +namespace { -std::string GetHTML(const Blacklist::Match* match) { +unsigned long Hash(std::set<std::string>::iterator i) { + return (unsigned long)(i.operator->()); +} + +std::string Dehash(unsigned long l) { + return *(std::string*)l; +} + +} + +namespace chrome { + +const char kUnblockScheme[] = "chrome-unblock"; + +const char kBlockScheme[] = "chrome-block"; + +std::string BlockedResponse::GetHTML(const std::string& url, + const Blacklist::Match* match) { DictionaryValue strings; strings.SetString(L"title", l10n_util::GetString(IDS_BLACKLIST_TITLE)); strings.SetString(L"message", l10n_util::GetString(IDS_BLACKLIST_MESSAGE)); @@ -39,15 +58,47 @@ std::string GetHTML(const Blacklist::Match* match) { strings.SetString(L"name", entry->provider()->name()); strings.SetString(L"url", entry->provider()->url()); + strings.SetString(L"bypass", GetUnblockedURL(url)); const base::StringPiece html = ResourceBundle::GetSharedInstance().GetRawDataResource(IDR_BLACKLIST_HTML); return jstemplate_builder::GetI18nTemplateHtml(html, &strings); } -std::string GetImage(const Blacklist::Match*) { +std::string BlockedResponse::GetImage(const Blacklist::Match*) { return ResourceBundle::GetSharedInstance(). GetDataResource(IDR_BLACKLIST_IMAGE); } -} // namespace BlockedResponse +std::string BlockedResponse::GetHeaders(const std::string& url) { + return + "HTTP/1.1 200 OK\nContent-Type: text/html\nlocation: " + + GetBlockedURL(url) + "\n" + "Cache-Control: no-store"; +} + +std::string BlockedResponse::GetBlockedURL(const std::string& url) { + return std::string(kBlockScheme) + "://" + url; +} + +std::string BlockedResponse::GetUnblockedURL(const std::string& url) { + std::set<std::string>::iterator i = blocked_.insert(blocked_.end(), url); + + char buf[64]; + base::snprintf(buf, 64, "%s://%lX", kUnblockScheme, Hash(i)); + return buf; +} + +std::string BlockedResponse::GetOriginalURL(const std::string& url) { + unsigned long l = 0; + + // Read the address of the url. + if (sscanf(url.c_str() + sizeof(kUnblockScheme) + 2, "%lX", &l)) { + std::size_t p = url.find('/', sizeof(kUnblockScheme) + 2); + if (p != std::string::npos) + return Dehash(l) + url.substr(p+1); + return Dehash(l); + } + return chrome::kAboutBlankURL; +} + +} // end namespace chrome diff --git a/chrome/browser/privacy_blacklist/blocked_response.h b/chrome/browser/privacy_blacklist/blocked_response.h index 1a770e4..a9e57bd 100644 --- a/chrome/browser/privacy_blacklist/blocked_response.h +++ b/chrome/browser/privacy_blacklist/blocked_response.h @@ -6,24 +6,52 @@ #define CHROME_BROWSER_PRIVACY_BLACKLIST_BLOCKED_RESPONSE_H_ #include <string> +#include <set> #include "chrome/browser/privacy_blacklist/blacklist.h" +namespace chrome { + +extern const char kUnblockScheme[]; +extern const char kBlockScheme[]; + // Generate localized responses to replace blacklisted resources. // Blacklisted resources such as frames and iframes are replaced // by HTML. Non visual resources such as Javascript and CSS are // simply be cancelled so there is no blocked response for them. -namespace BlockedResponse { +class BlockedResponse { + public: + BlockedResponse() {}; + + // Returns the HTML document used as substituted content for blacklisted + // elements. + std::string GetHTML(const std::string& url, const Blacklist::Match* match); + + // Returns the image (as a string because that is what is expected by callers) + // used as substituted content for blacklisted elements. + std::string GetImage(const Blacklist::Match* match); + + // Returns HTTP headers for a blocked response replacing the given url. + std::string GetHeaders(const std::string& url); + + // Gets the original url of a blocked resource from its blocked url. + // The input must be a chome-unblock://XXX url. If the unblock url is + // not found, then about:blank is returned. + std::string GetOriginalURL(const std::string& url); + + private: + // Returns a chrome-block://XXX link for the given requested URL. + std::string GetBlockedURL(const std::string& url); + + // Returns a chrome-unblock://XXX link for the given chrome-block://YYY url. + std::string GetUnblockedURL(const std::string& url); -// Returns the HTML document used as substituted content for blacklisted -// elements. -std::string GetHTML(const Blacklist::Match* match); + std::set<std::string> blocked_; -// Returns the image (as a string because that is what is expected by callers) -// used as substituted content for blacklisted elements. -std::string GetImage(const Blacklist::Match* match); + DISALLOW_COPY_AND_ASSIGN(BlockedResponse); +}; -} // namespace BlockedResponse +} #endif // CHROME_BROWSER_PRIVACY_BLACKLIST_BLOCKED_RESPONSE_H_ diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.cc b/chrome/browser/renderer_host/resource_dispatcher_host.cc index 60e42b9..e1d89fe 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.cc +++ b/chrome/browser/renderer_host/resource_dispatcher_host.cc @@ -29,7 +29,6 @@ #include "chrome/browser/net/url_request_tracking.h" #include "chrome/browser/plugin_service.h" #include "chrome/browser/privacy_blacklist/blacklist.h" -#include "chrome/browser/privacy_blacklist/blocked_response.h" #include "chrome/browser/profile.h" #include "chrome/browser/renderer_host/async_resource_handler.h" #include "chrome/browser/renderer_host/buffered_resource_handler.h" @@ -425,6 +424,7 @@ void ResourceDispatcherHost::BeginRequest( } return; } + std::string url = request_data.url.spec(); // Note that context can still be NULL here when running unit tests. Blacklist::Match* match = context && context->blacklist() ? @@ -438,7 +438,8 @@ void ResourceDispatcherHost::BeginRequest( URLRequestStatus status(URLRequestStatus::SUCCESS, 0); std::string data = request_data.resource_type != ResourceType::SUB_RESOURCE ? - BlockedResponse::GetHTML(match) : BlockedResponse::GetImage(match); + blocked_.GetHTML(url, match) : blocked_.GetImage(match); + std::string headers = blocked_.GetHeaders(url); if (sync_result) { SyncLoadResult result; @@ -460,6 +461,7 @@ void ResourceDispatcherHost::BeginRequest( header.mime_type = "text/html"; header.content_length = -1; header.status = status; + header.headers = new net::HttpResponseHeaders(headers); receiver_->Send(new ViewMsg_Resource_ReceivedResponse( route_id, request_id, header)); receiver_->Send(new ViewMsg_Resource_DataReceived( @@ -482,6 +484,10 @@ void ResourceDispatcherHost::BeginRequest( return; } + // To fetch a blocked resource, convert the unblock URL to the original one. + GURL gurl = request_data.url.scheme() != chrome::kUnblockScheme ? + request_data.url : GURL(blocked_.GetOriginalURL(url)); + // Ensure the Chrome plugins are loaded, as they may intercept network // requests. Does nothing if they are already loaded. // TODO(mpcomplete): This takes 200 ms! Investigate parallelizing this by @@ -491,24 +497,24 @@ void ResourceDispatcherHost::BeginRequest( // Construct the event handler. scoped_refptr<ResourceHandler> handler; if (sync_result) { - handler = new SyncResourceHandler(receiver_, request_data.url, sync_result); + handler = new SyncResourceHandler(receiver_, gurl, sync_result); } else { handler = new AsyncResourceHandler(receiver_, child_id, route_id, receiver_->handle(), - request_data.url, + gurl, this); } if (HandleExternalProtocol(request_id, child_id, route_id, - request_data.url, request_data.resource_type, + gurl, request_data.resource_type, handler)) { return; } // Construct the request. - URLRequest* request = new URLRequest(request_data.url, this); + URLRequest* request = new URLRequest(gurl, this); if (match) { request->SetUserData(&Blacklist::kRequestDataKey, match); } @@ -550,8 +556,10 @@ void ResourceDispatcherHost::BeginRequest( // Install a CrossSiteResourceHandler if this request is coming from a // RenderViewHost with a pending cross-site request. We only check this for - // MAIN_FRAME requests. - if (request_data.resource_type == ResourceType::MAIN_FRAME && + // MAIN_FRAME requests. Unblock requests only come from a blocked page, do + // not count as cross-site, otherwise it gets blocked indefinitely. + if (request_data.url.scheme() != chrome::kUnblockScheme && + request_data.resource_type == ResourceType::MAIN_FRAME && process_type == ChildProcessInfo::RENDER_PROCESS && Singleton<CrossSiteRequestManager>::get()-> HasPendingCrossSiteRequest(child_id, route_id)) { @@ -564,11 +572,11 @@ void ResourceDispatcherHost::BeginRequest( } if (safe_browsing_->enabled() && - safe_browsing_->CanCheckUrl(request_data.url)) { + safe_browsing_->CanCheckUrl(gurl)) { handler = new SafeBrowsingResourceHandler(handler, child_id, route_id, - request_data.url, + gurl, request_data.resource_type, safe_browsing_, this, diff --git a/chrome/browser/renderer_host/resource_dispatcher_host.h b/chrome/browser/renderer_host/resource_dispatcher_host.h index fc86453..3a2c2a7 100644 --- a/chrome/browser/renderer_host/resource_dispatcher_host.h +++ b/chrome/browser/renderer_host/resource_dispatcher_host.h @@ -23,6 +23,7 @@ #include "base/timer.h" #include "chrome/browser/renderer_host/resource_handler.h" #include "chrome/common/child_process_info.h" +#include "chrome/browser/privacy_blacklist/blocked_response.h" #include "ipc/ipc_message.h" #include "net/url_request/url_request.h" #include "webkit/glue/resource_type.h" @@ -477,6 +478,9 @@ class ResourceDispatcherHost : public URLRequest::Delegate { // to the source of the message. Receiver* receiver_; + // Keeps track of elements blocked by the Privacy Blacklist. + chrome::BlockedResponse blocked_; + static bool g_is_http_prioritization_enabled; DISALLOW_COPY_AND_ASSIGN(ResourceDispatcherHost); diff --git a/chrome/browser/resources/privacy_blacklist_block.html b/chrome/browser/resources/privacy_blacklist_block.html index 4b4c58c..1676ef9 100644 --- a/chrome/browser/resources/privacy_blacklist_block.html +++ b/chrome/browser/resources/privacy_blacklist_block.html @@ -35,9 +35,9 @@ body { <div class="icon"><img src="phishing_icon.png" alt="Blocked Element Icon"/></div> <p i18n-content="message"></p> <ul style="list-style-type: none"> - <li><a i18n-values="href: url" i18n-content="name" target="_top"></a></li> + <li><a i18n-values="href: url" i18n-content="name" target="_blank"></a></li> </ul> - <p><a href="about:blank" i18n-content="unblock"></a></p> + <p><a i18n-values="href: bypass" i18n-content="unblock"></a></p> </div> </td> </table> |