Skip to content
New issue

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

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

Already on GitHub? # to your account

Fail when base64 data contains nonzero padding bits #28

Closed
slashnick opened this issue Jun 9, 2022 · 6 comments
Closed

Fail when base64 data contains nonzero padding bits #28

slashnick opened this issue Jun 9, 2022 · 6 comments

Comments

@slashnick
Copy link

If the data in a base64 field of a PASETO token isn't a multiple of 6 bits, the last base64 character will be padded with 2 or 4 "zero" bits. But when decoding, most base64 libraries will ignore those last 4 bits.

eg. base64_encode(b"\xff") (11111111) == "_w" (111111 110000). But during decoding base64_decode("_w") (111111 110000) == base64_decode("_y") (111111 110001).

So given a valid PASETO token, you can construct a slightly different token with the same content but a different base64 representation. For example, these two public tokens both decode to the same content, despite having different final characters.

  • v4.public.eyJleHAiOiIyMDIyLTA2LTA5VDE4OjI0OjA4LTA0OjAwIiwidXNlciI6Inplcm8gY29vbCJ9CaoTvJwHuqZgEE8bQVpaIo3sTdZMEtuAXicK_mB2km98GkxvHYc_7nAzCsWjsnvI7OiwUW9aVyS5UnPOXYBnCw
  • v4.public.eyJleHAiOiIyMDIyLTA2LTA5VDE4OjI0OjA4LTA0OjAwIiwidXNlciI6Inplcm8gY29vbCJ9CaoTvJwHuqZgEE8bQVpaIo3sTdZMEtuAXicK_mB2km98GkxvHYc_7nAzCsWjsnvI7OiwUW9aVyS5UnPOXYBnCx

It seems weird for PASETO libraries to accept tokens that they clearly didn't generate.

@slashnick
Copy link
Author

Oh, I guess a simpler way to construct duplicate tokens with would be to append ==. Maybe that should be blocked too?

@paragonie-security
Copy link
Contributor

paragonie-security commented Jun 10, 2022

PASETO doesn't use Base64, PASETO uses Base64url (RFC 4648).

From the relevant section of the specification.

Nearly every component in a Paseto (except for the version, purpose, and the . separators) will be encoded using Base64url, without = padding.

If you'd like us to strengthen the wording ("MUST NOT include padding"; "decoders MUST be strict when decoding", etc.) then that's worth considering.

@paragonie-security
Copy link
Contributor

08be722

@paragonie-security
Copy link
Contributor

@paragonie-security
Copy link
Contributor

paragonie-security commented Jun 10, 2022

@paragonie-security
Copy link
Contributor

Reference implementation updated: https://github.com/paragonie/paseto/releases/tag/v3.0.1

  • Specification is now explicit about this requirement
  • The test vectors now have expected-to-fail test cases to reject malleable encoding
  • Reference implementation in PHP has been updated to be stricter

Thanks for reporting this.

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

No branches or pull requests

2 participants