Skip to content

fetch arrayBuffer() leaks random data from process memory #3337

Closed
@wille

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

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

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions