diff options
-rw-r--r-- | chromium/third_party/blink/renderer/modules/webusb/usb.cc | 113 | ||||
-rw-r--r-- | chromium/third_party/blink/renderer/modules/webusb/usb.h | 1 |
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_; |