Telegram WebApp: User Impersonation via initData

KloudFish

Newbie
SUPREME
MEMBER
Joined
Dec 24, 2025
Messages
7
Reaction score
54
Deposit
0$
Website Hacking
Telegram WebApp: User Impersonation via initData




Telegram WebApp uses a non-standard authentication model.
The backend does not manage sessions directly and does not issue tokens.

Instead, user identification is often derived from data sent by the client.
When this data is trusted without strict validation, user impersonation becomes possible.

This vulnerability is not related to XSS or SQL injection.
It is a pure logic flaw caused by client-side trust.




1. What initData Means in Practice

When a WebApp is opened, Telegram provides user data to the frontend.
In JavaScript, it usually looks like this:

  • Telegram.WebApp.initData
  • Telegram.WebApp.initDataUnsafe

initDataUnsafe is a parsed JavaScript object containing fields like:
  • user.id
  • username
  • auth_date

This object exists entirely in the client environment.
After that, the WebApp sends regular HTTP requests to the backend.

From the server perspective, these are just normal JSON requests.




2. How the Vulnerability Appears

The issue appears when the backend determines the user identity
based on fields received directly from the client.

Typical vulnerable logic:
  • backend accepts tg_user_id or user.id from request body
  • backend uses it as authenticated user
  • no independent server-side identity source exists

At this point, the client controls the user context.




3. Vulnerable Backend Example

A common vulnerable endpoint looks like this:

Python:
@app.post("/api/watch")
def watch(payload: dict):
    user_id = payload["tg_user_id"]
    video_id = payload["video_id"]
    return issue_video(user_id, video_id)

Here:
  • tg_user_id comes from the client
  • no verification of its origin exists
  • user identity is fully client-controlled

tg_user_id becomes a user context switch.




4. Where User Impersonation Happens

Impersonation happens directly inside the HTTP request.

Original request:
JSON:
{
  "tg_user_id": 10001,
  "video_id": 42
}

Modified request:
JSON:
{
  "tg_user_id": 10002,
  "video_id": 42
}

The backend processes the request as another user,
because it trusts the value provided by the client.

No server-side state changes are required.
No special access is needed.




5. How the Vulnerability Is Detected

This issue is detected by observing API behavior.

Typical indicators:

  • user_id or tg_user_id is present in request schema
  • API works without initData
  • changing user_id changes returned data
  • API responses reflect the provided user_id

Example response:
JSON:
{
  "user_id": 10001,
  "is_premium": false
}

After changing only user_id:
JSON:
{
  "user_id": 10002,
  "is_premium": true
}




6. Practical Scenario: Limits and Premium

Limits and premium status clearly expose impersonation.

Initial request:
JSON:
{
  "tg_user_id": 10001
}

Response:
JSON:
{
  "user_id": 10001,
  "is_premium": false,
  "daily_limit": 5,
  "daily_left": 0
}

After changing only tg_user_id:
JSON:
{
  "tg_user_id": 10002
}

Response:
JSON:
{
  "user_id": 10002,
  "is_premium": true,
  "daily_limit": 50,
  "daily_left": 47
}

The backend has fully switched user context.




7. Impact and Abuse Potential

Once impersonation is possible, it usually leads to:
  • global IDOR
  • premium bypass
  • limit bypass
  • business logic abuse
  • mass assignment chains

In real projects, this vulnerability often acts as the entry point
for multiple critical issues.


 
Top Bottom