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

Properly handle + and / replacements in state value generation #29

Closed
wants to merge 1 commit into from
Closed

Conversation

driverjb
Copy link
Contributor

@driverjb driverjb commented Feb 6, 2024

This pull request resolves issue: #28

Description

I modified the string replacements for + and / because the current version only replaces the first instance of these characters. Additionally, I've replace the - and _ values with Z because - and _ are invalid Base64 characters.

Motivation and Context

This issue causes intermittent failures of 2FA attempts in our client code because my original state value contains plus characters... sometimes... and the resulting state returned by the Duo authentication causes those plus signs to become space characters. Then they no longer match the original state when I check to see if they match for a user.

How Has This Been Tested?

Tested in my own production code...

Types of Changes

  • Bug fix (non-breaking change which fixes an issue)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)

…itionally, + and / characters are being replaced with the value Z because - and _ are invalid base64 values.

#28
src/util.ts Show resolved Hide resolved
@AaronAtDuo
Copy link
Contributor

Regarding your comment about - and _ being invalid base64 characters... is this causing an problem for your application? I'm not sure why the state generation was written with base64 involved; nothing about the OIDC spec says the state needs to be base64.

@driverjb
Copy link
Contributor Author

driverjb commented Feb 7, 2024

You're absolutely right, the state doesn't need to be base64. Your function name is "bytesToBase64url" so I assumed that meant it's expected to return a valid base64 string. Introducing - or _ makes it not a base64 string. That's the only reason why I changed that.

@@ -6,7 +6,7 @@
import { randomBytes } from 'crypto';

function bytesToBase64url(s: Buffer): string {
return s.toString('base64').replace('+', '-').replace('/', '_');
return s.toString('base64').replace(/\+/g, 'Z').replace(/\//g, 'Z');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm mildly concerned with the loss of randomness that this introduces; I remember our security team being very diligent about us using as random a string as possible. As we discussed, despite the name, there is no real reason the output needs to actually be valid Base64, so it's probably best if we go back to the old replacement characters. At the very least, the two replacement characters should be different.

@driverjb
Copy link
Contributor Author

driverjb commented Mar 8, 2024

I've come up with a better way to do this. I'll be submitting another PR shortly.

@driverjb driverjb closed this Mar 8, 2024
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