Skip to content

fix(@types/node): accept ArrayBufferView in webcrypto SubtleCrypto methods#74804

Closed
plu9in wants to merge 3 commits intoDefinitelyTyped:masterfrom
gthstepsecurity:fix/webcrypto-arraybufferview
Closed

fix(@types/node): accept ArrayBufferView in webcrypto SubtleCrypto methods#74804
plu9in wants to merge 3 commits intoDefinitelyTyped:masterfrom
gthstepsecurity:fix/webcrypto-arraybufferview

Conversation

@plu9in
Copy link
Copy Markdown

@plu9in plu9in commented Mar 27, 2026

Summary

Add | NodeJS.ArrayBufferView to data parameters in webcrypto.SubtleCrypto methods (importKey, encrypt, decrypt, sign, verify, digest, unwrapKey).

Problem

TypeScript 5.7+ infers Uint8Array<ArrayBufferLike> for new Uint8Array(n), which is not assignable to NodeJS.BufferSource (= NonSharedArrayBufferView | ArrayBuffer).

This causes type errors on all SubtleCrypto methods when passing a Uint8Array created via new Uint8Array(n) — a very common pattern:

```typescript
const key = new Uint8Array(32);
// ERROR: Argument of type 'Uint8Array' is not assignable to parameter of type 'BufferSource'
await webcrypto.subtle.importKey("raw", key, "AES-GCM", false, ["encrypt"]);
```

Root Cause

  1. TS 5.7 made `Uint8Array` generic: `Uint8Array`
  2. `new Uint8Array(32)` produces `Uint8Array` (default generic)
  3. `NodeJS.BufferSource` requires `NonSharedArrayBufferView` = `ArrayBufferView`
  4. `Uint8Array` is NOT assignable to `Uint8Array`

At runtime, `new Uint8Array(32)` always creates a view over a regular `ArrayBuffer`, and Node.js's `SubtleCrypto` accepts it without issue.

Solution

Add `NodeJS.ArrayBufferView` as an accepted type alongside `NodeJS.BufferSource` for data parameters. This matches Node.js's runtime behavior without modifying the `BufferSource` type itself (which follows the WebIDL spec).

Additive change — no existing signatures modified. All previously-compiling code continues to compile.

Methods Updated

  • `importKey` (raw format overload) — `keyData`
  • `encrypt` — `data`
  • `decrypt` — `data`
  • `sign` — `data`
  • `verify` — `signature` + `data`
  • `digest` — `data`
  • `unwrapKey` — `wrappedKey`

Impact

Every Node.js + TypeScript developer using `webcrypto` in strict mode. Eliminates the need for `as any` or `as unknown as BufferSource` workarounds.


Contributed by Continuum Identity — maintainers of 2FApi, a zero-knowledge proof authentication protocol for APIs.

TypeScript 5.7+ infers `Uint8Array<ArrayBufferLike>` for `new Uint8Array(n)`,
which is not assignable to `BufferSource` (= `NonSharedArrayBufferView | ArrayBuffer`).

This causes type errors on all SubtleCrypto methods when passing a Uint8Array
created via `new Uint8Array(n)` — a very common pattern in WebCrypto usage.

At runtime, Node.js accepts any ArrayBufferView regardless of the backing
buffer type. This change adds `| NodeJS.ArrayBufferView` to the data
parameters of: importKey, encrypt, decrypt, sign, verify, digest, unwrapKey.

This is additive (no existing signatures changed) and backward-compatible.
@typescript-bot
Copy link
Copy Markdown
Contributor

typescript-bot commented Mar 27, 2026

@plu9in Thank you for submitting this PR! I see this is your first time submitting to DefinitelyTyped 👋 — I'm the local bot who will help you through the process of getting things through.

This is a live comment that I will keep updated.

1 package in this PR

Code Reviews

Because this is a widely-used package, a DT maintainer will need to review it before it can be merged.

You can test the changes of this PR in the Playground.

Status

  • ✅ No merge conflicts
  • ✅ Continuous integration tests have passed
  • 🕐 Most recent commit is approved by a DT maintainer

Once every item on this list is checked, I'll ask you for permission to merge and publish the changes.


Diagnostic Information: What the bot saw about this PR
{
  "type": "info",
  "now": "-",
  "pr_number": 74804,
  "author": "plu9in",
  "headCommitOid": "b10d6d73dd9281aff801ada9dd9a4cd0ff3468bb",
  "mergeBaseOid": "b18c0e77059402c2fd62a7483e00dfd2209bf776",
  "lastPushDate": "2026-03-27T10:25:22.000Z",
  "lastActivityDate": "2026-03-27T13:24:46.000Z",
  "hasMergeConflict": false,
  "isFirstContribution": true,
  "tooManyFiles": false,
  "hugeChange": false,
  "popularityLevel": "Critical",
  "pkgInfo": [
    {
      "name": "node",
      "kind": "edit",
      "files": [
        {
          "path": "types/node/crypto.d.ts",
          "kind": "definition"
        },
        {
          "path": "types/node/node-tests/crypto.ts",
          "kind": "test"
        }
      ],
      "owners": [
        "Microsoft",
        "jkomyno",
        "r3nya",
        "btoueg",
        "touffy",
        "mohsen1",
        "galkin",
        "eps1lon",
        "WilcoBakker",
        "chyzwar",
        "trivikr",
        "yoursunny",
        "qwelias",
        "ExE-Boss",
        "peterblazejewicz",
        "addaleax",
        "victorperin",
        "NodeJS",
        "LinusU",
        "wafuwafu13",
        "mcollina",
        "Semigradsky",
        "Renegade334",
        "anonrig"
      ],
      "addedOwners": [],
      "deletedOwners": [],
      "popularityLevel": "Critical"
    }
  ],
  "reviews": [
    {
      "type": "changereq",
      "reviewer": "Renegade334",
      "date": "2026-03-27T13:24:46.000Z"
    }
  ],
  "mainBotCommentID": 4141629030,
  "ciResult": "pass"
}

