[WebView] Remove content relationship verification code
Bug: 1454473 Change-Id: Ib25c2114f9b92e6160db86498f520f9276f46ecd Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4608053 Reviewed-by: Bo Liu <boliu@chromium.org> Commit-Queue: Susanne Westphal <swestphal@chromium.org> Reviewed-by: Colin Blundell <blundell@chromium.org> Reviewed-by: Richard Coles <torne@chromium.org> Reviewed-by: Philip Rogers <pdr@chromium.org> Cr-Commit-Position: refs/heads/main@{#1158928}
This commit is contained in:

committed by
Chromium LUCI CQ

parent
b99b22261f
commit
334d01268d
android_webview
BUILD.gn
browser
BUILD.gnDEPSaw_content_browser_client.ccaw_settings.ccaw_settings.h
content_relationship_verification
glue
java
src
com
android
webview
chromium
java
DEPS
src
javatests
src
org
chromium
android_webview
junit
support_library
boundary_interfaces
src
org
chromium
support_lib_boundary
java
src
org
chromium
test
ui
components
android_system_error_page
content_relationship_verification
BUILD.gnDEPScontent_relationship_verification_constants.cccontent_relationship_verification_constants.h
resources
content/browser/devtools/protocol
third_party/blink
public
renderer
tools/metrics/histograms
@ -472,7 +472,6 @@ generate_jni("browser_jni_headers") {
|
||||
"java/src/org/chromium/android_webview/AwDevToolsServer.java",
|
||||
"java/src/org/chromium/android_webview/AwFeatureMap.java",
|
||||
"java/src/org/chromium/android_webview/AwHttpAuthHandler.java",
|
||||
"java/src/org/chromium/android_webview/AwOriginVerificationSchedulerBridge.java",
|
||||
"java/src/org/chromium/android_webview/AwPacProcessor.java",
|
||||
"java/src/org/chromium/android_webview/AwPdfExporter.java",
|
||||
"java/src/org/chromium/android_webview/AwProxyController.java",
|
||||
@ -536,9 +535,6 @@ android_library("browser_java") {
|
||||
"java/src/org/chromium/android_webview/AwKeyboardShortcuts.java",
|
||||
"java/src/org/chromium/android_webview/AwLayoutSizer.java",
|
||||
"java/src/org/chromium/android_webview/AwNetworkChangeNotifierRegistrationPolicy.java",
|
||||
"java/src/org/chromium/android_webview/AwOriginVerificationScheduler.java",
|
||||
"java/src/org/chromium/android_webview/AwOriginVerificationSchedulerBridge.java",
|
||||
"java/src/org/chromium/android_webview/AwOriginVerifier.java",
|
||||
"java/src/org/chromium/android_webview/AwPacProcessor.java",
|
||||
"java/src/org/chromium/android_webview/AwPdfExporter.java",
|
||||
"java/src/org/chromium/android_webview/AwPrintDocumentAdapter.java",
|
||||
@ -554,7 +550,6 @@ android_library("browser_java") {
|
||||
"java/src/org/chromium/android_webview/AwSupportLibIsomorphic.java",
|
||||
"java/src/org/chromium/android_webview/AwThreadUtils.java",
|
||||
"java/src/org/chromium/android_webview/AwTracingController.java",
|
||||
"java/src/org/chromium/android_webview/AwVerificationResultStore.java",
|
||||
"java/src/org/chromium/android_webview/AwViewAndroidDelegate.java",
|
||||
"java/src/org/chromium/android_webview/AwViewMethods.java",
|
||||
"java/src/org/chromium/android_webview/AwWebContentsDelegate.java",
|
||||
@ -634,7 +629,6 @@ android_library("browser_java") {
|
||||
"//components/background_task_scheduler:background_task_scheduler_task_ids_java",
|
||||
"//components/component_updater/android:embedded_component_loader_java",
|
||||
"//components/content_capture/android:java",
|
||||
"//components/content_relationship_verification/android:java",
|
||||
"//components/crash/android:handler_java",
|
||||
"//components/crash/android:java",
|
||||
"//components/embedder_support/android:util_java",
|
||||
@ -657,7 +651,6 @@ android_library("browser_java") {
|
||||
"//mojo/public/java:system_java",
|
||||
"//mojo/public/java/system:system_impl_java",
|
||||
"//net/android:net_java",
|
||||
"//services/data_decoder/public/cpp/android:safe_json_java",
|
||||
"//services/network/public/mojom:mojom_java",
|
||||
"//services/network/public/mojom:url_loader_base_java",
|
||||
"//third_party/android_deps:protobuf_lite_runtime_java",
|
||||
|
@ -121,10 +121,6 @@ source_set("browser") {
|
||||
"component_updater/registration.h",
|
||||
"component_updater/trust_token_key_commitments_component_loader.cc",
|
||||
"component_updater/trust_token_key_commitments_component_loader.h",
|
||||
"content_relationship_verification/aw_origin_verification_scheduler_bridge.cc",
|
||||
"content_relationship_verification/aw_origin_verification_scheduler_bridge.h",
|
||||
"content_relationship_verification/browser_url_loader_throttle.cc",
|
||||
"content_relationship_verification/browser_url_loader_throttle.h",
|
||||
"cookie_manager.cc",
|
||||
"cookie_manager.h",
|
||||
"enterprise_authentication_app_link_policy_handler.cc",
|
||||
@ -238,7 +234,6 @@ source_set("browser") {
|
||||
"//components/url_matcher",
|
||||
|
||||
# Called via JNI in CrashpadMain
|
||||
"//components/content_relationship_verification",
|
||||
"//components/crash/android:crashpad_main",
|
||||
"//components/crash/content/browser",
|
||||
"//components/crash/core/app",
|
||||
|
@ -15,7 +15,6 @@ include_rules = [
|
||||
"+components/cdm/browser",
|
||||
"+components/component_updater/android",
|
||||
"+components/component_updater/installer_policies",
|
||||
"+components/content_relationship_verification",
|
||||
"+components/crash/content/browser",
|
||||
"+components/crash/core",
|
||||
"+components/download/public/common",
|
||||
@ -112,7 +111,6 @@ include_rules = [
|
||||
"+third_party/blink/public/common/storage_key/storage_key.h",
|
||||
"+third_party/blink/public/common/user_agent/user_agent_metadata.h",
|
||||
"+third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h",
|
||||
"+third_party/blink/public/platform/resource_request_blocked_reason.h",
|
||||
"+third_party/crashpad/crashpad/client",
|
||||
"+third_party/crashpad/crashpad/util",
|
||||
"+third_party/zlib/google/compression_utils.h",
|
||||
|
@ -24,7 +24,6 @@
|
||||
#include "android_webview/browser/aw_settings.h"
|
||||
#include "android_webview/browser/aw_speech_recognition_manager_delegate.h"
|
||||
#include "android_webview/browser/aw_web_contents_view_delegate.h"
|
||||
#include "android_webview/browser/content_relationship_verification/aw_origin_verification_scheduler_bridge.h"
|
||||
#include "android_webview/browser/cookie_manager.h"
|
||||
#include "android_webview/browser/network_service/aw_proxy_config_monitor.h"
|
||||
#include "android_webview/browser/network_service/aw_proxying_restricted_cookie_manager.h"
|
||||
@ -596,19 +595,6 @@ AwContentBrowserClient::CreateURLLoaderThrottles(
|
||||
DCHECK_CURRENTLY_ON(BrowserThread::UI);
|
||||
|
||||
std::vector<std::unique_ptr<blink::URLLoaderThrottle>> result;
|
||||
|
||||
content::WebContents* web_contents = wc_getter.Run();
|
||||
AwSettings* aw_settings = AwSettings::FromWebContents(web_contents);
|
||||
if (request.is_outermost_main_frame &&
|
||||
((aw_settings && aw_settings->GetRestrictSensitiveWebContentEnabled()) ||
|
||||
base::FeatureList::IsEnabled(
|
||||
features::kWebViewRestrictSensitiveContent))) {
|
||||
auto* origin_verification_bridge =
|
||||
AwOriginVerificationSchedulerBridge::GetInstance();
|
||||
result.push_back(
|
||||
BrowserURLLoaderThrottle::Create(origin_verification_bridge));
|
||||
}
|
||||
|
||||
result.push_back(safe_browsing::BrowserURLLoaderThrottle::Create(
|
||||
base::BindOnce(
|
||||
[](AwContentBrowserClient* client) {
|
||||
|
@ -638,17 +638,6 @@ AwSettings::UpdateXRequestedWithAllowListOriginMatcher(
|
||||
return base::android::ToJavaArrayOfStrings(env, bad_rules);
|
||||
}
|
||||
|
||||
void AwSettings::SetRestrictSensitiveWebContentEnabled(
|
||||
JNIEnv* env,
|
||||
const JavaParamRef<jobject>& obj,
|
||||
jboolean enabled) {
|
||||
restrict_sensitive_web_content_enabled_ = enabled;
|
||||
}
|
||||
|
||||
bool AwSettings::GetRestrictSensitiveWebContentEnabled() {
|
||||
return restrict_sensitive_web_content_enabled();
|
||||
}
|
||||
|
||||
scoped_refptr<AwContentsOriginMatcher> AwSettings::xrw_allowlist_matcher() {
|
||||
return xrw_allowlist_matcher_;
|
||||
}
|
||||
|
@ -127,15 +127,6 @@ class AwSettings : public content::WebContentsObserver {
|
||||
return enterprise_authentication_app_link_policy_enabled_;
|
||||
}
|
||||
|
||||
void SetRestrictSensitiveWebContentEnabled(
|
||||
JNIEnv* env,
|
||||
const base::android::JavaParamRef<jobject>& obj,
|
||||
jboolean enabled);
|
||||
bool GetRestrictSensitiveWebContentEnabled();
|
||||
inline bool restrict_sensitive_web_content_enabled() {
|
||||
return restrict_sensitive_web_content_enabled_;
|
||||
}
|
||||
|
||||
base::android::ScopedJavaLocalRef<jobjectArray>
|
||||
UpdateXRequestedWithAllowListOriginMatcher(
|
||||
JNIEnv* env,
|
||||
@ -159,7 +150,6 @@ class AwSettings : public content::WebContentsObserver {
|
||||
// TODO(b/222053757,ayushsha): Change this policy to be by
|
||||
// default false from next Android version(Maybe Android U).
|
||||
bool enterprise_authentication_app_link_policy_enabled_{true};
|
||||
bool restrict_sensitive_web_content_enabled_{false};
|
||||
MixedContentMode mixed_content_mode_;
|
||||
|
||||
scoped_refptr<AwContentsOriginMatcher> xrw_allowlist_matcher_;
|
||||
|
@ -1,4 +0,0 @@
|
||||
file://components/content_relationship_verification/OWNERS
|
||||
|
||||
rayankans@chromium.org
|
||||
swestphal@chromium.org
|
44
android_webview/browser/content_relationship_verification/aw_origin_verification_scheduler_bridge.cc
44
android_webview/browser/content_relationship_verification/aw_origin_verification_scheduler_bridge.cc
@ -1,44 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "android_webview/browser/content_relationship_verification/aw_origin_verification_scheduler_bridge.h"
|
||||
|
||||
#include <string>
|
||||
#include "android_webview/browser_jni_headers/AwOriginVerificationSchedulerBridge_jni.h"
|
||||
#include "base/android/jni_android.h"
|
||||
#include "base/android/jni_string.h"
|
||||
#include "base/no_destructor.h"
|
||||
|
||||
namespace android_webview {
|
||||
|
||||
// static
|
||||
AwOriginVerificationSchedulerBridge*
|
||||
AwOriginVerificationSchedulerBridge::GetInstance() {
|
||||
static base::NoDestructor<AwOriginVerificationSchedulerBridge> instance;
|
||||
return instance.get();
|
||||
}
|
||||
|
||||
void AwOriginVerificationSchedulerBridge::Verify(
|
||||
std::string url,
|
||||
OriginVerifierCallback callback) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
|
||||
JNIEnv* env = base::android::AttachCurrentThread();
|
||||
intptr_t callback_id = reinterpret_cast<intptr_t>(
|
||||
new OriginVerifierCallback(std::move(callback)));
|
||||
|
||||
auto j_url = base::android::ConvertUTF8ToJavaString(env, url);
|
||||
Java_AwOriginVerificationSchedulerBridge_verify(env, j_url, callback_id);
|
||||
}
|
||||
|
||||
static void JNI_AwOriginVerificationSchedulerBridge_OnVerificationResult(
|
||||
JNIEnv* env,
|
||||
jlong callback_id,
|
||||
jboolean verified) {
|
||||
std::unique_ptr<OriginVerifierCallback> cb(
|
||||
reinterpret_cast<OriginVerifierCallback*>(callback_id));
|
||||
std::move(*cb).Run(verified);
|
||||
}
|
||||
|
||||
} // namespace android_webview
|
38
android_webview/browser/content_relationship_verification/aw_origin_verification_scheduler_bridge.h
38
android_webview/browser/content_relationship_verification/aw_origin_verification_scheduler_bridge.h
@ -1,38 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ANDROID_WEBVIEW_BROWSER_CONTENT_RELATIONSHIP_VERIFICATION_AW_ORIGIN_VERIFICATION_SCHEDULER_BRIDGE_H_
|
||||
#define ANDROID_WEBVIEW_BROWSER_CONTENT_RELATIONSHIP_VERIFICATION_AW_ORIGIN_VERIFICATION_SCHEDULER_BRIDGE_H_
|
||||
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/no_destructor.h"
|
||||
|
||||
#include "android_webview/browser/content_relationship_verification/browser_url_loader_throttle.h"
|
||||
|
||||
namespace android_webview {
|
||||
using OriginVerifierCallback = base::OnceCallback<void(bool /*verified*/)>;
|
||||
|
||||
// Lifetime: Singleton
|
||||
class AwOriginVerificationSchedulerBridge
|
||||
: public BrowserURLLoaderThrottle::OriginVerificationSchedulerBridge {
|
||||
public:
|
||||
static AwOriginVerificationSchedulerBridge* GetInstance();
|
||||
|
||||
AwOriginVerificationSchedulerBridge(
|
||||
const AwOriginVerificationSchedulerBridge&) = delete;
|
||||
AwOriginVerificationSchedulerBridge& operator=(
|
||||
const AwOriginVerificationSchedulerBridge&) = delete;
|
||||
|
||||
void Verify(std::string url, OriginVerifierCallback callback) override;
|
||||
|
||||
private:
|
||||
AwOriginVerificationSchedulerBridge() = default;
|
||||
~AwOriginVerificationSchedulerBridge() override = default;
|
||||
|
||||
friend class base::NoDestructor<AwOriginVerificationSchedulerBridge>;
|
||||
};
|
||||
|
||||
} // namespace android_webview
|
||||
|
||||
#endif // ANDROID_WEBVIEW_BROWSER_CONTENT_RELATIONSHIP_VERIFICATION_AW_ORIGIN_VERIFICATION_SCHEDULER_BRIDGE_H_
|
@ -1,141 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "android_webview/browser/content_relationship_verification/browser_url_loader_throttle.h"
|
||||
|
||||
#include "base/android/build_info.h"
|
||||
#include "base/check_op.h"
|
||||
#include "base/functional/bind.h"
|
||||
#include "base/memory/ptr_util.h"
|
||||
#include "base/metrics/histogram_functions.h"
|
||||
#include "base/trace_event/trace_event.h"
|
||||
#include "components/content_relationship_verification/content_relationship_verification_constants.h"
|
||||
#include "components/content_relationship_verification/response_header_verifier.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "net/log/net_log_event_type.h"
|
||||
#include "net/url_request/redirect_info.h"
|
||||
#include "services/network/public/cpp/resource_request.h"
|
||||
#include "services/network/public/mojom/fetch_api.mojom.h"
|
||||
#include "services/network/public/mojom/url_response_head.mojom.h"
|
||||
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
|
||||
|
||||
using content_relationship_verification::ResponseHeaderVerificationResult;
|
||||
|
||||
namespace android_webview {
|
||||
|
||||
BrowserURLLoaderThrottle::OriginVerificationSchedulerBridge::
|
||||
OriginVerificationSchedulerBridge() = default;
|
||||
BrowserURLLoaderThrottle::OriginVerificationSchedulerBridge::
|
||||
~OriginVerificationSchedulerBridge() = default;
|
||||
|
||||
// static
|
||||
std::unique_ptr<BrowserURLLoaderThrottle> BrowserURLLoaderThrottle::Create(
|
||||
OriginVerificationSchedulerBridge* bridge) {
|
||||
return base::WrapUnique<BrowserURLLoaderThrottle>(
|
||||
new BrowserURLLoaderThrottle(bridge));
|
||||
}
|
||||
|
||||
BrowserURLLoaderThrottle::BrowserURLLoaderThrottle(
|
||||
OriginVerificationSchedulerBridge* bridge)
|
||||
: bridge_(bridge) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
}
|
||||
|
||||
BrowserURLLoaderThrottle::~BrowserURLLoaderThrottle() = default;
|
||||
|
||||
bool BrowserURLLoaderThrottle::VerifyHeader(
|
||||
const network::mojom::URLResponseHead& response_head) {
|
||||
std::string header_value;
|
||||
response_head.headers->GetNormalizedHeader(
|
||||
content_relationship_verification::kEmbedderAncestorHeader,
|
||||
&header_value);
|
||||
ResponseHeaderVerificationResult header_verification_result =
|
||||
content_relationship_verification::ResponseHeaderVerifier::Verify(
|
||||
base::android::BuildInfo::GetInstance()->host_package_name(),
|
||||
header_value);
|
||||
|
||||
if (header_verification_result == ResponseHeaderVerificationResult::kAllow) {
|
||||
return true;
|
||||
} else if (header_verification_result ==
|
||||
ResponseHeaderVerificationResult::kMissing) {
|
||||
// TODO(crbug.com/1376958): Check for permission.
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void BrowserURLLoaderThrottle::WillStartRequest(
|
||||
network::ResourceRequest* request,
|
||||
bool* defer) {
|
||||
url_ = request->url;
|
||||
}
|
||||
|
||||
void BrowserURLLoaderThrottle::WillRedirectRequest(
|
||||
net::RedirectInfo* redirect_info,
|
||||
const network::mojom::URLResponseHead& response_head,
|
||||
bool* defer,
|
||||
std::vector<std::string>* to_be_removed_request_headers,
|
||||
net::HttpRequestHeaders* modified_request_headers,
|
||||
net::HttpRequestHeaders* modified_cors_exempt_request_headers) {
|
||||
DCHECK(delegate_);
|
||||
|
||||
GURL originating_url = url_;
|
||||
url_ = redirect_info->new_url;
|
||||
|
||||
if (VerifyHeader(response_head)) {
|
||||
return;
|
||||
}
|
||||
|
||||
*defer = true;
|
||||
content::GetUIThreadTaskRunner({})->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
&OriginVerificationSchedulerBridge::Verify, base::Unretained(bridge_),
|
||||
url_.spec(),
|
||||
base::BindOnce(&BrowserURLLoaderThrottle::OnDalVerificationComplete,
|
||||
weak_factory_.GetWeakPtr(), originating_url.spec())));
|
||||
}
|
||||
|
||||
void BrowserURLLoaderThrottle::WillProcessResponse(
|
||||
const GURL& response_url,
|
||||
network::mojom::URLResponseHead* response_head,
|
||||
bool* defer) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(delegate_);
|
||||
|
||||
if (VerifyHeader(*response_head)) {
|
||||
return;
|
||||
}
|
||||
|
||||
*defer = true;
|
||||
content::GetUIThreadTaskRunner({})->PostTask(
|
||||
FROM_HERE,
|
||||
base::BindOnce(
|
||||
&OriginVerificationSchedulerBridge::Verify, base::Unretained(bridge_),
|
||||
response_url.spec(),
|
||||
base::BindOnce(&BrowserURLLoaderThrottle::OnDalVerificationComplete,
|
||||
weak_factory_.GetWeakPtr(), response_url.spec())));
|
||||
}
|
||||
|
||||
void BrowserURLLoaderThrottle::OnDalVerificationComplete(std::string url,
|
||||
bool dal_verified) {
|
||||
DCHECK_CURRENTLY_ON(content::BrowserThread::UI);
|
||||
DCHECK(delegate_);
|
||||
|
||||
if (dal_verified) {
|
||||
delegate_->Resume();
|
||||
return;
|
||||
}
|
||||
delegate_->CancelWithExtendedError(
|
||||
content_relationship_verification::
|
||||
kNetErrorCodeForContentRelationshipVerification,
|
||||
static_cast<int>(content_relationship_verification::kExtendedErrorReason),
|
||||
content_relationship_verification::kCustomCancelReasonForURLLoader);
|
||||
}
|
||||
|
||||
const char* BrowserURLLoaderThrottle::NameForLoggingWillProcessResponse() {
|
||||
return "DigitalAssetLinksBrowserThrottle";
|
||||
}
|
||||
|
||||
} // namespace android_webview
|
@ -1,92 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef ANDROID_WEBVIEW_BROWSER_CONTENT_RELATIONSHIP_VERIFICATION_BROWSER_URL_LOADER_THROTTLE_H_
|
||||
#define ANDROID_WEBVIEW_BROWSER_CONTENT_RELATIONSHIP_VERIFICATION_BROWSER_URL_LOADER_THROTTLE_H_
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "base/functional/callback.h"
|
||||
#include "base/memory/raw_ptr.h"
|
||||
#include "base/memory/ref_counted.h"
|
||||
#include "base/strings/strcat.h"
|
||||
#include "base/time/time.h"
|
||||
#include "components/content_relationship_verification/response_header_verifier.h"
|
||||
#include "content/public/browser/browser_thread.h"
|
||||
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
|
||||
#include "url/gurl.h"
|
||||
|
||||
namespace android_webview {
|
||||
|
||||
// BrowserURLLoaderThrottle is used in the browser process to perform a
|
||||
// digital asset links verification to determine whether a URL and also its
|
||||
// redirect URLs are considered first party content and will be loaded.
|
||||
//
|
||||
// This throttle never defers starting the URL request or following redirects.
|
||||
// If any of the checks for the original URL and redirect chain are not complete
|
||||
// by the time the response headers are available, the request is deferred
|
||||
// until all the checks are done. It cancels the load if any URLs turn out to
|
||||
// be bad.
|
||||
//
|
||||
// Lifetime: Temporary. Created and destroyed for every URL request.
|
||||
class BrowserURLLoaderThrottle : public blink::URLLoaderThrottle {
|
||||
public:
|
||||
class OriginVerificationSchedulerBridge {
|
||||
public:
|
||||
using OriginVerifierCallback = base::OnceCallback<void(bool /*verified*/)>;
|
||||
|
||||
OriginVerificationSchedulerBridge();
|
||||
virtual ~OriginVerificationSchedulerBridge();
|
||||
|
||||
OriginVerificationSchedulerBridge(
|
||||
const OriginVerificationSchedulerBridge&) = delete;
|
||||
OriginVerificationSchedulerBridge& operator=(
|
||||
const OriginVerificationSchedulerBridge&) = delete;
|
||||
|
||||
virtual void Verify(std::string url, OriginVerifierCallback callback) = 0;
|
||||
};
|
||||
|
||||
static std::unique_ptr<BrowserURLLoaderThrottle> Create(
|
||||
OriginVerificationSchedulerBridge* bridge);
|
||||
|
||||
BrowserURLLoaderThrottle(const BrowserURLLoaderThrottle&) = delete;
|
||||
BrowserURLLoaderThrottle& operator=(const BrowserURLLoaderThrottle&) = delete;
|
||||
|
||||
~BrowserURLLoaderThrottle() override;
|
||||
|
||||
// blink::URLLoaderThrottle implementation.
|
||||
|
||||
void WillStartRequest(network::ResourceRequest* request,
|
||||
bool* defer) override;
|
||||
|
||||
void WillRedirectRequest(
|
||||
net::RedirectInfo* redirect_info,
|
||||
const network::mojom::URLResponseHead& response_head,
|
||||
bool* defer,
|
||||
std::vector<std::string>* to_be_removed_request_headers,
|
||||
net::HttpRequestHeaders* modified_request_headers,
|
||||
net::HttpRequestHeaders* modified_cors_exempt_request_headers) override;
|
||||
|
||||
void WillProcessResponse(const GURL& response_url,
|
||||
network::mojom::URLResponseHead* response_head,
|
||||
bool* defer) override;
|
||||
const char* NameForLoggingWillProcessResponse() override;
|
||||
|
||||
private:
|
||||
explicit BrowserURLLoaderThrottle(OriginVerificationSchedulerBridge* bridge);
|
||||
|
||||
void OnDalVerificationComplete(std::string url, bool dal_verified);
|
||||
|
||||
bool VerifyHeader(const network::mojom::URLResponseHead& response_head);
|
||||
|
||||
raw_ptr<OriginVerificationSchedulerBridge> bridge_;
|
||||
|
||||
GURL url_;
|
||||
|
||||
base::WeakPtrFactory<BrowserURLLoaderThrottle> weak_factory_{this};
|
||||
};
|
||||
|
||||
} // namespace android_webview
|
||||
|
||||
#endif // ANDROID_WEBVIEW_BROWSER_CONTENT_RELATIONSHIP_VERIFICATION_BROWSER_URL_LOADER_THROTTLE_H_
|
@ -26,10 +26,8 @@ import org.chromium.android_webview.AwContents;
|
||||
import org.chromium.android_webview.AwContentsStatics;
|
||||
import org.chromium.android_webview.AwCookieManager;
|
||||
import org.chromium.android_webview.AwDarkMode;
|
||||
import org.chromium.android_webview.AwFeatureMap;
|
||||
import org.chromium.android_webview.AwLocaleConfig;
|
||||
import org.chromium.android_webview.AwNetworkChangeNotifierRegistrationPolicy;
|
||||
import org.chromium.android_webview.AwOriginVerificationScheduler;
|
||||
import org.chromium.android_webview.AwProxyController;
|
||||
import org.chromium.android_webview.AwServiceWorkerController;
|
||||
import org.chromium.android_webview.AwThreadUtils;
|
||||
@ -38,7 +36,6 @@ import org.chromium.android_webview.HttpAuthDatabase;
|
||||
import org.chromium.android_webview.ProductConfig;
|
||||
import org.chromium.android_webview.R;
|
||||
import org.chromium.android_webview.WebViewChromiumRunQueue;
|
||||
import org.chromium.android_webview.common.AwFeatures;
|
||||
import org.chromium.android_webview.common.AwResource;
|
||||
import org.chromium.android_webview.common.AwSwitches;
|
||||
import org.chromium.android_webview.gfx.AwDrawFnImpl;
|
||||
@ -234,9 +231,6 @@ public class WebViewChromiumAwInit {
|
||||
mFactory, awBrowserContext.getGeolocationPermissions());
|
||||
mWebStorage =
|
||||
new WebStorageAdapter(mFactory, mBrowserContext.getQuotaManagerBridge());
|
||||
if (AwFeatureMap.isEnabled(AwFeatures.WEBVIEW_RESTRICT_SENSITIVE_CONTENT)) {
|
||||
AwOriginVerificationScheduler.initAndScheduleAll(null);
|
||||
}
|
||||
mAwTracingController = getTracingController();
|
||||
mServiceWorkerController = awBrowserContext.getServiceWorkerController();
|
||||
mAwProxyController = new AwProxyController();
|
||||
|
@ -1,7 +1,6 @@
|
||||
include_rules = [
|
||||
"+components/android_autofill",
|
||||
"+components/autofill/android/java",
|
||||
"+components/content_relationship_verification/android/java",
|
||||
"+components/embedder_support/android/java",
|
||||
"+components/embedder_support/android/metrics/java",
|
||||
"+components/navigation_interception/android/java",
|
||||
|
@ -1,82 +0,0 @@
|
||||
// Copyright 2022 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.android_webview;
|
||||
|
||||
import android.content.Context;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.chromium.android_webview.common.Lifetime;
|
||||
import org.chromium.base.Callback;
|
||||
import org.chromium.base.ContextUtils;
|
||||
import org.chromium.base.ThreadUtils;
|
||||
import org.chromium.components.content_relationship_verification.OriginVerificationScheduler;
|
||||
import org.chromium.components.content_relationship_verification.OriginVerifier;
|
||||
import org.chromium.components.content_relationship_verification.OriginVerifierHelper;
|
||||
import org.chromium.components.embedder_support.util.Origin;
|
||||
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* Singleton.
|
||||
* AwOriginVerificationScheduler provides a WebView specific implementation of {@link
|
||||
* OriginVerificationScheduler}.
|
||||
*
|
||||
* Call {@link AwOriginVerificationScheduler#init} to initialize the statement list and call
|
||||
* {@link AwOriginVerificationScheduler#validate} to perform a validation.
|
||||
*/
|
||||
@Lifetime.Singleton
|
||||
public class AwOriginVerificationScheduler extends OriginVerificationScheduler {
|
||||
private static final String TAG = "AwOriginVerification";
|
||||
|
||||
/** Lock on creation of sInstance. */
|
||||
private static final Object sLock = new Object();
|
||||
|
||||
private static AwOriginVerificationScheduler sInstance;
|
||||
|
||||
private AwOriginVerificationScheduler(
|
||||
AwOriginVerifier originVerifier, Set<Origin> pendingOrigins) {
|
||||
super(originVerifier, pendingOrigins);
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes the AwOriginVerificationScheduler.
|
||||
* This should be called exactly only once as it parses the AndroidManifest and statement list.
|
||||
*
|
||||
* @param packageName the package name of the host application.
|
||||
* @param browserContext the browserContext to use for the simpleUrlLoader to download the asset
|
||||
* links file.
|
||||
* @param context a context associated with an Activity/Service to load resources.
|
||||
*/
|
||||
public static void init(String packageName, AwBrowserContext browserContext, Context context) {
|
||||
ThreadUtils.assertOnUiThread();
|
||||
synchronized (sLock) {
|
||||
assert sInstance
|
||||
== null
|
||||
: "`init(String packageName, Context context)` must only be called once";
|
||||
|
||||
sInstance = new AwOriginVerificationScheduler(
|
||||
new AwOriginVerifier(packageName, OriginVerifier.HANDLE_ALL_URLS,
|
||||
browserContext, AwVerificationResultStore.getInstance()),
|
||||
OriginVerifierHelper.getClaimedOriginsFromManifest(packageName, context));
|
||||
}
|
||||
}
|
||||
|
||||
public static void initAndScheduleAll(@Nullable Callback<Boolean> callback) {
|
||||
synchronized (sLock) {
|
||||
if (sInstance == null) {
|
||||
Context context = ContextUtils.getApplicationContext();
|
||||
init(context.getPackageName(), AwBrowserContext.getDefault(), context);
|
||||
}
|
||||
sInstance.scheduleAllPendingVerifications(callback);
|
||||
}
|
||||
}
|
||||
|
||||
public static AwOriginVerificationScheduler getInstance() {
|
||||
synchronized (sLock) {
|
||||
return sInstance;
|
||||
}
|
||||
}
|
||||
}
|
@ -1,27 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.android_webview;
|
||||
|
||||
import org.chromium.base.annotations.CalledByNative;
|
||||
import org.chromium.base.annotations.JNINamespace;
|
||||
import org.chromium.base.annotations.NativeMethods;
|
||||
|
||||
@JNINamespace("android_webview")
|
||||
class AwOriginVerificationSchedulerBridge {
|
||||
private AwOriginVerificationSchedulerBridge() {}
|
||||
|
||||
@CalledByNative
|
||||
static void verify(String url, long nativeCallbackPtr) {
|
||||
AwOriginVerificationScheduler.getInstance().verify(url, (verified) -> {
|
||||
AwOriginVerificationSchedulerBridgeJni.get().onVerificationResult(
|
||||
nativeCallbackPtr, verified);
|
||||
});
|
||||
}
|
||||
|
||||
@NativeMethods
|
||||
interface Natives {
|
||||
void onVerificationResult(long callbackPtr, boolean verified);
|
||||
}
|
||||
}
|
@ -1,65 +0,0 @@
|
||||
// Copyright 2022 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.android_webview;
|
||||
|
||||
import androidx.annotation.Nullable;
|
||||
|
||||
import org.chromium.android_webview.common.Lifetime;
|
||||
import org.chromium.components.content_relationship_verification.OriginVerifier;
|
||||
import org.chromium.components.content_relationship_verification.Relationship;
|
||||
import org.chromium.components.embedder_support.util.Origin;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* AwOriginVerifier performs OriginVerifications for WebView.
|
||||
*/
|
||||
@Lifetime.Singleton
|
||||
public class AwOriginVerifier extends OriginVerifier {
|
||||
public AwOriginVerifier(String packageName, String relationship,
|
||||
AwBrowserContext browserContext,
|
||||
@Nullable AwVerificationResultStore verificationResultStore) {
|
||||
super(packageName, relationship, null, browserContext, verificationResultStore);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAllowlisted(String packageName, Origin origin, String relation) {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean wasPreviouslyVerified(Origin origin) {
|
||||
return wasPreviouslyVerified(mPackageName, mSignatureFingerprints, origin, mRelation);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether an origin is first-party relative to a given package name.
|
||||
*
|
||||
* This only returns data from previously cached relations, and does not trigger an asynchronous
|
||||
* validation.
|
||||
*
|
||||
* @param packageName The package name.
|
||||
* @param signatureFingerprint The signatures of the package.
|
||||
* @param origin The origin to verify.
|
||||
* @param relation The Digital Asset Links relation to verify for.
|
||||
*/
|
||||
private static boolean wasPreviouslyVerified(String packageName,
|
||||
List<String> signatureFingerprints, Origin origin, String relation) {
|
||||
AwVerificationResultStore resultStore = AwVerificationResultStore.getInstance();
|
||||
return resultStore.shouldOverride(packageName, origin, relation)
|
||||
|| resultStore.isRelationshipSaved(
|
||||
new Relationship(packageName, signatureFingerprints, origin, relation));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordResultMetrics(OriginVerifier.VerifierResult result) {
|
||||
// TODO(crbug.com/1376958): Implement UMA logging.
|
||||
}
|
||||
|
||||
@Override
|
||||
public void recordVerificationTimeMetrics(long duration, boolean online) {
|
||||
// TODO(crbug.com/1376958): Implement UMA logging.
|
||||
}
|
||||
}
|
@ -2015,22 +2015,6 @@ public class AwSettings {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Enable sensitive web content restrictions per WebView.
|
||||
*/
|
||||
public void enableRestrictSensitiveWebContent() {
|
||||
synchronized (mAwSettingsLock) {
|
||||
mEventHandler.runOnUiThreadBlockingAndLocked(() -> {
|
||||
assert Thread.holdsLock(mAwSettingsLock);
|
||||
AwOriginVerificationScheduler.initAndScheduleAll(null);
|
||||
if (mNativeAwSettings != 0) {
|
||||
AwSettingsJni.get().setRestrictSensitiveWebContentEnabled(
|
||||
mNativeAwSettings, AwSettings.this, true);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@NativeMethods
|
||||
interface Natives {
|
||||
long init(AwSettings caller, WebContents webContents);
|
||||
@ -2056,7 +2040,5 @@ public class AwSettings {
|
||||
boolean getEnterpriseAuthenticationAppLinkPolicyEnabled(
|
||||
long nativeAwSettings, AwSettings caller);
|
||||
String[] updateXRequestedWithAllowListOriginMatcher(long nativeAwSettings, String[] rules);
|
||||
void setRestrictSensitiveWebContentEnabled(
|
||||
long nativeAwSettings, AwSettings caller, boolean enabled);
|
||||
}
|
||||
}
|
||||
|
@ -1,38 +0,0 @@
|
||||
// Copyright 2022 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.android_webview;
|
||||
|
||||
import org.chromium.android_webview.common.Lifetime;
|
||||
import org.chromium.components.content_relationship_verification.VerificationResultStore;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
/**
|
||||
* AwVerificationResultStore stores relationships in a local variable.
|
||||
*/
|
||||
@Lifetime.Singleton
|
||||
public class AwVerificationResultStore extends VerificationResultStore {
|
||||
private static final AwVerificationResultStore sInstance = new AwVerificationResultStore();
|
||||
|
||||
private Set<String> mVerifiedOrigins = Collections.synchronizedSet(new HashSet<>());
|
||||
|
||||
private AwVerificationResultStore() {}
|
||||
|
||||
public static AwVerificationResultStore getInstance() {
|
||||
return sInstance;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected Set<String> getRelationships() {
|
||||
return mVerifiedOrigins;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void setRelationships(Set<String> relationships) {
|
||||
mVerifiedOrigins = relationships;
|
||||
}
|
||||
}
|
@ -366,8 +366,6 @@ public final class ProductionSupportedFlagList {
|
||||
Flag.baseFeature(AwFeatures.WEBVIEW_UMA_UPLOAD_QUALITY_OF_SERVICE_SET_TO_DEFAULT,
|
||||
"If enabled, the frequency to upload UMA is increased."),
|
||||
Flag.baseFeature("CanvasColorCache"),
|
||||
Flag.baseFeature(AwFeatures.WEBVIEW_RESTRICT_SENSITIVE_CONTENT,
|
||||
"Controls whether access to sensitive web content should be restricted."),
|
||||
Flag.baseFeature(BlinkFeatures.KEYBOARD_FOCUSABLE_SCROLLERS,
|
||||
"When enabled, can focus on a scroller element using the keyboard."),
|
||||
Flag.commandLine(AwSwitches.WEBVIEW_ENABLE_TRUST_TOKENS_COMPONENT,
|
||||
|
282
android_webview/javatests/src/org/chromium/android_webview/test/AwRestrictSensitiveContentTest.java
282
android_webview/javatests/src/org/chromium/android_webview/test/AwRestrictSensitiveContentTest.java
@ -1,282 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.android_webview.test;
|
||||
|
||||
import android.content.Context;
|
||||
import android.util.Pair;
|
||||
|
||||
import androidx.test.InstrumentationRegistry;
|
||||
import androidx.test.filters.SmallTest;
|
||||
|
||||
import org.junit.After;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
|
||||
import org.chromium.android_webview.AwContents;
|
||||
import org.chromium.android_webview.AwOriginVerificationScheduler;
|
||||
import org.chromium.android_webview.test.util.CommonResources;
|
||||
import org.chromium.base.PackageUtils;
|
||||
import org.chromium.base.test.util.CallbackHelper;
|
||||
import org.chromium.base.test.util.CommandLineFlags;
|
||||
import org.chromium.base.test.util.Feature;
|
||||
import org.chromium.components.embedder_support.util.Origin;
|
||||
import org.chromium.content_public.browser.test.util.TestThreadUtils;
|
||||
import org.chromium.net.test.util.TestWebServer;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
import java.util.concurrent.TimeoutException;
|
||||
|
||||
/**
|
||||
* Tests for the restricting access sensitive web content.
|
||||
*/
|
||||
@RunWith(AwJUnit4ClassRunner.class)
|
||||
public class AwRestrictSensitiveContentTest {
|
||||
@Rule
|
||||
public AwActivityTestRule mActivityTestRule = new AwActivityTestRule();
|
||||
|
||||
private static class OnProgressChangedClient extends TestAwContentsClient {
|
||||
List<Integer> mProgresses = new ArrayList<Integer>();
|
||||
|
||||
@Override
|
||||
public void onProgressChanged(int progress) {
|
||||
super.onProgressChanged(progress);
|
||||
mProgresses.add(Integer.valueOf(progress));
|
||||
if (progress == 100 && mCallbackHelper.getCallCount() == 0) {
|
||||
mCallbackHelper.notifyCalled();
|
||||
}
|
||||
}
|
||||
|
||||
public void waitForFullLoad() throws TimeoutException {
|
||||
mCallbackHelper.waitForFirst();
|
||||
}
|
||||
private CallbackHelper mCallbackHelper = new CallbackHelper();
|
||||
}
|
||||
|
||||
private TestWebServer mWebServer;
|
||||
private OnProgressChangedClient mContentsClient;
|
||||
private AwTestContainerView mTestContainerView;
|
||||
private AwContents mAwContents;
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
mContentsClient = new OnProgressChangedClient();
|
||||
mTestContainerView = mActivityTestRule.createAwTestContainerViewOnMainSync(mContentsClient);
|
||||
mAwContents = mTestContainerView.getAwContents();
|
||||
|
||||
mWebServer = TestWebServer.start();
|
||||
|
||||
final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
TestThreadUtils.runOnUiThreadBlocking(
|
||||
()
|
||||
-> AwOriginVerificationScheduler.init(context.getPackageName(),
|
||||
mActivityTestRule.getAwBrowserContext(), context));
|
||||
}
|
||||
|
||||
@After
|
||||
public void tearDown() {
|
||||
mWebServer.shutdown();
|
||||
}
|
||||
|
||||
private String addPageToTestServer(TestWebServer webServer, String httpPath, String html) {
|
||||
return addPageToTestServer(
|
||||
webServer, httpPath, html, new ArrayList<Pair<String, String>>());
|
||||
}
|
||||
|
||||
private String addPageToTestServer(TestWebServer webServer, String httpPath, String html,
|
||||
List<Pair<String, String>> additionalHeaders) {
|
||||
List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
|
||||
headers.add(Pair.create("Content-Type", "text/html"));
|
||||
headers.add(Pair.create("Cache-Control", "no-store"));
|
||||
headers.addAll(additionalHeaders);
|
||||
return webServer.setResponse(httpPath, html, headers);
|
||||
}
|
||||
|
||||
private String addAboutPageToTestServer(
|
||||
TestWebServer webServer, List<Pair<String, String>> additionalHeaders) {
|
||||
return addPageToTestServer(webServer, "/" + CommonResources.ABOUT_FILENAME,
|
||||
CommonResources.ABOUT_HTML, additionalHeaders);
|
||||
}
|
||||
|
||||
private String addAssetListToTestServer(TestWebServer webServer, String fingerprint) {
|
||||
return addPageToTestServer(webServer, CommonResources.ASSET_LINKS_PATH,
|
||||
CommonResources.makeAssetFile(fingerprint));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
@Feature({"AndroidWebView"})
|
||||
@CommandLineFlags.Add({"disable-features=WebViewRestrictSensitiveContent"})
|
||||
public void disablingFeatureDoesBlockOrRunValidation() throws Throwable {
|
||||
List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
|
||||
headers.add(Pair.create("X-Embedder-Ancestors", "none"));
|
||||
final String aboutPageUrl = addAboutPageToTestServer(mWebServer, headers);
|
||||
|
||||
AwOriginVerificationScheduler scheduler = AwOriginVerificationScheduler.getInstance();
|
||||
|
||||
scheduler.addPendingOriginForTesting(Origin.create(aboutPageUrl));
|
||||
Assert.assertEquals(2, scheduler.getPendingOriginsForTesting().size());
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(
|
||||
() -> mTestContainerView.getAwContents().loadUrl(aboutPageUrl, null));
|
||||
mContentsClient.waitForFullLoad();
|
||||
|
||||
Assert.assertEquals(CommonResources.ABOUT_TITLE, mAwContents.getTitle());
|
||||
Assert.assertEquals(2, scheduler.getPendingOriginsForTesting().size());
|
||||
Assert.assertTrue(
|
||||
scheduler.getPendingOriginsForTesting().contains(Origin.create(aboutPageUrl)));
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
@Feature({"AndroidWebView"})
|
||||
@CommandLineFlags.Add({"enable-features=WebViewRestrictSensitiveContent"})
|
||||
public void testInitAndScheduleAll() throws Throwable {
|
||||
|
||||
CountDownLatch countVerifiedLatch = new CountDownLatch(1);
|
||||
mActivityTestRule.runOnUiThread(() -> {
|
||||
AwOriginVerificationScheduler.initAndScheduleAll(
|
||||
(res) -> { countVerifiedLatch.countDown(); });
|
||||
});
|
||||
|
||||
countVerifiedLatch.await();
|
||||
AwOriginVerificationScheduler scheduler = AwOriginVerificationScheduler.getInstance();
|
||||
|
||||
Assert.assertNotNull(scheduler);
|
||||
Set<Origin> pendingOrigins = scheduler.getPendingOriginsForTesting();
|
||||
Assert.assertEquals(0, pendingOrigins.size());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
@Feature({"AndroidWebView"})
|
||||
@CommandLineFlags.Add({"enable-features=WebViewRestrictSensitiveContent"})
|
||||
public void doesNotBlockDALVerifiedContent() throws Throwable {
|
||||
final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
||||
List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
|
||||
headers.add(Pair.create("X-Embedder-Ancestors", "none"));
|
||||
final String aboutPageUrl = addAboutPageToTestServer(mWebServer, headers);
|
||||
|
||||
List<String> mSignatureFingerprints =
|
||||
PackageUtils.getCertificateSHA256FingerprintForPackage(context.getPackageName());
|
||||
final String assetLinksUrl =
|
||||
addAssetListToTestServer(mWebServer, mSignatureFingerprints.get(0));
|
||||
|
||||
AwOriginVerificationScheduler scheduler = AwOriginVerificationScheduler.getInstance();
|
||||
|
||||
AwOriginVerificationScheduler.getInstance().addPendingOriginForTesting(
|
||||
Origin.create(aboutPageUrl));
|
||||
Set<Origin> pendingOrigins = scheduler.getPendingOriginsForTesting();
|
||||
Assert.assertEquals(2, pendingOrigins.size());
|
||||
Assert.assertTrue(pendingOrigins.contains(Origin.create(aboutPageUrl)));
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(
|
||||
() -> mTestContainerView.getAwContents().loadUrl(aboutPageUrl, null));
|
||||
mContentsClient.waitForFullLoad();
|
||||
|
||||
Set<Origin> pendingOriginsAfterRequest = scheduler.getPendingOriginsForTesting();
|
||||
Assert.assertEquals(1, pendingOriginsAfterRequest.size());
|
||||
Assert.assertFalse(pendingOriginsAfterRequest.contains(Origin.create(aboutPageUrl)));
|
||||
|
||||
Assert.assertEquals(CommonResources.ABOUT_TITLE, mAwContents.getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
@Feature({"AndroidWebView"})
|
||||
@CommandLineFlags.Add({"enable-features=WebViewRestrictSensitiveContent"})
|
||||
public void doesNotBlockHeaderVerifiedContent() throws Throwable {
|
||||
final String webpageNotAvailable = "Webpage not available";
|
||||
List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
|
||||
headers.add(Pair.create("X-Embedder-Ancestors", "*"));
|
||||
final String aboutPageUrl = addAboutPageToTestServer(mWebServer, headers);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(
|
||||
() -> mTestContainerView.getAwContents().loadUrl(aboutPageUrl, null));
|
||||
mContentsClient.waitForFullLoad();
|
||||
|
||||
Assert.assertEquals(CommonResources.ABOUT_TITLE, mAwContents.getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
@Feature({"AndroidWebView"})
|
||||
@CommandLineFlags.Add({"enable-features=WebViewRestrictSensitiveContent"})
|
||||
public void headerCanBlockRedirects() throws Throwable {
|
||||
final String webpageNotAvailable = "Webpage not available";
|
||||
|
||||
List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
|
||||
headers.add(Pair.create("X-Embedder-Ancestors", "*"));
|
||||
final String aboutPageUrl = addAboutPageToTestServer(mWebServer, headers);
|
||||
|
||||
String redirect_path = "/redirect.html";
|
||||
List<Pair<String, String>> blocking_headers = new ArrayList<Pair<String, String>>();
|
||||
blocking_headers.add(Pair.create("X-Embedder-Ancestors", "none"));
|
||||
final String initialUrl =
|
||||
mWebServer.setRedirect(redirect_path, aboutPageUrl, blocking_headers);
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(
|
||||
() -> mTestContainerView.getAwContents().loadUrl(initialUrl, null));
|
||||
mContentsClient.waitForFullLoad();
|
||||
Assert.assertEquals(webpageNotAvailable, mAwContents.getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
@Feature({"AndroidWebView"})
|
||||
@CommandLineFlags.Add({"enable-features=WebViewRestrictSensitiveContent"})
|
||||
public void allowDALVerifiedRedirects() throws Throwable {
|
||||
final Context context = InstrumentationRegistry.getInstrumentation().getTargetContext();
|
||||
|
||||
List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
|
||||
headers.add(Pair.create("X-Embedder-Ancestors", "*"));
|
||||
final String aboutPageUrl = addAboutPageToTestServer(mWebServer, headers);
|
||||
|
||||
List<String> mSignatureFingerprints =
|
||||
PackageUtils.getCertificateSHA256FingerprintForPackage(context.getPackageName());
|
||||
final String assetLinksUrl =
|
||||
addAssetListToTestServer(mWebServer, mSignatureFingerprints.get(0));
|
||||
|
||||
String redirect_path = "/redirect.html";
|
||||
List<Pair<String, String>> blocking_headers = new ArrayList<Pair<String, String>>();
|
||||
blocking_headers.add(Pair.create("X-Embedder-Ancestors", "none"));
|
||||
final String initialUrl =
|
||||
mWebServer.setRedirect(redirect_path, aboutPageUrl, blocking_headers);
|
||||
AwOriginVerificationScheduler.getInstance().addPendingOriginForTesting(
|
||||
Origin.create(initialUrl));
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(
|
||||
() -> mTestContainerView.getAwContents().loadUrl(initialUrl, null));
|
||||
mContentsClient.waitForFullLoad();
|
||||
Assert.assertEquals(CommonResources.ABOUT_TITLE, mAwContents.getTitle());
|
||||
}
|
||||
|
||||
@Test
|
||||
@SmallTest
|
||||
@Feature({"AndroidWebView"})
|
||||
@CommandLineFlags.Add({"enable-features=WebViewRestrictSensitiveContent"})
|
||||
public void doesBlockForNotVerifiedContent() throws Throwable {
|
||||
final String webpageNotAvailable = "Webpage not available";
|
||||
List<Pair<String, String>> headers = new ArrayList<Pair<String, String>>();
|
||||
headers.add(Pair.create("X-Embedder-Ancestors", "none"));
|
||||
final String aboutPageUrl = addAboutPageToTestServer(mWebServer, headers);
|
||||
|
||||
Set<Origin> pendingOrigins =
|
||||
AwOriginVerificationScheduler.getInstance().getPendingOriginsForTesting();
|
||||
Assert.assertFalse(pendingOrigins.contains(Origin.create(aboutPageUrl)));
|
||||
|
||||
InstrumentationRegistry.getInstrumentation().runOnMainSync(
|
||||
() -> mTestContainerView.getAwContents().loadUrl(aboutPageUrl, null));
|
||||
mContentsClient.waitForFullLoad();
|
||||
|
||||
Assert.assertEquals(webpageNotAvailable, mAwContents.getTitle());
|
||||
}
|
||||
}
|
@ -1,4 +0,0 @@
|
||||
include_rules = [
|
||||
"+components/content_relationship_verification/android/java",
|
||||
"+content/public/test/android/javatests/src/org/chromium/content_public/browser/test/util/TestThreadUtils.java",
|
||||
]
|
@ -1,147 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
package org.chromium.android_webview.robolectric;
|
||||
|
||||
import static org.robolectric.Shadows.shadowOf;
|
||||
|
||||
import android.os.Process;
|
||||
|
||||
import androidx.test.core.app.ApplicationProvider;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.runner.RunWith;
|
||||
import org.mockito.ArgumentMatchers;
|
||||
import org.mockito.Mock;
|
||||
import org.mockito.Mockito;
|
||||
import org.mockito.junit.MockitoJUnit;
|
||||
import org.mockito.junit.MockitoRule;
|
||||
import org.mockito.quality.Strictness;
|
||||
import org.robolectric.annotation.Config;
|
||||
|
||||
import org.chromium.android_webview.AwBrowserContext;
|
||||
import org.chromium.android_webview.AwOriginVerifier;
|
||||
import org.chromium.android_webview.AwVerificationResultStore;
|
||||
import org.chromium.base.test.BaseRobolectricTestRunner;
|
||||
import org.chromium.base.test.util.JniMocker;
|
||||
import org.chromium.components.content_relationship_verification.OriginVerifier;
|
||||
import org.chromium.components.content_relationship_verification.OriginVerifier.OriginVerificationListener;
|
||||
import org.chromium.components.content_relationship_verification.OriginVerifierJni;
|
||||
import org.chromium.components.content_relationship_verification.OriginVerifierUnitTestSupport;
|
||||
import org.chromium.components.content_relationship_verification.RelationshipCheckResult;
|
||||
import org.chromium.components.embedder_support.util.Origin;
|
||||
import org.chromium.content_public.browser.test.util.TestThreadUtils;
|
||||
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
/**
|
||||
* JUnit tests for AwOriginVerifier.
|
||||
*/
|
||||
@RunWith(BaseRobolectricTestRunner.class)
|
||||
@Config(manifest = Config.NONE)
|
||||
public class AwOriginVerifierTest {
|
||||
public static final String TEST_BATCH_NAME = "aw_origin_verifier";
|
||||
|
||||
private static final String PACKAGE_NAME = "org.chromium.com";
|
||||
private int mUid = Process.myUid();
|
||||
|
||||
private Origin mHttpsOrigin = Origin.create("https://www.example.com");
|
||||
|
||||
private AwOriginVerifier mAwVerifier;
|
||||
|
||||
@Rule
|
||||
public MockitoRule mMockitoRule = MockitoJUnit.rule().strictness(Strictness.WARN);
|
||||
|
||||
@Rule
|
||||
public JniMocker mJniMocker = new JniMocker();
|
||||
|
||||
@Mock
|
||||
private OriginVerifier.Natives mMockOriginVerifierJni;
|
||||
|
||||
private static class TestOriginVerificationListener implements OriginVerificationListener {
|
||||
private CountDownLatch mLatch;
|
||||
private boolean mVerified;
|
||||
|
||||
TestOriginVerificationListener(CountDownLatch latch) {
|
||||
mLatch = latch;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onOriginVerified(
|
||||
String packageName, Origin origin, boolean verified, Boolean online) {
|
||||
mVerified = verified;
|
||||
mLatch.countDown();
|
||||
}
|
||||
|
||||
public boolean isVerified() {
|
||||
return mVerified;
|
||||
}
|
||||
}
|
||||
|
||||
@Before
|
||||
public void setUp() throws Exception {
|
||||
OriginVerifierUnitTestSupport.registerPackageWithSignature(
|
||||
shadowOf(ApplicationProvider.getApplicationContext().getPackageManager()),
|
||||
PACKAGE_NAME, mUid);
|
||||
|
||||
mJniMocker.mock(OriginVerifierJni.TEST_HOOKS, mMockOriginVerifierJni);
|
||||
Mockito.doAnswer(args -> { return 100L; })
|
||||
.when(mMockOriginVerifierJni)
|
||||
.init(Mockito.any(), Mockito.any());
|
||||
|
||||
mJniMocker.mock(OriginVerifierJni.TEST_HOOKS, mMockOriginVerifierJni);
|
||||
Mockito.doAnswer(args -> {
|
||||
String[] fingerprints = args.getArgument(3);
|
||||
if (fingerprints == null) {
|
||||
mAwVerifier.onOriginVerificationResult(
|
||||
args.getArgument(4), RelationshipCheckResult.FAILURE);
|
||||
return false;
|
||||
}
|
||||
// Ensure parsing of signature works.
|
||||
assert fingerprints.length == 1;
|
||||
assert fingerprints[0] != null;
|
||||
mAwVerifier.onOriginVerificationResult(
|
||||
args.getArgument(4), RelationshipCheckResult.SUCCESS);
|
||||
return true;
|
||||
})
|
||||
.when(mMockOriginVerifierJni)
|
||||
.verifyOrigin(ArgumentMatchers.anyLong(), Mockito.any(),
|
||||
ArgumentMatchers.anyString(), Mockito.any(), ArgumentMatchers.anyString(),
|
||||
ArgumentMatchers.anyString(), Mockito.any());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerification() throws Exception {
|
||||
mAwVerifier = new AwOriginVerifier(PACKAGE_NAME,
|
||||
"delegate_permission/common.handle_all_urls", Mockito.mock(AwBrowserContext.class),
|
||||
AwVerificationResultStore.getInstance());
|
||||
CountDownLatch verificationResultLatch = new CountDownLatch(1);
|
||||
TestOriginVerificationListener resultListener =
|
||||
new TestOriginVerificationListener(verificationResultLatch);
|
||||
TestThreadUtils.runOnUiThreadBlocking(
|
||||
() -> mAwVerifier.start(resultListener, mHttpsOrigin));
|
||||
verificationResultLatch.await();
|
||||
Assert.assertTrue(resultListener.isVerified());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testVerificationResultGetsCached() throws Exception {
|
||||
AwVerificationResultStore store = AwVerificationResultStore.getInstance();
|
||||
mAwVerifier =
|
||||
new AwOriginVerifier(PACKAGE_NAME, "delegate_permission/common.handle_all_urls",
|
||||
Mockito.mock(AwBrowserContext.class), store);
|
||||
CountDownLatch verificationResultLatch = new CountDownLatch(1);
|
||||
TestOriginVerificationListener resultListener =
|
||||
new TestOriginVerificationListener(verificationResultLatch);
|
||||
TestThreadUtils.runOnUiThreadBlocking(
|
||||
() -> mAwVerifier.start(resultListener, mHttpsOrigin));
|
||||
verificationResultLatch.await();
|
||||
|
||||
Assert.assertTrue(mAwVerifier.checkForSavedResult(mHttpsOrigin));
|
||||
Assert.assertTrue(mAwVerifier.wasPreviouslyVerified(mHttpsOrigin));
|
||||
}
|
||||
}
|
@ -62,6 +62,4 @@ public interface WebSettingsBoundaryInterface {
|
||||
|
||||
void setEnterpriseAuthenticationAppLinkPolicyEnabled(boolean enabled);
|
||||
boolean getEnterpriseAuthenticationAppLinkPolicyEnabled();
|
||||
|
||||
void enableRestrictSensitiveWebContent();
|
||||
}
|
||||
|
@ -244,5 +244,6 @@ public class Features {
|
||||
public static final String IMAGE_DRAG_DROP = "IMAGE_DRAG_DROP";
|
||||
|
||||
// WebSettingsCompat.enableRestrictSensitiveWebContent
|
||||
@Deprecated()
|
||||
public static final String RESTRICT_SENSITIVE_WEB_CONTENT = "RESTRICT_SENSITIVE_WEB_CONTENT";
|
||||
}
|
||||
|
@ -238,13 +238,4 @@ class SupportLibWebSettingsAdapter implements WebSettingsBoundaryInterface {
|
||||
return mAwSettings.getEnterpriseAuthenticationAppLinkPolicyEnabled();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void enableRestrictSensitiveWebContent() {
|
||||
try (TraceEvent event = TraceEvent.scoped(
|
||||
"WebView.APICall.AndroidX.RESTRICT_SENSITIVE_WEB_CONTENT")) {
|
||||
recordApiCall(ApiCall.RESTRICT_SENSITIVE_WEB_CONTENT);
|
||||
mAwSettings.enableRestrictSensitiveWebContent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,6 @@ class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryBoundary
|
||||
Features.WEB_MESSAGE_ARRAY_BUFFER,
|
||||
Features.REQUESTED_WITH_HEADER_ALLOW_LIST,
|
||||
Features.IMAGE_DRAG_DROP + Features.DEV_SUFFIX,
|
||||
Features.RESTRICT_SENSITIVE_WEB_CONTENT + Features.DEV_SUFFIX,
|
||||
// Add new features above. New features must include `+ Features.DEV_SUFFIX`
|
||||
// when they're initially added (this can be removed in a future CL). The final
|
||||
// feature should have a trailing comma for cleaner diffs.
|
||||
@ -171,7 +170,6 @@ class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryBoundary
|
||||
ApiCall.SERVICE_WORKER_SETTINGS_SET_REQUESTED_WITH_HEADER_ORIGIN_ALLOWLIST,
|
||||
ApiCall.SERVICE_WORKER_SETTINGS_GET_REQUESTED_WITH_HEADER_ORIGIN_ALLOWLIST,
|
||||
ApiCall.GET_IMAGE_DRAG_DROP_IMPLEMENTATION,
|
||||
ApiCall.RESTRICT_SENSITIVE_WEB_CONTENT,
|
||||
ApiCall.JS_REPLY_POST_MESSAGE_WITH_PAYLOAD,
|
||||
// Add new constants above. The final constant should have a trailing comma for cleaner
|
||||
// diffs.
|
||||
@ -255,6 +253,7 @@ class SupportLibWebViewChromiumFactory implements WebViewProviderFactoryBoundary
|
||||
int SERVICE_WORKER_SETTINGS_SET_REQUESTED_WITH_HEADER_ORIGIN_ALLOWLIST = 70;
|
||||
int SERVICE_WORKER_SETTINGS_GET_REQUESTED_WITH_HEADER_ORIGIN_ALLOWLIST = 71;
|
||||
int GET_IMAGE_DRAG_DROP_IMPLEMENTATION = 72;
|
||||
@Deprecated
|
||||
int RESTRICT_SENSITIVE_WEB_CONTENT = 73;
|
||||
int JS_REPLY_POST_MESSAGE_WITH_PAYLOAD = 74;
|
||||
// Remember to update AndroidXWebkitApiCall in enums.xml when adding new values here
|
||||
|
@ -269,7 +269,6 @@ instrumentation_test_apk("webview_instrumentation_test_apk") {
|
||||
"//components/component_updater/android:embedded_component_loader_java",
|
||||
"//components/content_capture/android:java",
|
||||
"//components/content_capture/android/test_support:java",
|
||||
"//components/content_relationship_verification/android:java",
|
||||
"//components/embedder_support/android:util_java",
|
||||
"//components/embedder_support/android:web_contents_delegate_java",
|
||||
"//components/embedder_support/android/metrics:java",
|
||||
@ -366,7 +365,6 @@ instrumentation_test_apk("webview_instrumentation_test_apk") {
|
||||
"../javatests/src/org/chromium/android_webview/test/AwPersistentOriginTrialTest.java",
|
||||
"../javatests/src/org/chromium/android_webview/test/AwProxyControllerTest.java",
|
||||
"../javatests/src/org/chromium/android_webview/test/AwQuotaManagerBridgeTest.java",
|
||||
"../javatests/src/org/chromium/android_webview/test/AwRestrictSensitiveContentTest.java",
|
||||
"../javatests/src/org/chromium/android_webview/test/AwSecondBrowserProcessTest.java",
|
||||
"../javatests/src/org/chromium/android_webview/test/AwServiceWorkerClientTest.java",
|
||||
"../javatests/src/org/chromium/android_webview/test/AwServiceWorkerSettingsTest.java",
|
||||
@ -699,7 +697,6 @@ robolectric_binary("android_webview_junit_tests") {
|
||||
"../junit/src/org/chromium/android_webview/robolectric/AwDisplayModeControllerTest.java",
|
||||
"../junit/src/org/chromium/android_webview/robolectric/AwHttpAuthHandlerTest.java",
|
||||
"../junit/src/org/chromium/android_webview/robolectric/AwLayoutSizerTest.java",
|
||||
"../junit/src/org/chromium/android_webview/robolectric/AwOriginVerifierTest.java",
|
||||
"../junit/src/org/chromium/android_webview/robolectric/AwScrollOffsetManagerTest.java",
|
||||
"../junit/src/org/chromium/android_webview/robolectric/AwWebContentsMetricsRecorderTest.java",
|
||||
"../junit/src/org/chromium/android_webview/robolectric/FindAddressTest.java",
|
||||
@ -726,9 +723,6 @@ robolectric_binary("android_webview_junit_tests") {
|
||||
"//base:base_java_test_support_uncommon",
|
||||
"//base:base_junit_test_support",
|
||||
"//components/component_updater/android:embedded_component_loader_java",
|
||||
"//components/content_relationship_verification:java",
|
||||
"//components/content_relationship_verification/android:java",
|
||||
"//components/content_relationship_verification/android:junit_test_support",
|
||||
"//components/embedder_support/android:util_java",
|
||||
"//content/public/android:content_full_java",
|
||||
"//content/public/test/android:content_java_test_support",
|
||||
|
@ -14,4 +14,3 @@ IDR_WEBUI_JS_UTIL_TS_JS
|
||||
IDR_WEBUI_JS_PROMISE_RESOLVER_JS
|
||||
IDR_WEBUI_MOJO_MOJO_PUBLIC_JS_BINDINGS_JS
|
||||
IDR_MOJO_BINDINGS_JS
|
||||
IDR_ANDROID_ERROR_CONTENT_BLOCKED_ERROR_HTML
|
||||
|
@ -13,7 +13,6 @@ static_library("android_system_error_page") {
|
||||
deps = [
|
||||
"//base",
|
||||
"//base:i18n",
|
||||
"//components/content_relationship_verification",
|
||||
"//components/resources",
|
||||
"//components/strings",
|
||||
"//net",
|
||||
|
@ -4,5 +4,4 @@ include_rules = [
|
||||
"+net",
|
||||
"+third_party/blink/public",
|
||||
"+ui/base",
|
||||
"+components/content_relationship_verification"
|
||||
]
|
||||
|
@ -8,7 +8,6 @@
|
||||
#include "base/strings/escape.h"
|
||||
#include "base/strings/string_util.h"
|
||||
#include "base/strings/utf_string_conversions.h"
|
||||
#include "components/content_relationship_verification/content_relationship_verification_constants.h"
|
||||
#include "components/grit/components_resources.h"
|
||||
#include "components/strings/grit/components_strings.h"
|
||||
#include "net/base/net_errors.h"
|
||||
@ -46,18 +45,6 @@ void PopulateErrorPageHtml(const blink::WebURLError& error,
|
||||
|
||||
std::string escaped_url = base::EscapeForHTML(url_string);
|
||||
|
||||
// Restrict webview content error.
|
||||
if (error.reason() == net::ERR_ACCESS_DENIED &&
|
||||
error.extended_reason() ==
|
||||
static_cast<int>(
|
||||
content_relationship_verification::kExtendedErrorReason)) {
|
||||
*error_html = base::ReplaceStringPlaceholders(
|
||||
ui::ResourceBundle::GetSharedInstance().LoadDataResourceString(
|
||||
IDR_ANDROID_ERROR_CONTENT_BLOCKED_ERROR_HTML),
|
||||
{escaped_url}, nullptr);
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<std::string> replacements;
|
||||
|
||||
replacements.push_back(
|
||||
|
@ -1,147 +0,0 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Webpage not available</title>
|
||||
|
||||
<style type="text/css">
|
||||
|
||||
:root {
|
||||
/* vars */
|
||||
--button-back-background: #1B72E7;
|
||||
--button-back-text: #FFFFFF;
|
||||
|
||||
--button-browser-background: #FFFFFF;
|
||||
--button-browser-text: #6E7277;
|
||||
|
||||
--explanation-text: #5F6368;
|
||||
|
||||
--font-size-large: 3.5em;
|
||||
--font-size-medium: 2.18em;
|
||||
|
||||
}
|
||||
|
||||
body {
|
||||
padding: 0;
|
||||
margin: 0;
|
||||
overflow: hidden;
|
||||
|
||||
}
|
||||
|
||||
.container {
|
||||
width: 100vw;
|
||||
height: 100vh;
|
||||
padding: 0 5vw;
|
||||
box-sizing: border-box;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.spacer {
|
||||
min-height: 1px;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.warning-icon {
|
||||
margin-bottom: 3.5em;
|
||||
}
|
||||
|
||||
.title {
|
||||
font-family: 'Roboto';
|
||||
font-size: var(--font-size-large);
|
||||
line-height: 1.5;
|
||||
margin-bottom: 0.5em;
|
||||
}
|
||||
|
||||
.explanation {
|
||||
font-family: 'Roboto';
|
||||
color: var(--explanation-text);
|
||||
line-height: 2;
|
||||
font-size: var(--font-size-medium);
|
||||
flex: 2;
|
||||
}
|
||||
|
||||
button {
|
||||
border: 0;
|
||||
border-radius: 0.35em;
|
||||
background-color: var(--button-back-background);
|
||||
color: var(--button-back-text);
|
||||
|
||||
font-weight: bold;
|
||||
font-size: var(--font-size-medium);
|
||||
|
||||
height: 4em;
|
||||
user-select: none;
|
||||
}
|
||||
|
||||
button.back-button {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
button.browser-button {
|
||||
margin-bottom: 3em;
|
||||
background-color: var(--button-browser-background);
|
||||
color: var(--button-browser-text);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
</head>
|
||||
<body>
|
||||
<div class="container">
|
||||
<div class="spacer"></div>
|
||||
<div class="warning-icon">
|
||||
<svg width="200" height="200" viewBox="0 0 200 200" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="mask0_7_79" style="mask-type:alpha" maskUnits="userSpaceOnUse" x="8" y="16" width="184" height="159">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M191.667 175L100 16.6667L8.33373 175H191.667Z" fill="#DA4437">
|
||||
</mask>
|
||||
<g mask="url(#mask0_7_79)">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M191.667 175L100 16.6667L8.3335 175H191.667ZM91.6668 150V133.333H108.334V150H91.6668ZM91.6668 116.667H108.334V83.3333H91.6668V116.667Z" fill="#DA4437">
|
||||
<path d="M108.308 83.313L91.6392 116.651L171.163 196.163L199 174L108.308 83.313Z" fill="url(#paint0_linear_7_79)">
|
||||
<path d="M108.336 132.999L91.667 150.004L171.191 229.516L199.028 223.686L108.336 132.999Z" fill="url(#paint1_linear_7_79)">
|
||||
<g filter="url(#filter0_d_7_79)">
|
||||
<path d="M108.334 116.667H91.667V83.3333H108.334V116.667Z" fill="white">
|
||||
</g>
|
||||
<g filter="url(#filter1_d_7_79)">
|
||||
<path d="M91.667 133.333V150H108.334V133.333H91.667Z" fill="white">
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d_7_79" x="87.667" y="79.3333" width="24.6667" height="41.3333" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix">
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha">
|
||||
<feOffset>
|
||||
<feGaussianBlur stdDeviation="2">
|
||||
<feComposite in2="hardAlpha" operator="out">
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0">
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_7_79">
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_7_79" result="shape">
|
||||
</filter>
|
||||
<filter id="filter1_d_7_79" x="87.667" y="129.333" width="24.6667" height="24.6667" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix">
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0" result="hardAlpha">
|
||||
<feOffset>
|
||||
<feGaussianBlur stdDeviation="2">
|
||||
<feComposite in2="hardAlpha" operator="out">
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0">
|
||||
<feBlend mode="normal" in2="BackgroundImageFix" result="effect1_dropShadow_7_79">
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow_7_79" result="shape">
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear_7_79" x1="91.6392" y1="116.876" x2="164.22" y2="188.767" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#202125" stop-opacity="0.1">
|
||||
<stop offset="0.776042" stop-color="#202125" stop-opacity="0">
|
||||
</linearGradient>
|
||||
<linearGradient id="paint1_linear_7_79" x1="91.667" y1="150.23" x2="164.248" y2="222.12" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="#202125" stop-opacity="0.1">
|
||||
<stop offset="0.776042" stop-color="#202125" stop-opacity="0">
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
</div>
|
||||
<div class="title" >This site cannot be viewed in the current app</div>
|
||||
<div class="explanation">The current app is prevented from opening <b>$1</b> because it may intend to access and modify the site data or collect usage data without your permission.</div>
|
||||
<button class="back-button" >Go back</button>
|
||||
<button class="browser-button" >Open in default browser</button>
|
||||
</div>
|
||||
</body>
|
||||
|
||||
</html>
|
@ -4,8 +4,6 @@
|
||||
|
||||
source_set("content_relationship_verification") {
|
||||
sources = [
|
||||
"content_relationship_verification_constants.cc",
|
||||
"content_relationship_verification_constants.h",
|
||||
"digital_asset_links_handler.cc",
|
||||
"digital_asset_links_handler.h",
|
||||
"response_header_verifier.cc",
|
||||
|
@ -10,5 +10,4 @@ include_rules = [
|
||||
"+services/network/test",
|
||||
"+third_party/blink/public/common/loader/url_loader_throttle.h",
|
||||
"+third_party/blink/public/mojom",
|
||||
"+third_party/blink/public/platform/resource_request_blocked_reason.h"
|
||||
]
|
||||
|
@ -1,21 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#include "components/content_relationship_verification/content_relationship_verification_constants.h"
|
||||
|
||||
#include "net/base/net_errors.h"
|
||||
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
|
||||
|
||||
namespace content_relationship_verification {
|
||||
|
||||
const char kCustomCancelReasonForURLLoader[] =
|
||||
"ContentRelationshipVerification";
|
||||
|
||||
const int kNetErrorCodeForContentRelationshipVerification =
|
||||
net::ERR_ACCESS_DENIED;
|
||||
|
||||
const blink::ResourceRequestBlockedReason kExtendedErrorReason =
|
||||
blink::ResourceRequestBlockedReason::kContentRelationshipVerification;
|
||||
|
||||
} // namespace content_relationship_verification
|
@ -1,26 +0,0 @@
|
||||
// Copyright 2023 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
#ifndef COMPONENTS_CONTENT_RELATIONSHIP_VERIFICATION_CONTENT_RELATIONSHIP_VERIFICATION_CONSTANTS_H_
|
||||
#define COMPONENTS_CONTENT_RELATIONSHIP_VERIFICATION_CONTENT_RELATIONSHIP_VERIFICATION_CONSTANTS_H_
|
||||
#include "third_party/blink/public/platform/resource_request_blocked_reason.h"
|
||||
|
||||
namespace content_relationship_verification {
|
||||
|
||||
// When a network::mojom::URLLoader is cancelled because of content relationship
|
||||
// verification, this custom cancellation reason could be used to notify the
|
||||
// implementation side. Please see
|
||||
// network::mojom::URLLoader::kClientDisconnectReason for more details.
|
||||
extern const char kCustomCancelReasonForURLLoader[];
|
||||
|
||||
// error_code to use when content relationship verification blocks a request.
|
||||
extern const int kNetErrorCodeForContentRelationshipVerification;
|
||||
|
||||
// extended_reason() to use when content relationship verification blocks a
|
||||
// request.
|
||||
extern const blink::ResourceRequestBlockedReason kExtendedErrorReason;
|
||||
|
||||
} // namespace content_relationship_verification
|
||||
|
||||
#endif // COMPONENTS_CONTENT_RELATIONSHIP_VERIFICATION_CONTENT_RELATIONSHIP_VERIFICATION_CONSTANTS_H_
|
@ -1,5 +1,4 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<grit-part>
|
||||
<include name="IDR_ANDROID_ERROR_PAGE_LOAD_ERROR_HTML" file="../android_system_error_page/resources/load_error.html" flattenhtml="true" type="BINDATA" />
|
||||
<include name="IDR_ANDROID_ERROR_CONTENT_BLOCKED_ERROR_HTML" file="../android_system_error_page/resources/content_blocked_error.html" flattenhtml="true" type="BINDATA" />
|
||||
</grit-part>
|
||||
|
@ -1994,8 +1994,6 @@ String blockedReason(blink::ResourceRequestBlockedReason reason) {
|
||||
CorpNotSameOriginAfterDefaultedToSameOriginByCoep;
|
||||
case blink::ResourceRequestBlockedReason::kCorpNotSameSite:
|
||||
return protocol::Network::BlockedReasonEnum::CorpNotSameSite;
|
||||
case blink::ResourceRequestBlockedReason::kContentRelationshipVerification:
|
||||
return protocol::Network::BlockedReasonEnum::Other;
|
||||
case blink::ResourceRequestBlockedReason::kConversionRequest:
|
||||
// This is actually never reached, as the conversion request
|
||||
// is marked as successful and no blocking reason is reported.
|
||||
|
@ -16,7 +16,6 @@ enum class ResourceRequestBlockedReason {
|
||||
kInspector,
|
||||
kSubresourceFilter,
|
||||
kContentType,
|
||||
kContentRelationshipVerification,
|
||||
kCoepFrameResourceNeedsCoepHeader,
|
||||
kCoopSandboxedIFrameCannotNavigateToCoopPage,
|
||||
kCorpNotSameOrigin,
|
||||
|
@ -419,8 +419,6 @@ String BuildBlockedReason(ResourceRequestBlockedReason reason) {
|
||||
CorpNotSameOriginAfterDefaultedToSameOriginByCoep;
|
||||
case blink::ResourceRequestBlockedReason::kCorpNotSameSite:
|
||||
return protocol::Network::BlockedReasonEnum::CorpNotSameSite;
|
||||
case blink::ResourceRequestBlockedReason::kContentRelationshipVerification:
|
||||
return protocol::Network::BlockedReasonEnum::Other;
|
||||
case ResourceRequestBlockedReason::kConversionRequest:
|
||||
// This is actually never reached, as the conversion request
|
||||
// is marked as successful and no blocking reason is reported.
|
||||
|
@ -298,9 +298,6 @@ String DescriptionForBlockedByClientOrResponse(
|
||||
case ResourceRequestBlockedReason::kContentType:
|
||||
detail = "ContentType";
|
||||
break;
|
||||
case ResourceRequestBlockedReason::kContentRelationshipVerification:
|
||||
detail = "ContentRelationshipVerification";
|
||||
break;
|
||||
case ResourceRequestBlockedReason::kCoepFrameResourceNeedsCoepHeader:
|
||||
detail = "ResponseNeedsCrossOriginEmbedderPolicy";
|
||||
break;
|
||||
|
@ -3139,7 +3139,7 @@ Unknown properties are collapsed to zero. -->
|
||||
WebViewProviderFactory#getDropDataProviderImplementation()
|
||||
</int>
|
||||
<int value="73" label="RESTRICT_SENSITIVE_WEB_CONTENT">
|
||||
WebSettingsCompat#enableRestrictSensitiveWebContent()
|
||||
WebSettingsCompat#enableRestrictSensitiveWebContent() (deprecated)
|
||||
</int>
|
||||
<int value="74" label="JS_REPLY_POST_MESSAGE_WITH_PAYLOAD">
|
||||
JsReplyProxy#postMessageWithPayload(WebMessagePayload)
|
||||
|
Reference in New Issue
Block a user