Skip to content
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

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.

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

No branches or pull requests

2 participants