summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-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_;