Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(6157)

Unified Diff: chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc

Issue 2924723002: Network service: SafeBrowsing check for frame-resources from browser. (Closed)
Patch Set: . Created 3 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc
diff --git a/chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc b/chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc
index 8aed82731bc6c5db11d6c7ecb7cc61bc142ccb0d..67e38a72bf738ed6fbf73cbd5c02b7b39e18b59b 100644
--- a/chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc
+++ b/chrome/browser/safe_browsing/mojo_safe_browsing_impl.cc
@@ -7,10 +7,7 @@
#include <vector>
#include "base/memory/ptr_util.h"
-#include "base/memory/weak_ptr.h"
-#include "base/timer/timer.h"
-#include "chrome/browser/browser_process.h"
-#include "chrome/browser/prerender/prerender_contents.h"
+#include "chrome/browser/safe_browsing/safe_browsing_url_checker_impl.h"
#include "chrome/browser/safe_browsing/ui_manager.h"
#include "components/safe_browsing_db/database_manager.h"
#include "content/public/browser/browser_thread.h"
@@ -23,12 +20,6 @@
namespace safe_browsing {
namespace {
-// TODO(yzshen): Share such value with safe_browsing::BaseResourceThrottle.
-// Maximum time in milliseconds to wait for the SafeBrowsing service reputation
-// check. After this amount of time the outstanding check will be aborted, and
-// the resource will be treated as if it were safe.
-const int kCheckUrlTimeoutMs = 5000;
-
content::WebContents* GetWebContentsFromID(int render_process_id,
int render_frame_id) {
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
@@ -40,222 +31,23 @@ content::WebContents* GetWebContentsFromID(int render_process_id,
return content::WebContents::FromRenderFrameHost(render_frame_host);
}
-// TODO(yzshen): Handle the case where SafeBrowsing is not enabled, or
-// !database_manager()->IsSupported().
-// TODO(yzshen): Make sure it also works on Andorid.
-// TODO(yzshen): Do all the logging like what BaseResourceThrottle does.
-class SafeBrowsingUrlCheckerImpl : public mojom::SafeBrowsingUrlChecker,
- public SafeBrowsingDatabaseManager::Client {
+// This class wraps a base::OnceCallback<void(bool)> and runs it on destruction,
+// if it hasn't been run yet.
+class BooleanCallbackWrapper {
public:
- SafeBrowsingUrlCheckerImpl(
- int load_flags,
- content::ResourceType resource_type,
- scoped_refptr<SafeBrowsingDatabaseManager> database_manager,
- scoped_refptr<SafeBrowsingUIManager> ui_manager,
- int render_process_id,
- int render_frame_id)
- : load_flags_(load_flags),
- resource_type_(resource_type),
- render_process_id_(render_process_id),
- render_frame_id_(render_frame_id),
- database_manager_(std::move(database_manager)),
- ui_manager_(std::move(ui_manager)),
- weak_factory_(this) {
- DCHECK_NE(resource_type, content::RESOURCE_TYPE_MAIN_FRAME);
- DCHECK_NE(resource_type, content::RESOURCE_TYPE_SUB_FRAME);
- }
-
- ~SafeBrowsingUrlCheckerImpl() override {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
+ using BooleanCallback = base::OnceCallback<void(bool)>;
- if (state_ == STATE_CHECKING_URL)
- database_manager_->CancelCheck(this);
-
- for (size_t i = next_index_; i < callbacks_.size(); ++i)
- std::move(callbacks_[i]).Run(false);
+ explicit BooleanCallbackWrapper(BooleanCallback callback)
+ : callback_(std::move(callback)) {}
+ ~BooleanCallbackWrapper() {
+ if (callback_)
+ Run(false);
}
- // mojom::SafeBrowsingUrlChecker implementation.
- void CheckUrl(const GURL& url, CheckUrlCallback callback) override {
- DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
-
- DVLOG(1) << "SafeBrowsingUrlCheckerImpl checks URL: " << url;
- urls_.push_back(url);
- callbacks_.push_back(std::move(callback));
-
- ProcessUrls();
- }
+ void Run(bool value) { std::move(callback_).Run(value); }
private:
- // SafeBrowsingDatabaseManager::Client implementation:
- void OnCheckBrowseUrlResult(const GURL& url,
- SBThreatType threat_type,
- const ThreatMetadata& metadata) override {
- DCHECK_EQ(STATE_CHECKING_URL, state_);
- DCHECK_LT(next_index_, urls_.size());
- DCHECK_EQ(urls_[next_index_], url);
-
- timer_.Stop();
- if (threat_type == SB_THREAT_TYPE_SAFE) {
- state_ = STATE_NONE;
- std::move(callbacks_[next_index_]).Run(true);
- next_index_++;
- ProcessUrls();
- return;
- }
-
- if (load_flags_ & net::LOAD_PREFETCH) {
- BlockAndProcessUrls();
- return;
- }
-
- security_interstitials::UnsafeResource resource;
- resource.url = url;
- resource.original_url = urls_[0];
- if (urls_.size() > 1)
- resource.redirect_urls =
- std::vector<GURL>(urls_.begin() + 1, urls_.end());
- resource.is_subresource = true;
- resource.is_subframe = false;
- resource.threat_type = threat_type;
- resource.threat_metadata = metadata;
- resource.callback =
- base::Bind(&SafeBrowsingUrlCheckerImpl::OnBlockingPageComplete,
- weak_factory_.GetWeakPtr());
- resource.callback_thread = content::BrowserThread::GetTaskRunnerForThread(
- content::BrowserThread::IO);
- resource.web_contents_getter =
- base::Bind(&GetWebContentsFromID, render_process_id_, render_frame_id_);
- resource.threat_source = database_manager_->GetThreatSource();
-
- state_ = STATE_DISPLAYING_BLOCKING_PAGE;
-
- content::BrowserThread::PostTask(
- content::BrowserThread::UI, FROM_HERE,
- base::Bind(&SafeBrowsingUrlCheckerImpl::StartDisplayingBlockingPage,
- weak_factory_.GetWeakPtr(), ui_manager_, resource));
- }
-
- static void StartDisplayingBlockingPage(
- const base::WeakPtr<SafeBrowsingUrlCheckerImpl>& checker,
- scoped_refptr<BaseUIManager> ui_manager,
- const security_interstitials::UnsafeResource& resource) {
- content::WebContents* web_contents = resource.web_contents_getter.Run();
- if (web_contents) {
- prerender::PrerenderContents* prerender_contents =
- prerender::PrerenderContents::FromWebContents(web_contents);
- if (prerender_contents) {
- prerender_contents->Destroy(prerender::FINAL_STATUS_SAFE_BROWSING);
- } else {
- ui_manager->DisplayBlockingPage(resource);
- return;
- }
- }
-
- // Tab is gone or it's being prerendered.
- content::BrowserThread::PostTask(
- content::BrowserThread::IO, FROM_HERE,
- base::BindOnce(&SafeBrowsingUrlCheckerImpl::BlockAndProcessUrls,
- checker));
- }
-
- void OnCheckUrlTimeout() {
- database_manager_->CancelCheck(this);
-
- OnCheckBrowseUrlResult(urls_[next_index_],
- safe_browsing::SB_THREAT_TYPE_SAFE,
- ThreatMetadata());
- }
-
- void ProcessUrls() {
- DCHECK_NE(STATE_BLOCKED, state_);
-
- if (state_ == STATE_CHECKING_URL ||
- state_ == STATE_DISPLAYING_BLOCKING_PAGE) {
- return;
- }
-
- while (next_index_ < urls_.size()) {
- DCHECK_EQ(STATE_NONE, state_);
- // TODO(yzshen): Consider moving CanCheckResourceType() to the renderer
- // side. That would save some IPCs. It requires a method on the
- // SafeBrowsing mojo interface to query all supported resource types.
- if (!database_manager_->CanCheckResourceType(resource_type_) ||
- database_manager_->CheckBrowseUrl(urls_[next_index_], this)) {
- std::move(callbacks_[next_index_]).Run(true);
- next_index_++;
- continue;
- }
-
- state_ = STATE_CHECKING_URL;
- // Start a timer to abort the check if it takes too long.
- timer_.Start(FROM_HERE,
- base::TimeDelta::FromMilliseconds(kCheckUrlTimeoutMs), this,
- &SafeBrowsingUrlCheckerImpl::OnCheckUrlTimeout);
-
- break;
- }
- }
-
- void BlockAndProcessUrls() {
- DVLOG(1) << "SafeBrowsingUrlCheckerImpl blocks URL: " << urls_[next_index_];
- state_ = STATE_BLOCKED;
-
- // If user decided to not proceed through a warning, mark all the remaining
- // redirects as "bad".
- for (; next_index_ < callbacks_.size(); ++next_index_)
- std::move(callbacks_[next_index_]).Run(false);
- }
-
- void OnBlockingPageComplete(bool proceed) {
- DCHECK_EQ(STATE_DISPLAYING_BLOCKING_PAGE, state_);
-
- if (proceed) {
- state_ = STATE_NONE;
- std::move(callbacks_[next_index_]).Run(true);
- next_index_++;
- ProcessUrls();
- } else {
- BlockAndProcessUrls();
- }
- }
-
- enum State {
- // Haven't started checking or checking is complete.
- STATE_NONE,
- // We have one outstanding URL-check.
- STATE_CHECKING_URL,
- // We're displaying a blocking page.
- STATE_DISPLAYING_BLOCKING_PAGE,
- // The blocking page has returned *not* to proceed.
- STATE_BLOCKED
- };
-
- const int load_flags_;
- const content::ResourceType resource_type_;
- const int render_process_id_;
- const int render_frame_id_;
- scoped_refptr<SafeBrowsingDatabaseManager> database_manager_;
- scoped_refptr<BaseUIManager> ui_manager_;
-
- // The redirect chain for this resource, including the original URL and
- // subsequent redirect URLs.
- std::vector<GURL> urls_;
- // Callbacks corresponding to |urls_| to report check results. |urls_| and
- // |callbacks_| are always of the same size.
- std::vector<CheckUrlCallback> callbacks_;
- // |urls_| before |next_index_| have been checked. If |next_index_| is smaller
- // than the size of |urls_|, the URL at |next_index_| is being processed.
- size_t next_index_ = 0;
-
- State state_ = STATE_NONE;
-
- // Timer to abort the SafeBrowsing check if it takes too long.
- base::OneShotTimer timer_;
-
- base::WeakPtrFactory<SafeBrowsingUrlCheckerImpl> weak_factory_;
-
- DISALLOW_COPY_AND_ASSIGN(SafeBrowsingUrlCheckerImpl);
+ BooleanCallback callback_;
};
} // namespace
@@ -296,8 +88,14 @@ void MojoSafeBrowsingImpl::CreateCheckerAndCheck(
DCHECK_CURRENTLY_ON(content::BrowserThread::IO);
auto checker_impl = base::MakeUnique<SafeBrowsingUrlCheckerImpl>(
static_cast<int>(load_flags), resource_type, database_manager_,
- ui_manager_, render_process_id_, static_cast<int>(render_frame_id));
- checker_impl->CheckUrl(url, std::move(callback));
+ ui_manager_,
+ base::Bind(&GetWebContentsFromID, render_process_id_,
+ static_cast<int>(render_frame_id)));
+
+ checker_impl->CheckUrl(
+ url, base::BindOnce(
+ &BooleanCallbackWrapper::Run,
+ base::Owned(new BooleanCallbackWrapper(std::move(callback)))));
mojo::MakeStrongBinding(std::move(checker_impl), std::move(request));
}

Powered by Google App Engine
This is Rietveld 408576698