Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 6 additions & 6 deletions proposals/cli/wit-0.3.0-draft/deps.lock
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,15 @@ sha512 = "f08a2828b88fc6ddea935af584531c484ad4a7a5f30340265e11e91b2bfe0f81e74a66

[filesystem]
path = "../../filesystem/wit-0.3.0-draft"
sha256 = "184861e98785957311bfaab242cdf9e66a9ecca11fe2c493b840c461b2361088"
sha512 = "50fa8801fc0a2c1ecfa3cea52af57836f98a12bb0a264439c13bbdcc0e269b3b37ade38b903d6ce10594d1f585d02ef993f3f769c4cddeebdfc00bf93734ed25"
sha256 = "8808ea3adfbc1a025d649b82ddf4f38232ca4377100cfe671d80d5ee37fa3147"
sha512 = "19f4eb8fa62e96ba37b3ea231af6a3bc396c28f82935018a3322441321936b34fb0e44360b378145fcb681d9fea810745969d8baab02ae6017be1784be8abe45"

[random]
path = "../../random/wit-0.3.0-draft"
sha256 = "5794796c909d6656fcbae6bed28265210ca57308a624119ac0a472326a75aa8f"
sha512 = "812ce57aa13ff3128779d41f4dad50714365e4f9cfd2e1b13458a885fa65da05e409f145deefa25c4a82e0e301a41e2e6572705b35752dc33908d565a73a2e9c"
sha256 = "e51ca727c7bbc0f5b6d7e52bb68d5d838a1c8f3d3ae683cf1c0f247b91b0633f"
sha512 = "77791400acebdea60c35a3ca455ad73bc64584840a42fb2365bcfee6cff835fb14fb625145cdbde6cb7a153c841b479393dde8aa0f21bc7bab7046aca541aefb"

[sockets]
path = "../../sockets/wit-0.3.0-draft"
sha256 = "985821e86f2643d90b7a100420a44a5a60a6838adcf76fdb90a66255e3926dde"
sha512 = "9ba1e9456c0dc02800ba738acd382a4113103bed72127396546c5f0ad3d38dd5c8e077443bd508b15f86f6095706907e9cb258cccab37c273b4c597a238987e7"
sha256 = "0be70fab90ec1d62e620f37f8fc55397222ceb68ca8387eb0503df7173782634"
sha512 = "997e336258dd3d8d1bf1b27463e77d1dc2160eb13fff899c93b446973f5efbc59448a23279b60568679c08e006a20cc88769ec74d6d30baa4e7a17df0bdb2c30"
12 changes: 6 additions & 6 deletions proposals/http/wit-0.3.0-draft/deps.lock
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ sha256 = "888647625fec3eaaf276cb884e426bc32bfa79ced22955f10eb239df74c8550c"
sha512 = "f08a2828b88fc6ddea935af584531c484ad4a7a5f30340265e11e91b2bfe0f81e74a660a512f72e5197d60278feccc00534833ebd73868e801859dd31a61bdbb"

[filesystem]
sha256 = "184861e98785957311bfaab242cdf9e66a9ecca11fe2c493b840c461b2361088"
sha512 = "50fa8801fc0a2c1ecfa3cea52af57836f98a12bb0a264439c13bbdcc0e269b3b37ade38b903d6ce10594d1f585d02ef993f3f769c4cddeebdfc00bf93734ed25"
sha256 = "8808ea3adfbc1a025d649b82ddf4f38232ca4377100cfe671d80d5ee37fa3147"
sha512 = "19f4eb8fa62e96ba37b3ea231af6a3bc396c28f82935018a3322441321936b34fb0e44360b378145fcb681d9fea810745969d8baab02ae6017be1784be8abe45"

[random]
sha256 = "5794796c909d6656fcbae6bed28265210ca57308a624119ac0a472326a75aa8f"
sha512 = "812ce57aa13ff3128779d41f4dad50714365e4f9cfd2e1b13458a885fa65da05e409f145deefa25c4a82e0e301a41e2e6572705b35752dc33908d565a73a2e9c"
sha256 = "329785794587f27cc531d19e23fe872237f052d7d839b29ae2288db5ae9f0533"
sha512 = "691a26b30ce4fdfce070d0a9ccfe8b4f998b8dca6f58a7e22298457a8e0d05eba2f5fd38aa19879cc25bcc5f73a99358b33ae2690dde4e1dfea80fc841b1d69b"

[sockets]
sha256 = "985821e86f2643d90b7a100420a44a5a60a6838adcf76fdb90a66255e3926dde"
sha512 = "9ba1e9456c0dc02800ba738acd382a4113103bed72127396546c5f0ad3d38dd5c8e077443bd508b15f86f6095706907e9cb258cccab37c273b4c597a238987e7"
sha256 = "0be70fab90ec1d62e620f37f8fc55397222ceb68ca8387eb0503df7173782634"
sha512 = "997e336258dd3d8d1bf1b27463e77d1dc2160eb13fff899c93b446973f5efbc59448a23279b60568679c08e006a20cc88769ec74d6d30baa4e7a17df0bdb2c30"
28 changes: 26 additions & 2 deletions proposals/random/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,12 @@ The primary goals of WASI Random are:

### Non-goals

