> For the complete documentation index, see [llms.txt](https://ahmed-tarek.gitbook.io/security-notes/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://ahmed-tarek.gitbook.io/security-notes/how-i-was-able-to-discover-ato-via-idor-vulnerability.md).

# How I was able to discover ATO Via IDOR vulnerability

<figure><img src="https://miro.medium.com/v2/resize:fit:1400/0*Fq-PmjWQn4tBIoTE.png" alt="" height="367" width="700"><figcaption></figcaption></figure>

hey there,

I’m Ahmed Tarek, Today I would like to share with you a crazy and weird IDOR discovery in HackerOne ’s program, This is my 1st article so if there is any mistakes , leave on it or DM me on facebook. Without wasting any time we will start on article.**So let’s get started! 😉**

<figure><img src="https://miro.medium.com/v2/resize:fit:660/1*yxXY4xrfMkDdDXHR9fqImQ.jpeg" alt="" height="153" width="330"><figcaption><p>let’s dive in</p></figcaption></figure>

*Let’s consider the target as `target.com` . I quickly signed up with necessary information and created & Verified both accounts for testing purpose `Account 1 & Account 2` in the same time.*

When I tried accessing the profile from both accounts, I noticed something kinda fishy. The application sends a request to an endpoint called `/api/v1/user/profile` to view the profile. Let's dissect the request, shall we?

For *`Account 1`*, the request looks like this:

```
GET /api/v1/user/profile?
user_id=273948261&auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWI
iOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxw
RJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c&timestamp=1349328731
```

Now, pay close attention to the `user_id`: `273948261`. It's crucial, and here's why. When we peek at *`Account 2`* request:

```
GET /api/v1/user/profile?
user_id=273948262&auth_token=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJ
zdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkF0dGVudG9yIiwiaWF0IjoxNjQ5MjQwNjcwL
CJleHAiOjE2NDkyNDExNzB9&timestamp=1349328732
```

Notice the subtle difference? The user ID in *`Account 2`* request is just one step ahead of the `user_id` in *`Account 2`*, so thats if we sign in with another account it will get an `user_id` increased by one from *`Account 2 .`*&#x53;neaky, right? but wait, it gets better.

Now, here’s the catch. The application is supposed to validate the user through three things: `user_id`, `auth_token`, and `timestamp`. But does it really do that?

<figure><img src="https://miro.medium.com/v2/resize:fit:450/1*Bt2vu3lpEpxV27YkxT7agw.jpeg" alt="" height="225" width="225"><figcaption></figcaption></figure>

I tried changing the `user_`id and the auth\_token( the auth\_t) from the attacker to the user , but it gave me a bad request. So, it seems like it’s validating the token, right? Wrong.

[![Become a member](https://miro.medium.com/v2/da:true/resize:fit:0/60026f4340686a391639ac58864da18070aa773cea45de6e55fa47fd56bfdb74)](https://medium.com/plans?source=upgrade_membership---post_li_non_moc_upsell--27af312c8481---------------------------------------)

Upon further investigation, I realized that the application doesn’t validate the token’s validity based on the token itself. Instead, it validates it based on the `timestamp` so if the`timestamp` is right, and even if the token is wrong but it will accept the request.

<figure><img src="https://miro.medium.com/v2/resize:fit:450/1*QjBPuwvjltQmag7Ew42nlw.jpeg" alt="" height="225" width="225"><figcaption><p>i know</p></figcaption></figure>

lets explain it more

once a token is generated, it remains valid for 60 seconds from the time it was create, if the token is used after this 60-second period, it is considered expired and be invalid.

in our application, the timestamp increments by 1 every 10 seconds. After 60 seconds, it deems the token invalid. So, if the `timestamp` was `1349328731`, and a request sent 10 seconds later it will increase by 1 and the `timestamp` will be `1349328732` and would be accepted. But after 60 seconds, it will increase by 6 and will be`1349328737`, and it would be considered an invalid token, because the Token Validity Window will be expired.

So how do i expliot it ?

<figure><img src="https://miro.medium.com/v2/resize:fit:800/1*O6GFagx9tzbefjr6lKRL7Q.gif" alt="" height="300" width="400"><figcaption></figcaption></figure>

I changed the `user_id` from the *`Account 2`*&#x74;o the *`Account 1`* to try to access *`Account 2`* and matched the timestamp value in it t&#x6F;*`Account 1`* timestamp, which was `1349328731` it didn't accept it, but when I bumped the *`Account 2`*&#x74;imestamp to `1349328733` which in the same Validity Window (still the 60 second didnt finshed), it went through smoothly. Can't pinpoint the exact reason, but hey, it worked!, and now i can takeover any account by just changing the `user_id.`

In the end, the company acknowledged the issue as a critical severity and got paid $$$$

Thanks for reading!

<figure><img src="https://miro.medium.com/v2/resize:fit:636/1*QfPMVOteKDZ53nk14SsMWw.jpeg" alt="" height="159" width="318"><figcaption></figcaption></figure>

you can follow me on social media to see more Write-Ups

### Contact : <a href="#id-518e" id="id-518e"></a>

> [X](https://x.com/0x_xnum)
>
> [linkedin](https://www.linkedin.com/in/ahmed-tarek-288754295/)
