Back in the day, when we talked about hacking a website, those famous <script>alert('XSS')</script> codes or database-lifting OR 1=1 SQL injections immediately came to mind. Firewalls (WAFs) learned to recognize these patterns, and developers memorized sanitization functions. But today, the rules of the game have completely changed. No one is trying to smash the front door with a sledgehammer anymore; everyone is looking for a 'logic' flaw in that tiny, undocumented API endpoint at the back.
APIs have become the nervous system of the internet. From mobile apps to IoT devices, from microservice architectures to third-party integrations, everything runs on a silent stream of data flowing in JSON format. This silence brings a massive blind spot along with it. There’s a reality we frequently see in our Red Team operations: No matter how much you surround a system with WAFs or IPSs, a flaw in the Business Logic can bypass all those defense layers with a single 'Request'.
BOLA: Our Favorite But Most Dangerous Guest
There is a friend of ours who refuses to leave the top of the OWASP API Security Top 10 list: BOLA (Broken Object Level Authorization). Formerly known as IDOR. But in the API world, it’s much more insidious.
Let’s consider a scenario: Suppose a mobile application is being developed for an e-commerce platform called testCompany. When a user wants to view their own orders, the application sends a request to this endpoint:
GET /api/v1/orders/ORD-8821
Here, the thing the security team needs to check isn't just 'Is this user logged in?' (Authentication), but 'Is this user authorized to see order 8821?' (Authorization). Most of the time, developers only check the former for the sake of speed. As an attacker, if I intercept this request via a proxy (like Burp Suite) and change the ORD-8821 value to ORD-8822, and I end up seeing another customer’s order details (address, phone, last 4 digits of the card), then it's game over; we have a BOLA on our hands.
Defanged Example:
GET /api/v1/user/1005/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer [JWT_TOKEN_OF_USER_1005]
# The request modified by the attacker:
GET /api/v1/user/1001/profile HTTP/1.1
Host: api.example.com
Authorization: Bearer [JWT_TOKEN_OF_USER_1005]
If the server returns the data of user 1001 with a 200 OK, it means the authorization layer of the system has collapsed.
Mass Assignment: 'I'll Give You More Than You Asked For'
Another one of our favorite topics is Mass Assignment. Modern frameworks (Node.js, Ruby on Rails, Spring, etc.) love to map the JSON object coming from the client directly to the database model. This is a great convenience for the developer but a nightmare for the security professional.
Imagine that the testCompany user registration form only has username, email, and password fields. However, in the User table in the database, there are also is_admin or account_balance columns.
An attacker might send a payload like this while registering:
{
"username": "attacker_user",
"email": "[email protected]",
"password": "P@ssword123",
"is_admin": true
}
If the backend application doesn't have a strict 'allow-list' (DTO - Data Transfer Object) and takes the incoming JSON and saves it directly to the database, the attacker just promoted themselves to admin.
Defensive Mindset: To prevent this, never trust the structure provided by the client. Always use specific models for input and validate every single field before it touches your database logic.