WASI Random is not aiming to allow programs to handle errors or to query for
In WASIp2, WASI Random does not allow programs to handle errors or to query for
availability. It always succeeds (though on platforms where randomness is
unavailable, programs may fail to be instantiated or may trap).
unavailable, programs may fail to be instantiated or may trap). In WASIp3,
`get-random-bytes` and `get-insecure-random-bytes` return `result` types so that
hosts can reject oversized requests gracefully (see
[Resource exhaustion](#resource-exhaustion) below).

WASI Random is not aiming to be a full DRBG API. Such an API could be
considered in WASI, but it should be a separate proposal.
Expand Down Expand Up @@ -171,6 +174,27 @@ their bits of security, and it doesn't seem desirable to require wasm engines to
run their own CSPRNG on a platform which already has one, so for now, the API
does not specify a specific number.

### Resource exhaustion

In WASIp2, `get-random-bytes` and `get-insecure-random-bytes` accept a `u64`
length and return `list<u8>` with no way to signal failure. A guest can request
up to 2^64-1 bytes, forcing hosts to either allocate unbounded memory or
hard-trap. This was reported as [GHSA-852m-cvvp-9p4w].

WASIp3 addresses this by changing both functions to return
`result<list<u8>, error>` where `error` is a variant with a `too-many-bytes`
case and an `other(option<string>)` catch-all. This allows hosts to reject
oversized requests gracefully instead of trapping. Callers that need more bytes
than the host supports can simply retry in smaller chunks.

The `error` variant is defined once in the `random` interface and reused by
`insecure` via `use random.{error}`, keeping the error type consistent.

The `get-random-u64` and `get-insecure-random-u64` functions are unchanged since
they always return exactly 8 bytes, posing no resource exhaustion risk.

[GHSA-852m-cvvp-9p4w]: https://github.com/WebAssembly/WASI/security/advisories/GHSA-852m-cvvp-9p4w

### Why is insecure-random a fixed-sized return value?

This limits the amount of data that can be obtained through it. Since it's
Expand Down
10 changes: 9 additions & 1 deletion proposals/random/wit-0.3.0-draft/insecure.wit
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ package wasi:random@0.3.0-rc-2026-02-09;
/// Windows.
@since(version = 0.3.0-rc-2026-02-09)
interface insecure {
@since(version = 0.3.0-rc-2026-02-09)
use random.{error};

/// Return `len` insecure pseudo-random bytes.
///
/// This function is not cryptographically secure. Do not use it for
Expand All @@ -13,8 +16,13 @@ interface insecure {
/// There are no requirements on the values of the returned bytes, however
/// implementations are encouraged to return evenly distributed values with
/// a long period.
///
/// # Errors
///
/// Returns `error::too-many-bytes` if `len` exceeds the host's supported
/// limit.
@since(version = 0.3.0-rc-2026-02-09)
get-insecure-random-bytes: func(len: u64) -> list<u8>;
get-insecure-random-bytes: func(len: u64) -> result<list<u8>, error>;

/// Return an insecure pseudo-random `u64` value.
///
Expand Down
21 changes: 20 additions & 1 deletion proposals/random/wit-0.3.0-draft/random.wit
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@ package wasi:random@0.3.0-rc-2026-02-09;
/// Windows.
@since(version = 0.3.0-rc-2026-02-09)
interface random {
/// An error type for random byte generation.
@since(version = 0.3.0-rc-2026-02-09)
variant error {
/// The requested number of bytes exceeds the host's supported limit.
too-many-bytes,

/// A catch-all error for anything that doesn't fit into a more
/// specific case. The optional string provides an unstructured
/// description of the error. Users should not depend on the string
/// for diagnosing errors, as it is not required to be consistent
/// between implementations.
other(option<string>),
}

/// Return `len` cryptographically-secure random or pseudo-random bytes.
///
/// This function must produce data at least as cryptographically secure and
Expand All @@ -17,8 +31,13 @@ interface random {
/// This function must always return fresh data. Deterministic environments
/// must omit this function, rather than implementing it with deterministic
/// data.
///
/// # Errors
///
/// Returns `error::too-many-bytes` if `len` exceeds the host's supported
/// limit.
@since(version = 0.3.0-rc-2026-02-09)
get-random-bytes: func(len: u64) -> list<u8>;
get-random-bytes: func(len: u64) -> result<list<u8>, error>;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
get-random-bytes: func(len: u64) -> result<list<u8>, error>;
get-random-bytes: func(max-len: u64) -> list<u8>;

We could also allow get-random-bytes to return fewer bytes than requested.

That way we don't need the fallibility and the new max-random-bytes-length API.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is one of the most portable implementations to emulate: https://docs.rs/getrandom/0.4.2/getrandom/

So if we make get-random-bytes fallible (return result) and let callers handle errors, matching how Rust's getrandom crate works, then we remove the ceilings. Implementors may set their own limits and fail.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I'm suggesting is to remove the too-many-bytes failure mode and allow hosts to simply return fewer bytes than requested. (But with a required minimum of 1?)

The guest (e.g. Rust's getrandom::fill implementation) can call the WASI API in a loop in case they don't like short reads.

And with the too-many-bytes case removed, I'm not sure we need an error variant at all here, though I'm also not fundamentally opposed to it either.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Personally I might lean towards the max-len idea as well because it removes ambiguity about the error case. In general a failure to acquire randomness is a weird situation to be in, so by removing errors entirely it means that the guest is guaranteed it's able to acquire at least some randomness. I also would agree with @badeend that it's not a loss in expressiveness necessarily since getrandom might just end up bottoming out in mulitple calls to this function


/// Return a cryptographically-secure random or pseudo-random `u64` value.
///
Expand Down
Loading