Break a login.
Then prove it.
One real bug, two tools. Catch a login request, flip a single field in Repeater to bypass auth, then load Intruder to prove it's genuine SQL injection — not a fluke. Target: OWASP Juice Shop.
(!) Every request here really happened. Real bytes from a local Juice Shop (2026-06-14), captured and replayed. Point Hugin only at targets you are authorized to test.
Send it once.
Change one field.
Repeater is for the careful, hand-driven probe. Take one request, edit it, fire it, read the response — no browser in the loop. Here's the Juice Shop login. With real credentials it answers 401. Edit the email field — type ' OR 1=1-- — and press Send.
POST /rest/user/login HTTP/2 host: juice-sh.op content-type: application/json content-length: 49 {"email":"test@juice-sh.op","password":"hunter2"}
HTTP/2 401 Unauthorized content-type: text/html; charset=utf-8 content-length: 26 Invalid email or password.HTTP/2 200 OK content-type: application/json; charset=utf-8 content-length: 799 {"authentication":{"token":"eyJhbGciOiJSUzI1NiJ9.eyJzdGF0dXMiOiJzdWNjZXNzIiwiZGF0YSI6…", "bid":1,"umail":"admin@juice-sh.op"}}HTTP/2 500 Internal Server Error content-type: text/html; charset=utf-8 content-length: 1449 OWASP Juice Shop (Express ^4.22.1) 500 Error at Database.<anonymous> (…/sequelize/lib/dialects/sqlite/query.js:185:27) … 5 more stack frames
● You are now the administrator.
The 200 carries a signed session token. Drop it into Decoder and the JWT claims are plain:
"id": 1, "email": "admin@juice-sh.op", "role": "admin", "iat": 1781454986
No password was ever known. The login query trusted unescaped input, so ' OR 1=1-- matched the first row — which is the admin.
Prove it's
injection.
Was that one payload a coincidence? Mark the email field as the position, feed Intruder a short list of probes, and fire a sniper attack. Sort by length — the bypasses and database errors separate themselves from the noise.
' OR 1=1-- → 200, but ' OR 1=2-- → 401. The response tracks the condition — textbook boolean SQL injection.
A single ' returns 500 with a 1,449-byte error page. The parser choked — input reaches the SQL engine raw.
26 B is rejection, 799 B is a token, 1,449 B is a stack trace. Sort the column and the bugs rise to the top.
Run it
yourself.
Nothing here is special-cased. Stand up the same sandbox and walk the same path. ~5 minutes, your machine.
Start the sandbox
Run a throwaway Juice Shop in Docker — it's built to be broken.
docker run --rm -p 3000:3000 bkimminich/juice-shopProxy through Hugin
Launch Hugin, set your browser's proxy to 127.0.0.1:8080, trust the CA, log in once so the request lands in history.
huginRepeat & fuzz
Right-click the login → Send to Repeater, swap the email, resend. Then Send to Intruder, mark the field, paste the payloads, attack.
The built-in scanner finds this same class of bug without the manual steps.