Skip to content

[decoding] add limits to variable-length decoders #97

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

reknih
Copy link

@reknih reknih commented May 8, 2025

This commit allows decoder users to limit how many characters or array elements they want to decode.

Such limits are useful in a server environment because lib0 synchronously decodes messages. An attacker just send a message with a very long string or array and stall the main thread of the server so that no other requests can be served.

The length limits have been added to these public functions:

  • readVarUint8Array
  • readTerminatedUint8Array
  • readVarString
  • peekVarString
  • readTerminatedString
  • The constructor of StringDecoder

Each of these functions accepts a new trailing optional argument maxLen. The change should therefore not be breaking.

I have added some tests, the code is fully covered.

This commit allows decoder users to limit how many characters or array elements they want to decode.

Such limits are useful in a server environment because `lib0` synchronously decodes messages. An attacker just send a message with a very long string or array and stall the main thread of the server so that no other requests can be served.

The length limits have been added to these public functions:

- `readVarUint8Array`
- `readTerminatedUint8Array`
- `readVarString`
- `peekVarString`
- `readTerminatedString`
- The constructor of `StringDecoder`

Each of these functions accepts a new trailing optional argument `maxLen`. The change should therefore not be breaking.

I have added some tests, the code is fully covered.
@dmonad
Copy link
Owner

dmonad commented May 9, 2025

Wouldn't it be better to check the length of the buffer instead?

If you really must check the size of readVar* decoders without reading the content, you could do peekVarUint(decoder) > maxLen instead before reading the content.

Generally, I avoid polymorphism in low-level primitives. This is why this library is so fast. Hence, I don't want to accept the PR as is. Sorry for that. There are probably better ways to solve the problem you are facing.

I would accept a PR that checks that the buffer is not exceeded (which is not always the case in lib0).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants