Skip to content

Add CSRF protection by generating/verifying state#2

Merged
radiantshaw merged 4 commits intodevelopfrom
feature/authentication-request
Jan 19, 2026
Merged

Add CSRF protection by generating/verifying state#2
radiantshaw merged 4 commits intodevelopfrom
feature/authentication-request

Conversation

@radiantshaw
Copy link
Owner

@radiantshaw radiantshaw commented Jan 19, 2026

Adds CSRF protection via the state URL parameter.

::Vauth::AuthenticationRequest generates a random state for each instance. This should be accessed via the #state method and stored in a secured place (like Rails session). After the redirect, this stored state should be given back to this class to construct the "same" request again. This should then be passed to the ::Vauth::AuthorizationCodeGrant class along with the received state to verify it.

Notice that ::Vauth::AuthCodeGrant is now called ::Vauth::AuthorizationCodeGrant.

Changed some RuboCop rules as well.

Created the `::Vauth::AuthorizationRequest` class which currently has
the ability to construct the Authorization URL via the `#url` method.
It needs the `::Vauth::Client` to construct the URL.

Also had to modify the `::Vauth::Client` struct to now hold the
`:authorization_uri` value.

Also fixed some RuboCop issues in other places, and modified some
default RuboCop rules.
Added the ability to generate the state of a request to the
`::Vauth::AuthorizationRequest` class. When a state is not passed, it
represents a new request to be made by the Resource Owner. When a state
is passed, it represents a previously made request by the Resource
Owner.

The ability to verify is given to the `::Vauth::AuthCodeGrant` object.
It needs the request instance, and the received state from the redirect.
The state value returned by the `::Vauth::AuthorizationRequest#state`
method should be stored in a secured storage (like Rails sessions)
before redirecting the Resource Owner to the Authorization URI. If the
stored and received states don't match, then the
`::Vauth::AuthCodeGrant` instance is not available and an error is
thrown. The thought behind this is that if there's a state mismatch,
then you're not given the grant to fetch the ID Token (and Access Token,
but it's not implemented).

Also modified a RuboCop rule for the block length metric. I'm just gonna
keep increasing the number for now to see how big the test blocks get. I
might just disable this metric for tests, but at the same time I don't
want the tests to get out of hand. Let's see!
@radiantshaw radiantshaw self-assigned this Jan 19, 2026
`token_uri` was wrapped, but `authorization_uri` wasn't.

Also, I'm not sure if everytime `::Vauth::Client#token_uri` or
`::Vauth::Client#authorization_uri` is called, it should return a new
instance of `URI`. I feel like it should be the responsibility of the
consumers of this class to do the duplication if they need it. But, I'm
not stressing about it right now, so we should be good!
Renamed it to `::Vauth::AuthorizationCodeGrant` for no particular reason
other than feeling like "Auth" should be "Authorization".
@radiantshaw radiantshaw marked this pull request as ready for review January 19, 2026 10:14
@radiantshaw radiantshaw merged commit 94efc36 into develop Jan 19, 2026
1 check passed
@radiantshaw radiantshaw deleted the feature/authentication-request branch January 19, 2026 14:41
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.

1 participant