summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJack Hsieh <chengweih@chromium.org>2023-03-13 19:57:29 +0000
committerMichael BrĂ¼ning <michael.bruning@qt.io>2023-05-15 11:36:23 +0000
commitb7e9102b863216fddc5564594a30325829a26a05 (patch)
tree84f7ce344da8326d4839f83a3f322cc73f223521
parent1e552d63f76514a8b0bad478334d1b02d74a5e75 (diff)
downloadqtwebengine-chromium-b7e9102b863216fddc5564594a30325829a26a05.tar.gz
[Backport] CVE-2023-2462: Inappropriate implementation in Prompts (7/10)
Cherry-pick of patch originally reviewed on https://chromium-review.googlesource.com/c/chromium/src/+/4248258: Reject Web USB requests with an opaque origin The Web USB API tracks permissions using the origin of the top-level document in the frame tree. If this document has an opaque origin then there is no way to format the origin for display to the user in permission prompts or to write their decision in the preferences file. Access to the Web USB API from such contexts should therefore be blocked. Bug: 1375133 Change-Id: I47952bb230b3fdf0bfbc76f46d1ef91c19fc7ea1 Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/4248258 Reviewed-by: Reilly Grant <reillyg@chromium.org> Commit-Queue: Jack Hsieh <chengweih@chromium.org> Cr-Commit-Position: refs/heads/main@{#1116559} Reviewed-on: https://codereview.qt-project.org/c/qt/qtwebengine-chromium/+/476761 Reviewed-by: Michal Klocek <michal.klocek@qt.io>
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.cc113
-rw-r--r--chromium/third_party/blink/renderer/modules/webusb/usb.h1
2 files changed, 80 insertions, 34 deletions
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.cc b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
index 90018f42a9b..5bebb5675b7 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.cc
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.cc
@@ -6,6 +6,7 @@
#include <utility>
+#include "base/notreached.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "services/device/public/mojom/usb_device.mojom-blink.h"
#include "services/device/public/mojom/usb_enumeration_options.mojom-blink.h"
@@ -20,6 +21,7 @@
#include "third_party/blink/renderer/core/execution_context/navigator_base.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame.h"
+#include "third_party/blink/renderer/core/workers/worker_global_scope.h"
#include "third_party/blink/renderer/modules/event_target_modules.h"
#include "third_party/blink/renderer/modules/webusb/usb_connection_event.h"
#include "third_party/blink/renderer/modules/webusb/usb_device.h"
@@ -90,6 +92,76 @@ UsbDeviceFilterPtr ConvertDeviceFilter(const USBDeviceFilter* filter,
return mojo_filter;
}
+bool IsContextSupported(ExecutionContext* context) {
+ // Since WebUSB on Web Workers is in the process of being implemented, we
+ // check here if the runtime flag for the appropriate worker is enabled.
+ // TODO(https://crbug.com/837406): Remove this check once the feature has
+ // shipped.
+ if (!context) {
+ return false;
+ }
+
+ DCHECK(context->IsWindow() || context->IsDedicatedWorkerGlobalScope() ||
+ context->IsServiceWorkerGlobalScope());
+ DCHECK(!context->IsDedicatedWorkerGlobalScope() ||
+ RuntimeEnabledFeatures::WebUSBOnDedicatedWorkersEnabled());
+ DCHECK(!context->IsServiceWorkerGlobalScope() ||
+ RuntimeEnabledFeatures::WebUSBOnServiceWorkersEnabled());
+
+ return true;
+}
+
+// Carries out basic checks for the web-exposed APIs, to make sure the minimum
+// requirements for them to be served are met. Returns true if any conditions
+// fail to be met, generating an appropriate exception as well. Otherwise,
+// returns false to indicate the call should be allowed.
+bool ShouldBlockUsbServiceCall(LocalDOMWindow* window,
+ ExecutionContext* context,
+ ExceptionState* exception_state) {
+ if (!IsContextSupported(context)) {
+ if (exception_state) {
+ exception_state->ThrowDOMException(
+ DOMExceptionCode::kNotSupportedError,
+ "The implementation did not support the requested type of object or "
+ "operation.");
+ }
+ return true;
+ }
+ // For window and dedicated workers, reject the request if the top-level frame
+ // has an opaque origin. For Service Workers, we use their security origin
+ // directly as they do not use delegated permissions.
+ const SecurityOrigin* security_origin = nullptr;
+ if (context->IsWindow()) {
+ security_origin =
+ window->GetFrame()->Top()->GetSecurityContext()->GetSecurityOrigin();
+ } else if (context->IsDedicatedWorkerGlobalScope()) {
+ security_origin = static_cast<WorkerGlobalScope*>(context)
+ ->top_level_frame_security_origin();
+ } else if (context->IsServiceWorkerGlobalScope()) {
+ security_origin = context->GetSecurityOrigin();
+ } else {
+ NOTREACHED();
+ }
+ if (security_origin->IsOpaque()) {
+ if (exception_state) {
+ exception_state->ThrowSecurityError(
+ "Access to the WebUSB API is denied from contexts where the "
+ "top-level document has an opaque origin.");
+ }
+ return true;
+ }
+
+ if (!context->IsFeatureEnabled(mojom::blink::PermissionsPolicyFeature::kUsb,
+ ReportOptions::kReportOnFailure)) {
+ if (exception_state) {
+ exception_state->ThrowSecurityError(kFeaturePolicyBlocked);
+ }
+ return true;
+ }
+
+ return false;
+}
+
} // namespace
const char USB::kSupplementName[] = "USB";
@@ -118,16 +190,8 @@ USB::~USB() {
ScriptPromise USB::getDevices(ScriptState* script_state,
ExceptionState& exception_state) {
- if (!IsContextSupported()) {
- exception_state.ThrowDOMException(
- DOMExceptionCode::kNotSupportedError,
- "The implementation did not support the requested type of object or "
- "operation.");
- return ScriptPromise();
- }
-
- if (!IsFeatureEnabled(ReportOptions::kReportOnFailure)) {
- exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
+ if (ShouldBlockUsbServiceCall(GetSupplementable()->DomWindow(),
+ GetExecutionContext(), &exception_state)) {
return ScriptPromise();
}
@@ -150,8 +214,8 @@ ScriptPromise USB::requestDevice(ScriptState* script_state,
return ScriptPromise();
}
- if (!IsFeatureEnabled(ReportOptions::kReportOnFailure)) {
- exception_state.ThrowSecurityError(kFeaturePolicyBlocked);
+ if (ShouldBlockUsbServiceCall(GetSupplementable()->DomWindow(),
+ GetExecutionContext(), &exception_state)) {
return ScriptPromise();
}
@@ -305,8 +369,10 @@ void USB::AddedEventListener(const AtomicString& event_type,
return;
}
- if (!IsContextSupported() || !IsFeatureEnabled(ReportOptions::kDoNotReport))
+ if (ShouldBlockUsbServiceCall(GetSupplementable()->DomWindow(),
+ GetExecutionContext(), nullptr)) {
return;
+ }
EnsureServiceConnection();
}
@@ -315,7 +381,7 @@ void USB::EnsureServiceConnection() {
if (service_.is_bound())
return;
- DCHECK(IsContextSupported());
+ DCHECK(IsContextSupported(GetExecutionContext()));
DCHECK(IsFeatureEnabled(ReportOptions::kDoNotReport));
// See https://bit.ly/2S0zRAS for task types.
auto task_runner =
@@ -331,25 +397,6 @@ void USB::EnsureServiceConnection() {
client_receiver_.BindNewEndpointAndPassRemote(task_runner));
}
-bool USB::IsContextSupported() const {
- // Since WebUSB on Web Workers is in the process of being implemented, we
- // check here if the runtime flag for the appropriate worker is enabled.
- // TODO(https://crbug.com/837406): Remove this check once the feature has
- // shipped.
- ExecutionContext* context = GetExecutionContext();
- if (!context)
- return false;
-
- DCHECK(context->IsWindow() || context->IsDedicatedWorkerGlobalScope() ||
- context->IsServiceWorkerGlobalScope());
- DCHECK(!context->IsDedicatedWorkerGlobalScope() ||
- RuntimeEnabledFeatures::WebUSBOnDedicatedWorkersEnabled());
- DCHECK(!context->IsServiceWorkerGlobalScope() ||
- RuntimeEnabledFeatures::WebUSBOnServiceWorkersEnabled());
-
- return true;
-}
-
bool USB::IsFeatureEnabled(ReportOptions report_options) const {
return GetExecutionContext()->IsFeatureEnabled(
mojom::blink::PermissionsPolicyFeature::kUsb, report_options);
diff --git a/chromium/third_party/blink/renderer/modules/webusb/usb.h b/chromium/third_party/blink/renderer/modules/webusb/usb.h
index 7e3f40d05d0..413db4f419e 100644
--- a/chromium/third_party/blink/renderer/modules/webusb/usb.h
+++ b/chromium/third_party/blink/renderer/modules/webusb/usb.h
@@ -92,7 +92,6 @@ class USB final : public EventTargetWithInlineData,
private:
void EnsureServiceConnection();
- bool IsContextSupported() const;
bool IsFeatureEnabled(ReportOptions) const;
HeapMojoRemote<mojom::blink::WebUsbService> service_;