Add csrf token protection to API calls. - #3169
Open
drgrice1 wants to merge 1 commit into
Open
Conversation
somiaj
reviewed
Aug 26, 2026
Anytime a page is rendered a csrf token is added to the `webworkConfig` variable. This is then retrieved in JavaScript anytime an API call is going to be performed and is attached to the request. The API will now refuse any request that does not have this token or if the token does not match the token in the session. This utilizes the Mojolicious `csrf_token` helper method. The point of this is that a user that has properly logged into webwork in the browser may be tricked into doing something in another tab or window by an attacker that would cause a request to be sent to the API. That request would automatically have the valid WeBWorK session cookie attached to it by the browser, and so the request would succeed and could do whatever the user has permission to do via the API. Adding the csrf token prevents that because the other tab or window would not have access to the `csrf_token` in the `webworkConfig` JavaScript variable. This was one of the vulnerabilities that @Alex-Jordan found with Claude before. This does mean that using the API via a script will not work as easily. You would have to extract the `csrf_token` either from the cookies in the response or by parsing the HTML to find the `csrf_token` in the `webworkConfig` variable. But it can still be done. If we really want a proper API for usage in scripts we could make it possible for users to generate an API token in the UI (those with sufficient permissions at least), and the API token added as an `Authorization: Bearer` header could be used as an alternative to the `csrf_token`. At this point I don't think this is needed though. I doubt anyone really uses the API in this way. Note that this does not apply to the `render_rpc` endpoint. It probably should, but that would cause issues for PreTeXt (although this could be worked around in much the same way that cookie disabling is done if the `allow_unsecured_rpc` option is set). At this point I think this is also not necessary as this endpoint generally can't do anything destructive. It just renders problems.
drgrice1
force-pushed
the
api-csrf-token
branch
from
August 26, 2026 20:29
237f4b1 to
efa65b1
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Anytime a page is rendered a csrf token is added to the
webworkConfigvariable. This is then retrieved in JavaScript anytime an API call is going to be performed and is attached to the request. The API will now refuse any request that does not have this token or if the token does not match the token in the session. This utilizes the Mojoliciouscsrf_tokenhelper method.The point of this is that a user that has properly logged into webwork in the browser may be tricked into doing something in another tab or window by an attacker that would cause a request to be sent to the API. That request would automatically have the valid WeBWorK session cookie attached to it by the browser, and so the request would succeed and could do whatever the user has permission to do via the API. Adding the csrf token prevents that because the other tab or window would not have access to the
csrf_tokenin thewebworkConfigJavaScript variable.This was one of the vulnerabilities that @Alex-Jordan found with Claude before.
This does mean that using the API via a script will not work as easily. You would have to extract the
csrf_tokeneither from the cookies in the response or by parsing the HTML to find thecsrf_tokenin thewebworkConfigvariable. But it can still be done. If we really want a proper API for usage in scripts we could make it possible for users to generate an API token in the UI (those with sufficient permissions at least), and the API token added as anAuthorization: Bearerheader could be used as an alternative to thecsrf_token. At this point I don't think this is needed though. I doubt anyone really uses the API in this way.Note that this does not apply to the
render_rpcendpoint. It probably should, but that would cause issues for PreTeXt an others using this endpoint in the same way (although this could be worked around in much the same way that cookie disabling is done if theallow_unsecured_rpcoption is set). At this point I think this is also not necessary as this endpoint generally can't do anything destructive. It just renders problems.