cloudflare / cloudflare/workerd

🐛 Bug Report Runtime APIs node:crypto: Cipheriv.prototype.update throws when string is passed without inputEncoding

Open Beginner friendly
#6,920 0 comments 0 reactions 0 assignees View on GitHub
Dominant language
C++
Stars
8.7k
Forks
739
Avg merge
2d 20h
Merged PRs (30d)
174

Description

### Description

`Cipheriv.prototype.update` (and `Decipheriv`) incorrectly throws `ERR_INVALID_ARG_VALUE`
when `data` is a string and `inputEncoding` is not provided.

In Node.js, omitting `inputEncoding` when `data` is a string is valid the encoding
defaults to `'utf8'` (passed as `undefined` to the C++ binding which normalizes it).

### Reproduction

```js
import { createCipheriv, randomBytes } from 'node:crypto';

const key = randomBytes(32);
const iv = randomBytes(16);
const cipher = createCipheriv('aes-256-cbc', key, iv);

// In Node.js this works fine defaults to utf8
// In workerd this throws: ERR_INVALID_ARG_VALUE [inputEncoding]
cipher.update('hello world');
```

### Expected behavior (Node.js v22)

Returns a `Buffer` containing the encrypted bytes, using `'utf8'` as the input encoding.

### Actual behavior (workerd)

Error [ERR_INVALID_ARG_VALUE]: The argument 'inputEncoding' is invalid. If inputEncoding is not provided then the data must be a Buffer.

### Root cause

In `src/node/internal/crypto_cipher.ts`, `Cipheriv.prototype.update` throws when
`typeof data === 'string' && inputEncoding === undefined` instead of defaulting to `'utf8'`.

**Fix:** Replace the throw with `inputEncoding = 'utf8'`.

### Impact

Breaks any code that passes a plain string to `cipher.update()` without an explicit
encoding a very common pattern when migrating Node.js code to Workers.

Contributor guide

Open the contributing guide

Research direction

Start in src/node/internal/crypto_cipher.ts at Cipheriv.prototype.update and compare the string-input path with Node.js v22 behavior. Replace the invalid-argument path for an omitted inputEncoding with the documented utf8 default, then verify the provided cipher.update('hello world') reproduction returns encrypted bytes and that Decipheriv follows the same behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
node.js, typescript
Domain
backend-api-design, security
Issue type
Bug
Difficulty
1/5
Estimated time
Under an hour
Activity status
Quiet
Clarity
Clearly specified
Newbie friendliness
85/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.