Skip to content

V8 private symbols #4

Open
Open
@jdalton

Description

@jdalton

This issue is less of a use-case and more of an FYI on a possible approach.

As we know Prototype pollution injection attacks are a common JavaScript issue with CVE after CVE for years now. A recent Node security update from Feb 2024 was related to it as well (Buffer.prototype.utf8Write).

In my experience with WebKit (it's something I'm more familiar with than V8 at the moment) I found that expanding on WebKit's private symbols (properties and intrinsics prefixed with@ instead of V8's%) was totally doable to cover all primordial cases. So for built-in Node code with V8-like private symbols in mind (by way of patching V8 or otherwise) things could look like:

someArray.%push(a, b, c)

optionally using $ or _ as a stand-in prefix for formatters/editors then later through the code-gen/build step transformed to the V8 private symbol % prefix:

someArray.$push(a, b, c)

Even things like this could be possible:

%Buffer.%prototype.%utf8Write
someBuffer.%utf8Write(string, offset, len)

class Foo {
  [%%iterator]() {
    return this;
  }
}

%Map.%__lookupGetter__(%%species)
%Map.%prototype.%%iterator
%RegExp.%prototype.%__lookupGetter__(%dotAll)

Because the private symbol values are references to builtins they are treated just like snapshotted forms except you can call them in a more straight forward way (without uncurrying). These would also only be available to the privileged Node core JS internals (not accessible to user-land code).

No separate realms or VM instances, no cherry-picking/plucking of properties, no indirection through uncurrying. Fast, expressive, and direct access to tamper-proof versions of these methods, properties, and symbols.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions