Is your feature request related to a problem? Please describe.
The current API implementation only considers a single token that would be passed to the /ballot endpoint using a GET request, exposing the token in plain text in the URL. Although small, this security risk can be mitigated by implementing a /auth/exchange endpoint that exchanges the initial authentication token for a single-use and short-life one that the /ballot endpoint would require.
Describe the solution you'd like
Instead of relying on the PASETO token generated by the Auth.py controller, the ballot.py router should require a token generated by a new controller called Exchange.py. An easy way to implement a solution to this would be:
When the client calls the /auth/exchange check the token's validity (all fields should match the ClientAuthTokenResponse model) and if the token is valid, revoke it using the ban_token() method from the Clients.py controller.
Once the token is properly validated, leverage that PASETO tokens are strongly encrypted and include a custom exchange claim into the token generated by the Exchange.py controller, together with all the original claims from the authentication token.
In the ballot.py router verify if the token JTI isn't expired, and check if the exchange claim exists in the token and is set to True. If one of those conditions fails, reject the request. But if it passes the check,
Store the data passed to the endpoint and invalidate the token.
Is your feature request related to a problem? Please describe.
The current API implementation only considers a single token that would be passed to the
/ballot
endpoint using aGET
request, exposing the token in plain text in the URL. Although small, this security risk can be mitigated by implementing a/auth/exchange
endpoint that exchanges the initial authentication token for a single-use and short-life one that the/ballot
endpoint would require.Describe the solution you'd like
Instead of relying on the PASETO token generated by the
Auth.py
controller, theballot.py
router should require a token generated by a new controller calledExchange.py
. An easy way to implement a solution to this would be:/auth/exchange
check the token's validity (all fields should match theClientAuthTokenResponse
model) and if the token is valid, revoke it using theban_token()
method from theClients.py
controller.exchange
claim into the token generated by theExchange.py
controller, together with all the original claims from the authentication token.ballot.py
router verify if the token JTI isn't expired, and check if theexchange
claim exists in the token and is set toTrue
. If one of those conditions fails, reject the request. But if it passes the check,