@typescript-bot
Copy link
Copy Markdown
Contributor

🔔 @microsoft @jkomyno @r3nya @btoueg @Touffy @mohsen1 @galkin @eps1lon @WilcoBakker @chyzwar @trivikr @yoursunny @qwelias @ExE-Boss @peterblazejewicz @addaleax @victorperin @nodejs @LinusU @wafuwafu13 @mcollina @Semigradsky @Renegade334 @anonrig — please review this PR in the next few days. Be sure to explicitly select Approve or Request Changes in the GitHub UI so I know what's going on.

@typescript-bot typescript-bot moved this from Waiting for Code Reviews to Needs Maintainer Review in Pull Request Status Board Mar 27, 2026
Verify that SubtleCrypto methods (importKey, encrypt, decrypt, sign,
verify, digest, unwrapKey) accept Uint8Array created via new Uint8Array(n),
which TypeScript 5.7+ infers as Uint8Array<ArrayBufferLike>.

9 test assertions added to the existing webcrypto test block.
@typescript-bot typescript-bot removed the Untested Change This PR does not touch tests label Mar 27, 2026
@typescript-bot typescript-bot moved this from Needs Maintainer Review to Waiting for Code Reviews in Pull Request Status Board Mar 27, 2026
@typescript-bot typescript-bot moved this from Waiting for Code Reviews to Needs Maintainer Review in Pull Request Status Board Mar 27, 2026
@typescript-bot typescript-bot moved this from Needs Maintainer Review to Waiting for Code Reviews in Pull Request Status Board Mar 27, 2026
@typescript-bot typescript-bot moved this from Waiting for Code Reviews to Needs Maintainer Review in Pull Request Status Board Mar 27, 2026
Copy link
Copy Markdown
Contributor

@Renegade334 Renegade334 left a comment

Choose a reason for hiding this comment

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

The types are both accurate and deliberate. This is essentially a duplicate of a number of TS-related discussions (microsoft/TypeScript#62324 etc.) relating to strongly typed buffer sources in the web API definitions.

In the web IDL, BufferSource specifically rejects either SharedArrayBuffers or typed arrays / DataViews that are backed by a SharedArrayBuffer. In TS 5.7+, this is represented by the narrowed ArrayBuffer-backed types you see here.

TypeScript 5.7+ infers Uint8Array<ArrayBufferLike> for new Uint8Array(n)

This is incorrect. All of the new T() typed array constructor signatures return a T<ArrayBuffer> in TS 5.7+, except in the case where a SharedArrayBuffer is passed as the first constructor argument.

This causes type errors on all SubtleCrypto methods when passing a Uint8Array created via new Uint8Array(n) — a very common pattern:

const key = new Uint8Array(32);
// ERROR: Argument of type 'Uint8Array' is not assignable to parameter of type 'BufferSource'
await webcrypto.subtle.importKey("raw", key, "AES-GCM", false, ["encrypt"]);

This is 100% an AI hallucination: TS Playground example

@typescript-bot typescript-bot added the Revision needed This PR needs code changes before it can be merged. label Mar 27, 2026
@typescript-bot
Copy link
Copy Markdown
Contributor

@plu9in One or more reviewers has requested changes. Please address their comments. I'll be back once they sign off or you've pushed new commits. Thank you!

@typescript-bot typescript-bot moved this from Needs Maintainer Review to Needs Author Action in Pull Request Status Board Mar 27, 2026
@plu9in
Copy link
Copy Markdown
Author

plu9in commented Mar 29, 2026

@Renegade334 Thank you for the thorough review. You're absolutely right — the premise of this PR is incorrect.

I re-checked and confirmed that new Uint8Array(n) does return Uint8Array<ArrayBuffer> in TS 5.7+, which is assignable to the existing BufferSource type. The type errors I encountered were caused by Uint8Array values coming from WASM/NAPI bindings (which infer ArrayBufferLike instead of ArrayBuffer), not from the SubtleCrypto type definitions themselves.

The correct fix is on our side (explicit type assertion at the FFI boundary), not in @types/node.

Closing this PR. Apologies for the noise on a critical package.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Critical package Revision needed This PR needs code changes before it can be merged.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants