Skip to content
Field Detail
Platform PortSwigger Web Security Academy
Type Authentication — Broken Brute-Force Protection, Array-Based Bypass
Difficulty Expert
Objective Brute-force Carlos's password, then access his account page
Note Victim username carlos

Broken Brute-Force Protection, Multiple Credentials per Request

Trying to log in as carlos:teto revealed that the login endpoint accepts JSON:

Screenshot
POST /login HTTP/2
Host: 0a1a001d035ed8c480d7cc3000d30003.web-security-academy.net
Cookie: session=SufzEI9hlUo3VeSxn1BJbatcKYDE2gHc

{"username":"carlos","password":"teto"}

Since password is a JSON value rather than a flat form field, it doesn't have to stay a single string — JSON allows arrays. If the backend iterates the array and accepts a match against any element, every candidate gets tried inside a single HTTP request. Brute-force protection that counts failed login attempts is completely blind to this: the entire wordlist arrives as one request, so there's no volume to rate-limit or lock out against.

I built a JSON array from the candidate password wordlist:

 cat passwords | while read line; do echo "\"$line\","; done > password2

producing a password field like:

"username":"carlos","password":["123456",
"password",
"12345678"
(...)]
Screenshot

Sending the request with the full array returned a 302 Found — the server found a match somewhere inside it and succeeded the whole request. The response carried a valid session cookie for Carlos. I added it to the browser:

Screenshot

Clicking "My account" confirmed the session was valid. This isn't brute-forcing one password at a time — it's exploiting how the backend processes the field when given an array instead of a scalar. JSON-based login endpoints deserve a structural check beyond "what's a valid value here": testing whether a normally-scalar field accepts an array, object, or other JSON type can surface this kind of logic flaw before any traditional brute-force approach even gets started.

Lab solved :P

Resources