summaryrefslogtreecommitdiffstats
path: root/chrome/browser
diff options
context:
space:
mode:
authoridanan@google.com <idanan@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 14:00:02 +0000
committeridanan@google.com <idanan@google.com@0039d316-1c4b-4281-b951-d872f2087c98>2009-10-01 14:00:02 +0000
commite3d2b690d1e9294050376e73c1a9b5c87dcd47ec (patch)
tree54899b7fa379e1eee4841cf2ef017e6a3a59d68a /chrome/browser
parentd64b54376d74e8759b764d2f34c85d7377cb44ab (diff)
downloadchromium_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')
-rw-r--r--chrome/browser/privacy_blacklist/blocked_response.cc59
-rw-r--r--chrome/browser/privacy_blacklist/blocked_response.h44
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.cc28
-rw-r--r--chrome/browser/renderer_host/resource_dispatcher_host.h4
-rw-r--r--chrome/browser/resources/privacy_blacklist_block.html4
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>