Skip to content

Commit 78374c8

Browse files
panvaaduh95
authored andcommitted
crypto: match algorithm names as ASCII
Reject non-ASCII equivalents of registered Web Crypto algorithm names. Skip the character scan when the input already uses the canonical name. Signed-off-by: Filip Skokan <panva.ip@gmail.com> Assisted-by: Codex PR-URL: #66237 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Aviv Keller <me@aviv.sh>
1 parent ab9a3f2 commit 78374c8

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

‎lib/internal/crypto/util.js‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ const {
2222
PromiseWithResolvers,
2323
SafeMap,
2424
SafeSet,
25+
StringPrototypeCharCodeAt,
2526
StringPrototypeToUpperCase,
2627
Symbol,
2728
TypedArrayPrototypeGetBuffer,
@@ -794,6 +795,15 @@ function normalizeAlgorithm(algorithm, op) {
794795
if (canonicalName === undefined)
795796
throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError');
796797

798+
// Registered names are ASCII. Only check characters when case folding was
799+
// needed, so Unicode characters such as U+017F cannot match ASCII names.
800+
if (algName !== canonicalName) {
801+
for (let i = 0; i < algName.length; i++) {
802+
if (StringPrototypeCharCodeAt(algName, i) > 0x7f)
803+
throw lazyDOMException('Unrecognized algorithm name', 'NotSupportedError');
804+
}
805+
}
806+
797807
algName = canonicalName;
798808
const desiredType = registeredAlgorithms[algName];
799809

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
'use strict';
2+
3+
const common = require('../common');
4+
if (!common.hasCrypto)
5+
common.skip('missing crypto');
6+
7+
const assert = require('assert');
8+
const { subtle } = globalThis.crypto;
9+
10+
(async () => {
11+
const data = new Uint8Array(0);
12+
assert.deepStrictEqual(await subtle.digest('sha-256', data),
13+
await subtle.digest('SHA-256', data));
14+
for (const name of ['\u017fha-256', 'SHA-256\u0131']) {
15+
await assert.rejects(subtle.digest(name, data), { name: 'NotSupportedError' });
16+
assert.strictEqual(SubtleCrypto.supports('digest', name), false);
17+
}
18+
await assert.rejects(subtle.generateKey({ name: 'AE\u017f-GCM', length: 128 },
19+
false, ['encrypt']),
20+
{ name: 'NotSupportedError' });
21+
await assert.rejects(subtle.importKey('raw-secret', data, 'Argon2\u0131d',
22+
false, ['deriveBits']),
23+
{ name: 'NotSupportedError' });
24+
})().then(common.mustCall());

0 commit comments

Comments
 (0)