# 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/)


---

# Agent Instructions: Querying This Documentation

If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://ahmed-tarek.gitbook.io/security-notes/how-i-was-able-to-discover-ato-via-idor-vulnerability.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
