Repository navigation
Description
Version
22.3.0
Platform
Linux
Subsystem
No response
What steps will reproduce the bug?
Here is a test script that will reproduce the bug.
I've been unable to reproduce it with a local web server, even if I replicate the cloudinary response.
async function test() {
const url = process.argv[2];
const f = await fetch(url);
const body = await f.arrayBuffer();
console.log('Content-Length:', f.headers.get('content-length'), 'byteLength:', body.byteLength);
if (body.byteLength !== 8192) {
console.log('Bug not reproduced. Please try again.');
return;
}
const decoder = new TextDecoder();
const str = decoder.decode(body);
console.log('Reproduced successfully');
console.log('####################### Arraybuffer');
console.log(str);
console.log('#######################');
}
test();$ node test.js https://res.cloudinary.com/demo/image/upload/h_50,w_50/docs/camera-640.webp
How often does it reproduce? Is there a required condition?
If the script says that it was not able to reproduce it then wait for a bit and try again. Sometimes it happens 10 times in a row and sometimes not for 30 times in a row.
What is the expected behavior? Why is that the expected behavior?
No response
What do you see instead?
As you can see below the buffer returned by arrayBuffer is fixed at 8192 bytes and the webp image received from the actual HTTP request will start at RIFF.
The data before the RIFF header is something random nearby in memory. I had this bug in a production environment and got server logs in there instead of the random HTTP text. In my node instance where I first detected this, I'm serving lots of request and the data leaked was different every time.
I also noticed that the HTTP request data might end up at a random offset, with more leaked data at the end of the blob.
Content-Length: 980, byteLength: 8192
Reproduced successfully
####################### Arraybuffer
/
HTTP/1.1 400 Bad Request
Connection: close
HTTP/1.1 408 Request Timeout
Connection: close
HTTP/1.1 431 Request Header Fields Too Large
Connection: close
HTTP/1.1 413 Payload Too Large
Connection: close
form-data; name="; filename----
�http/1.1RIFF�WEBPVP8 �P�*22>�:�G��!�.0� d�\�d�3~;V��oޏ�p[\��e��O�Z�q�����{���L�K�
x\
�MdM�j�7�Y[2m�Y�>o6���䂫��/LE4�.�vGo�����S/L����(��� ��19��f����T�����!s�※�W4~M��e��VGb�[�H�n��`�]�V������E�އ����(Ba�f5ت��=�S�%c���j���e��ˎ��?�M���X
��<S�>�Ͳ!��W P9�6����m�
-��� �~�I�����̈́*�XK��:U9&���O�����0�7Էc����"�+��z�� R�~�H��0p�La��K��l��
���F?��籁���UV�<I~炷N
�[M)֚��N��TlK>�e������e��!�Y�IJ��f`5om$ݎ�
���1)�
Xl�#�YAu�;��D����ə��a�s��!�o��x�Ċy�Z����_�5Q8��S�3V��<2�fVh�1�5��K�Y�H/
o�SG����c'M>&qb[�q��/�`�E1��J�۽/[J�w!�{���2�:;p"������J���2q���y��>���鬵������R/R�]��W�X��R�|�$����ɽ�d��v�`Qd*G\�NL��������u2e�
���1{�7>c��~v���aV�;� 7��>�@����������P�9����F��TQ��08P��Y���6�B�Fw�H��wPu^�oy������I�5H�d0���=�0R���
�1p:���j��50J���GC=��'��Η?t෨ŋ}g�/�Vx/�,�G��*�U`��
#######################
Additional information
Reproducible on Node 22.3 and NOT on 22.2.
Activity
[-]fetch arrayBuffer() leaks random memory[/-][+]fetch arrayBuffer() includes random data in memory[/+]avivkeller commentedon Jun 17, 2024
CC @nodejs/undici
Uzlopak commentedon Jun 17, 2024
Actually can be a security issue if memory with passwords or something like this is exposed
KhafraDev commentedon Jun 17, 2024
Is it possible to create a local repro?
avivkeller commentedon Jun 17, 2024
@nodejs/security-wg
wille commentedon Jun 17, 2024
This is what I was trying to imply, I had an almost complete dump of cookies here, cached in my CDN, which then leaked to end users
[-]fetch arrayBuffer() includes random data in memory[/-][+]fetch arrayBuffer() leaks random data from process memory[/+]wille commentedon Jun 17, 2024
I've tried to do that replicating the exact HTTP response from the demo URL I included, but I couldn't get it to work.
fix nodejs#3337
KhafraDev commentedon Jun 17, 2024
Reverting f979ec3 fixed the repro you gave. Although with the spottiness of it, I'd prefer if someone else tested it.
fix nodejs#3337 (nodejs#3338)
mcollina commentedon Jun 19, 2024
Unfortunately, I can't repro at all with the given script.
ChALkeR commentedon Jun 19, 2024
@mcollina I can. Looking
ChALkeR commentedon Jun 19, 2024
See #3338 (comment)
Stono commentedon Jun 21, 2024
https://github.com/nodejs/premature-disclosures/issues/11 my script here repros 100% if it helps
Leaking random memory feels like a significant security vulnerability, hopefully the release of this through to node will be expedited!
mcollina commentedon Jun 22, 2024
This already fixed, reproduced and a relevant test added. No further help is needed.
Stono commentedon Jun 22, 2024
Ok thanks.
Do you know if there was a CVE associated to it?
Stono commentedon Jun 22, 2024
Ignore that, I noticed my original issue has been removed/moved to something called premature disclosures so guessing one is coming, maybe this one should be too?
wille commentedon Jun 24, 2024
@Stono can you please share your reproducible script that doesn't depend on the image url I included? Would be nice to see it
Stono commentedon Jun 25, 2024
@wille given that my original thread has now been moved to a premature disclosure, i'm guessing a CVE announcement is coming and they are trying to minimise how much its publicised before a new version is released. Therefore I don't think it's right to share productions here.
wille commentedon Jun 25, 2024
@Stono send it to me privately or paste it here once fixed?
diego-aquino commentedon Jun 26, 2024
This is already fixed, but I just wanted to comment an alternative repro I found. It appears that using any non-empty form data with
RequestorResponsein Node 22.3 also causes the issue:Output in Node 22.2:
Output in Node 22.3:
chore(ci): latest node 22 (#242)