ReVanced / revanced-polling-api

🗳️ API for ReVanced Polls
GNU Affero General Public License v3.0
13 stars 3 forks source link

feat(auth): exchange token #5

Closed alexandreteles closed 1 year ago

alexandreteles commented 1 year ago

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:

  1. 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.
  2. 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.
  3. 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,
  4. Store the data passed to the endpoint and invalidate the token.