Answer
API Security Testing
API security testing verifies that APIs are protected against common attacks and vulnerabilities. The OWASP API Security Top 10 is the industry standard reference.
OWASP API Security Top 10
1. Broken Object Level Authorization (BOLA/IDOR)
Accessing another user's data by changing the ID:
Java
@Test
public void testIDORVulnerability() {
// User 1 should NOT be able to access User 2's orders
given()
.header("Authorization", "Bearer " + user1Token)
.when()
.get("/api/users/2/orders") // accessing user 2 as user 1
.then()
.statusCode(403); // Must be 403, NOT 200
}
2. Broken Authentication
Java
@Test
public void testWeakPassword() {
given()
.body("{ \"username\": \"admin\", \"password\": \"123\" }")
.contentType(ContentType.JSON)
.when()
.post("/api/auth/login")
.then()
.statusCode(400) // Should reject weak passwords
.body("error", containsString("Password too weak"));
}
@Test
public void testBruteForceProtection() {
// After 5 failed attempts, should get 429
for (int i = 0; i < 5; i++) {
given().body("{ \"username\": \"admin\", \"password\": \"wrong\" + i }")
.contentType(ContentType.JSON)
.when().post("/api/auth/login");
}
given().body("{ \"username\": \"admin\", \"password\": \"wrong6\" }")
.contentType(ContentType.JSON)
.when().post("/api/auth/login")
.then().statusCode(429); // Too Many Requests
}
3. Excessive Data Exposure
Java
@Test
public void testNoSensitiveDataExposed() {
Response response = given()
.when()
.get("/api/users/1");
String body = response.getBody().asString();
// Sensitive fields should NOT appear in response
assertFalse(body.contains("password"), "Password should not be in response");
assertFalse(body.contains("credit_card"), "Credit card should not be in response");
assertFalse(body.contains("ssn"), "SSN should not be in response");
}
4. SQL Injection
Java
@Test
public void testSQLInjectionInQueryParam() {
given()
.queryParam("id", "1 OR 1=1")
.when()
.get("/api/users")
.then()
.statusCode(anyOf(equalTo(400), equalTo(404)))
// Should NOT return all users due to SQL injection
.statusCode(not(200));
}
@Test
public void testSQLInjectionInBody() {
given()
.body("{ \"username\": \"admin'' OR ''1''=''1\", \"password\": \"x\" }")
.contentType(ContentType.JSON)
.when()
.post("/api/auth/login")
.then()
.statusCode(anyOf(equalTo(400), equalTo(401)))
.statusCode(not(200)); // Must NOT succeed
}
5. Lack of Rate Limiting
Java
@Test
public void testPasswordResetRateLimited() {
for (int i = 0; i < 10; i++) {
given().body("{ \"email\": \"user@test.com\" }")
.contentType(ContentType.JSON)
.when().post("/api/auth/forgot-password");
}
given().body("{ \"email\": \"user@test.com\" }")
.contentType(ContentType.JSON)
.when().post("/api/auth/forgot-password")
.then().statusCode(429);
}
6. Mass Assignment Vulnerability
Java
@Test
public void testMassAssignmentProtection() {
// User should NOT be able to set themselves as admin
given()
.header("Authorization", "Bearer " + userToken)
.body("{ \"name\": \"John\", \"role\": \"admin\", \"is_admin\": true }")
.contentType(ContentType.JSON)
.when()
.put("/api/users/profile")
.then()
.statusCode(200)
// Role should remain 'user', not 'admin'
.body("role", not(equalTo("admin")));
}
Security Test Checklist
| Vulnerability | Test |
|---|---|
| BOLA/IDOR | Access other users' resources |
| Broken Auth | Brute force, weak passwords |
| Data Exposure | Check for sensitive fields in response |
| SQL Injection | Inject SQL in params and body |
| Rate Limiting | Flood endpoint, check 429 |
| Mass Assignment | Try to set privileged fields |
| CORS | Test unauthorized origins |
| JWT | Test expired/tampered tokens |
