fix: Node.js atob
input validation (#35415)
fix: Node.js atob input validation
This commit is contained in:
parent
7e8607fd7a
commit
22ff2b6b93
2 changed files with 90 additions and 0 deletions
|
@ -47,3 +47,4 @@ support_v8_sandboxed_pointers.patch
|
|||
build_ensure_v8_pointer_compression_sandbox_is_enabled_on_64bit.patch
|
||||
build_ensure_native_module_compilation_fails_if_not_using_a_new.patch
|
||||
fix_override_createjob_in_node_platform.patch
|
||||
buffer_fix_atob_input_validation.patch
|
||||
|
|
89
patches/node/buffer_fix_atob_input_validation.patch
Normal file
89
patches/node/buffer_fix_atob_input_validation.patch
Normal file
|
@ -0,0 +1,89 @@
|
|||
From 0000000000000000000000000000000000000000 Mon Sep 17 00:00:00 2001
|
||||
From: Shelley Vohr <shelley.vohr@gmail.com>
|
||||
Date: Tue, 23 Aug 2022 11:13:45 +0200
|
||||
Subject: buffer: fix `atob` input validation
|
||||
|
||||
This patch combines:
|
||||
|
||||
* https://github.com/nodejs/node/pull/42539
|
||||
* https://github.com/nodejs/node/pull/42662
|
||||
|
||||
To bring the Node.js implementation of atob into alignment with the
|
||||
WHATWG spec.
|
||||
|
||||
diff --git a/lib/buffer.js b/lib/buffer.js
|
||||
index 57d6cddbaa2e6bdd846a667897588dea18daeb42..7602d4049e9bb1c09440bc3af09ad5ad9c768308 100644
|
||||
--- a/lib/buffer.js
|
||||
+++ b/lib/buffer.js
|
||||
@@ -23,8 +23,10 @@
|
||||
|
||||
const {
|
||||
Array,
|
||||
+ ArrayFrom,
|
||||
ArrayIsArray,
|
||||
ArrayPrototypeForEach,
|
||||
+ ArrayPrototypeIndexOf,
|
||||
MathFloor,
|
||||
MathMin,
|
||||
MathTrunc,
|
||||
@@ -1231,8 +1233,25 @@ function btoa(input) {
|
||||
return buf.toString('base64');
|
||||
}
|
||||
|
||||
-const kBase64Digits =
|
||||
- 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=';
|
||||
+// Refs: https://infra.spec.whatwg.org/#forgiving-base64-decode
|
||||
+const kForgivingBase64AllowedChars = [
|
||||
+ // ASCII whitespace
|
||||
+ // Refs: https://infra.spec.whatwg.org/#ascii-whitespace
|
||||
+ 0x09, 0x0A, 0x0C, 0x0D, 0x20,
|
||||
+
|
||||
+ // Uppercase letters
|
||||
+ ...ArrayFrom({ length: 26 }, (_, i) => StringPrototypeCharCodeAt('A') + i),
|
||||
+
|
||||
+ // Lowercase letters
|
||||
+ ...ArrayFrom({ length: 26 }, (_, i) => StringPrototypeCharCodeAt('a') + i),
|
||||
+
|
||||
+ // Decimal digits
|
||||
+ ...ArrayFrom({ length: 10 }, (_, i) => StringPrototypeCharCodeAt('0') + i),
|
||||
+
|
||||
+ 0x2B, // +
|
||||
+ 0x2F, // /
|
||||
+ 0x3D, // =
|
||||
+];
|
||||
|
||||
function atob(input) {
|
||||
// The implementation here has not been performance optimized in any way and
|
||||
@@ -1241,11 +1260,31 @@ function atob(input) {
|
||||
if (arguments.length === 0) {
|
||||
throw new ERR_MISSING_ARGS('input');
|
||||
}
|
||||
+
|
||||
input = `${input}`;
|
||||
+ let nonAsciiWhitespaceCharCount = 0;
|
||||
+
|
||||
for (let n = 0; n < input.length; n++) {
|
||||
- if (!kBase64Digits.includes(input[n]))
|
||||
+ const index = ArrayPrototypeIndexOf(
|
||||
+ kForgivingBase64AllowedChars,
|
||||
+ StringPrototypeCharCodeAt(input, n));
|
||||
+
|
||||
+ if (index > 4) {
|
||||
+ // The first 5 elements of `kForgivingBase64AllowedChars` are
|
||||
+ // ASCII whitespace char codes.
|
||||
+ nonAsciiWhitespaceCharCount++;
|
||||
+ } else if (index === -1) {
|
||||
throw lazyDOMException('Invalid character', 'InvalidCharacterError');
|
||||
+ }
|
||||
}
|
||||
+
|
||||
+ // See #3 - https://infra.spec.whatwg.org/#forgiving-base64
|
||||
+ if (nonAsciiWhitespaceCharCount % 4 === 1) {
|
||||
+ throw lazyDOMException(
|
||||
+ 'The string to be decoded is not correctly encoded.',
|
||||
+ 'InvalidCharacterError');
|
||||
+ }
|
||||
+
|
||||
return Buffer.from(input, 'base64').toString('latin1');
|
||||
}
|
||||
|
Loading…
Add table
Add a link
Reference in a new issue