diff options
author | Leo K <crowlkats@toaxl.com> | 2021-06-05 19:30:20 +0200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2021-06-05 19:30:20 +0200 |
commit | 083f5c345445af4e434281c37817e12249d7553d (patch) | |
tree | 2db46d622283ab37182ca988ecb0712dc11af6e8 | |
parent | 706b75d7421a33a54f51ceafc0747be4a646c707 (diff) |
refactor(crypto): validate max random bytes in Rust (#10857)
-rw-r--r-- | Cargo.lock | 2 | ||||
-rw-r--r-- | extensions/crypto/01_crypto.js | 8 | ||||
-rw-r--r-- | extensions/crypto/Cargo.toml | 1 | ||||
-rw-r--r-- | extensions/crypto/lib.rs | 17 | ||||
-rw-r--r-- | extensions/web/lib.rs | 30 | ||||
-rw-r--r-- | extensions/webstorage/Cargo.toml | 1 | ||||
-rw-r--r-- | extensions/webstorage/lib.rs | 34 | ||||
-rw-r--r-- | runtime/errors.rs | 2 |
8 files changed, 51 insertions, 44 deletions
diff --git a/Cargo.lock b/Cargo.lock index a28d90d6a..7bb10b7ae 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -644,6 +644,7 @@ name = "deno_crypto" version = "0.21.1" dependencies = [ "deno_core", + "deno_web", "rand 0.8.3", "uuid", ] @@ -823,6 +824,7 @@ name = "deno_webstorage" version = "0.2.1" dependencies = [ "deno_core", + "deno_web", "rusqlite", "serde", ] diff --git a/extensions/crypto/01_crypto.js b/extensions/crypto/01_crypto.js index 627035c28..f18b6d5aa 100644 --- a/extensions/crypto/01_crypto.js +++ b/extensions/crypto/01_crypto.js @@ -26,18 +26,12 @@ "TypeMismatchError", ); } - if (arrayBufferView.byteLength > 65536) { - throw new DOMException( - `The ArrayBufferView's byte length (${arrayBufferView.byteLength}) exceeds the number of bytes of entropy available via this API (65536)`, - "QuotaExceededError", - ); - } const ui8 = new Uint8Array( arrayBufferView.buffer, arrayBufferView.byteOffset, arrayBufferView.byteLength, ); - core.opSync("op_crypto_get_random_values", null, ui8); + core.opSync("op_crypto_get_random_values", ui8); return arrayBufferView; } diff --git a/extensions/crypto/Cargo.toml b/extensions/crypto/Cargo.toml index 8b919b611..b263b6014 100644 --- a/extensions/crypto/Cargo.toml +++ b/extensions/crypto/Cargo.toml @@ -15,5 +15,6 @@ path = "lib.rs" [dependencies] deno_core = { version = "0.88.1", path = "../../core" } +deno_web = { version = "0.38.1", path = "../web" } rand = "0.8.3" uuid = { version = "0.8.2", features = ["v4"] } diff --git a/extensions/crypto/lib.rs b/extensions/crypto/lib.rs index bf4174f75..0ec7f4717 100644 --- a/extensions/crypto/lib.rs +++ b/extensions/crypto/lib.rs @@ -1,6 +1,5 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. -use deno_core::error::null_opbuf; use deno_core::error::AnyError; use deno_core::include_js_files; use deno_core::op_sync; @@ -39,10 +38,16 @@ pub fn init(maybe_seed: Option<u64>) -> Extension { pub fn op_crypto_get_random_values( state: &mut OpState, - _args: (), - zero_copy: Option<ZeroCopyBuf>, + mut zero_copy: ZeroCopyBuf, + _: (), ) -> Result<(), AnyError> { - let mut zero_copy = zero_copy.ok_or_else(null_opbuf)?; + if zero_copy.len() > 65536 { + return Err( + deno_web::DomExceptionQuotaExceededError::new(&format!("The ArrayBufferView's byte length ({}) exceeds the number of bytes of entropy available via this API (65536)", zero_copy.len())) + .into(), + ); + } + let maybe_seeded_rng = state.try_borrow_mut::<StdRng>(); if let Some(seeded_rng) = maybe_seeded_rng { seeded_rng.fill(&mut *zero_copy); @@ -56,8 +61,8 @@ pub fn op_crypto_get_random_values( pub fn op_crypto_random_uuid( state: &mut OpState, - _args: (), - _zero_copy: (), + _: (), + _: (), ) -> Result<String, AnyError> { let maybe_seeded_rng = state.try_borrow_mut::<StdRng>(); let uuid = if let Some(seeded_rng) = maybe_seeded_rng { diff --git a/extensions/web/lib.rs b/extensions/web/lib.rs index 0d2dbbd78..7fa809776 100644 --- a/extensions/web/lib.rs +++ b/extensions/web/lib.rs @@ -1,7 +1,9 @@ // Copyright 2018-2021 the Deno authors. All rights reserved. MIT license. +use deno_core::error::AnyError; use deno_core::include_js_files; use deno_core::Extension; +use std::fmt; use std::path::PathBuf; /// Load and execute the javascript code. @@ -24,3 +26,31 @@ pub fn init() -> Extension { pub fn get_declaration() -> PathBuf { PathBuf::from(env!("CARGO_MANIFEST_DIR")).join("lib.deno_web.d.ts") } + +#[derive(Debug)] +pub struct DomExceptionQuotaExceededError { + pub msg: String, +} + +impl DomExceptionQuotaExceededError { + pub fn new(msg: &str) -> Self { + DomExceptionQuotaExceededError { + msg: msg.to_string(), + } + } +} + +impl fmt::Display for DomExceptionQuotaExceededError { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.pad(&self.msg) + } +} + +impl std::error::Error for DomExceptionQuotaExceededError {} + +pub fn get_quota_exceeded_error_class_name( + e: &AnyError, +) -> Option<&'static str> { + e.downcast_ref::<DomExceptionQuotaExceededError>() + .map(|_| "DOMExceptionQuotaExceededError") +} diff --git a/extensions/webstorage/Cargo.toml b/extensions/webstorage/Cargo.toml index b72970bbd..86018e97b 100644 --- a/extensions/webstorage/Cargo.toml +++ b/extensions/webstorage/Cargo.toml @@ -15,5 +15,6 @@ path = "lib.rs" [dependencies] deno_core = { version = "0.88.1", path = "../../core" } +deno_web = { version = "0.38.1", path = "../web" } rusqlite = { version = "0.25.3", features = ["unlock_notify", "bundled"] } serde = { version = "1.0.125", features = ["derive"] } diff --git a/extensions/webstorage/lib.rs b/extensions/webstorage/lib.rs index d2170890e..595a6b7dd 100644 --- a/extensions/webstorage/lib.rs +++ b/extensions/webstorage/lib.rs @@ -138,8 +138,10 @@ pub fn op_webstorage_set( if size >= 5000000 { return Err( - DomExceptionQuotaExceededError::new("Exceeded maximum storage size") - .into(), + deno_web::DomExceptionQuotaExceededError::new( + "Exceeded maximum storage size", + ) + .into(), ); } @@ -213,34 +215,6 @@ pub fn op_webstorage_iterate_keys( } #[derive(Debug)] -pub struct DomExceptionQuotaExceededError { - pub msg: String, -} - -impl DomExceptionQuotaExceededError { - pub fn new(msg: &str) -> Self { - DomExceptionQuotaExceededError { - msg: msg.to_string(), - } - } -} - -impl fmt::Display for DomExceptionQuotaExceededError { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - f.pad(&self.msg) - } -} - -impl std::error::Error for DomExceptionQuotaExceededError {} - -pub fn get_quota_exceeded_error_class_name( - e: &AnyError, -) -> Option<&'static str> { - e.downcast_ref::<DomExceptionQuotaExceededError>() - .map(|_| "DOMExceptionQuotaExceededError") -} - -#[derive(Debug)] pub struct DomExceptionNotSupportedError { pub msg: String, } diff --git a/runtime/errors.rs b/runtime/errors.rs index c5e93d65b..a3332d41a 100644 --- a/runtime/errors.rs +++ b/runtime/errors.rs @@ -157,7 +157,7 @@ fn get_nix_error_class(error: &nix::Error) -> &'static str { pub fn get_error_class_name(e: &AnyError) -> Option<&'static str> { deno_core::error::get_custom_error_class(e) .or_else(|| deno_webgpu::error::get_error_class_name(e)) - .or_else(|| deno_webstorage::get_quota_exceeded_error_class_name(e)) + .or_else(|| deno_web::get_quota_exceeded_error_class_name(e)) .or_else(|| deno_webstorage::get_not_supported_error_class_name(e)) .or_else(|| { e.downcast_ref::<dlopen::Error>() |