QA Interview Hub · Knowledge base · Quizzes

API

API security

OWASP API Top 10: access and authentication

The OWASP API Security Top 10 is a list of the most common API risks. QA doesn't have to be a pentester, but everyone should do the basic checks from it.

BOLA (Broken Object Level Authorization), a.k.a. IDOR, is first on the list. A user changes the id in the URL or body and gets someone else's object: GET /accounts/43 with the token of the owner of account 42. The check: two test users, the first one's resource is requested with the second's token, and we expect 403 or 404. I check all methods, not only GET: someone else's account can also be changed and deleted.

Broken Function Level Authorization: an ordinary user calls an admin function, for example DELETE /admin/users/5, because the front end just hides the button and the server doesn't check the role.

Broken Authentication: weak spots in login and tokens:

  • There is no limit on login attempts, and a password can be guessed.
  • A token isn't invalidated after logout or a password change.
  • A token is passed in the URL and ends up in logs.
  • Changing a password or email without re-confirmation.
In an interview: The most important thing in API security is BOLA, or IDOR: I check access to someone else's resource with another user's token for all methods. I also check admin functions under an ordinary role and the handling of tokens: logout, the login attempt limit, invalidation after a password change.

Excessive data, mass assignment, injections, rate limiting

Excessive data exposure: the API returns more than the UI shows, hoping the front end will filter it. A profile response may include a password hash, internal flags, a full card number. I check the raw JSON, not the screen, and use a schema with additionalProperties: false.

Mass assignment: the server binds the whole request body to a model. A user adds "role": "admin" or "balance": 1000000 to PATCH /users/me, and it is saved. The test: send fields that the client has no right to change and check through GET that they didn't change.

{ "name": "Ivan", "role": "admin", "isVerified": true }

Injection: SQL, NoSQL or command injection through parameters. I basically check quotes, ' OR 1=1--, special characters and very long strings in fields and the query: the response must be a 4xx or a correct result, with no 500 and no SQL error in the body.

Rate limiting (in the current list, unrestricted resource consumption): without limits an API can be DDoSed or SMS codes can be brute-forced. I check that after the limit a 429 with Retry-After arrives, and that the limit applies per user or IP, not only per endpoint. Separately, page and file sizes: limit=100000 must not bring the service down.

In an interview: I look at the raw JSON for extra sensitive fields, try mass assignment by adding role or balance to the body, and basic injections in string fields. I also check rate limiting: after the limit there must be a 429, not endless attempts.

JWT traps

I already know the structure of a JWT and the basic token tests; here are the typical vulnerabilities asked about at the senior level.

  • The none algorithm. An attacker sets "alg": "none" in the header and removes the signature. A server that trusts the alg field will accept such a token. Expected: 401.
  • Swapping RS256 for HS256. A server with an asymmetric key accepts a token signed symmetrically with its own public key. A correct implementation hard-codes the expected algorithm.
  • A weak HS256 secret. A short secret can be brute-forced offline, and then any payload can be signed.
  • Sensitive data in the payload. The payload is only encoded, so an email, phone or account number is visible to everyone.
  • No check of exp, aud, iss. A token from another service or environment must not be accepted.
  • Inability to revoke a token. A JWT is stateless, so after logout or blocking a user the access token lives until exp. The protection is a short access token lifetime, refresh token rotation and a denylist for critical cases.

For tests I decode the token (the payload is readable without a key), change the role or sub and send it without re-signing, and I also check a token from stage on dev.

In an interview: Besides an expired and a corrupted token, I check alg: none, a token from another environment and sensitive data in the payload. I also ask how the team revokes tokens, because a JWT is stateless and after logout lives until exp.