You are not a penetration tester. Nobody expects you to find zero-day exploits. But as a QA engineer, you should know the common API security vulnerabilities. The OWASP API Security Top 10 is your checklist. Every company asks about it in interviews.
| # | Vulnerability | What It Means | QA Tester Action |
|---|---|---|---|
| 1 | Broken Object Level Auth (BOLA/IDOR) | User A can access User B's data via ID manipulation | Test every ID-based endpoint with another user's token |
| 2 | Broken Authentication | Weak login, no rate limiting, token flaws | Test brute force protection, token expiry, credential validation |
| 3 | Broken Object Property Level Auth | User can update fields they should not (mass assignment) | Try sending "role: admin" in a profile update request |
| 4 | Unrestricted Resource Consumption | No rate limiting — API can be flooded | Send 100 requests rapidly, check if rate limiting kicks in |
| 5 | Broken Function Level Auth | User can call admin-only functions | Test admin endpoints with user token — expect 403 |
| 6 | Unrestricted Access to Sensitive Business Flows | Automating flows that should have human checks | Test if coupon/referral flows can be abused programmatically |
| 7 | Server-Side Request Forgery (SSRF) | API fetches URLs that attacker controls | Test URL input fields with internal IPs like 127.0.0.1 |
| 8 | Security Misconfiguration | Debug mode on, default credentials, verbose errors | Check if error responses leak stack traces or DB details |
| 9 | Improper Inventory Management | Old API versions still accessible | Test if /api/v1/users works when only /api/v2 should |
| 10 | Unsafe Consumption of APIs | Blindly trusting data from third-party APIs | Harder to test — focus on input validation of external data |
Mass assignment happens when an API accepts more fields than it should. Example: a profile update endpoint accepts "name" and "email." But what if you also send "role: admin" and the server blindly updates it?
import org.testng.annotations.Test;
import static org.hamcrest.Matchers.*;
public class MassAssignmentTest extends BaseTest {
@Test
public void testUserCannotEscalateRoleViaMassAssignment() {
// Try to set role to admin via profile update
asUser()
.body("""
{
"name": "Regular User",
"role": "admin"
}
""")
.when()
.put("/users/me")
.then()
.statusCode(anyOf(is(200), is(403)));
// Verify role did NOT change
asUser()
.when()
.get("/users/me")
.then()
.statusCode(200)
.body("role", equalTo("user"));
}
@Test
public void testUserCannotModifyIsVerifiedFlag() {
asUser()
.body("""
{
"name": "Test User",
"isVerified": true,
"isActive": true
}
""")
.when()
.put("/users/me")
.then()
.statusCode(anyOf(is(200), is(400)));
}
@Test
public void testUserCannotModifyBalanceField() {
asUser()
.body("""
{
"name": "Test User",
"balance": 999999
}
""")
.when()
.put("/users/me")
.then()
.statusCode(anyOf(is(200), is(400)));
// Verify balance did NOT change
asUser()
.when()
.get("/users/me")
.then()
.body("balance", not(equalTo(999999)));
}
}import org.testng.annotations.Test;
import static io.restassured.RestAssured.*;
import static org.hamcrest.Matchers.*;
public class BrokenAuthTest extends BaseTest {
@Test
public void testErrorResponseDoesNotLeakStackTrace() {
given()
.header("Authorization", "Bearer invalid")
.when()
.get("/users/me")
.then()
.statusCode(401)
.body(not(containsString("Exception")))
.body(not(containsString("stack")))
.body(not(containsString("at com.")));
}
@Test
public void testErrorResponseDoesNotLeakDatabaseInfo() {
asUser()
.when()
.get("/users/' OR 1=1 --")
.then()
.statusCode(anyOf(is(400), is(404)))
.body(not(containsString("SQL")))
.body(not(containsString("postgres")))
.body(not(containsString("mysql")));
}
@Test
public void testPasswordNotReturnedInUserResponse() {
asUser()
.when()
.get("/users/me")
.then()
.statusCode(200)
.body("$", not(hasKey("password")))
.body("$", not(hasKey("passwordHash")))
.body("$", not(hasKey("password_hash")));
}
@Test
public void testTokenNotReturnedInNonAuthResponses() {
asUser()
.when()
.get("/users/me")
.then()
.body("$", not(hasKey("token")))
.body("$", not(hasKey("refreshToken")));
}
}If an error response contains a stack trace, database table names, or SQL errors — that is a security bug. Attackers use this information to map the system. Always check that error responses are clean and generic.
Key Point: You do not need to be a security expert. Just know the OWASP API Top 10, test for IDOR on every ID-based endpoint, try mass assignment on every PUT/PATCH, and verify error responses do not leak internal details.
Q: What is the OWASP API Security Top 10? Name a few items you test for.
A: OWASP API Security Top 10 is a list of the most critical API security risks. The ones I actively test for are: (1) BOLA/IDOR — accessing other users' data by changing the resource ID. (2) Broken Authentication — weak token validation, missing expiry checks. (3) Mass Assignment — sending extra fields like "role: admin" in update requests. (4) Broken Function Level Authorization — calling admin endpoints with a regular user token. (5) Security Misconfiguration — error responses leaking stack traces or DB info. I build specific test cases for each of these in my automation framework.
Key Point: Know the OWASP API Top 10. Test for IDOR, mass assignment, broken auth, and information leakage. You are not a pentester, but these basic checks catch critical bugs.