×

a["{"msg":"added","collection":"users","id":"***CUT***","fields":{"createdAt":{"$date":1456509130107},"services":{"password":{"bcrypt":"***CUT***"},***All personal information and IP's***

["{"msg":"sub","id":"***Random ID***","name":"usernameFromId","params":["***My user ID***"]}"]

// log() starts on websocket response and logs it to a textarea function log( text ) { $log = $('#log'); $log.append(($log.val()?"



":'')+text); if(text == 'o'){ log( "sending preload" ) // At first I included the authentication requests but after // further inspection the requests worked unauthenticated send('["{\\"msg\\":\\"connect\\",\\"version\\":\\\"1\\",\\"support\\":[\\"1\\",\\"pre2\\",\\"pre1\\"]}"]'); } if(text.indexOf("ping") !== -1){ send('["{\\"msg\\":\\"pong\\"}"]'); // invokes pong reply from server // send('["{\\"msg\\":\\"ping\\"}"]'); } }

["{"msg":"method","method":"users.findUsersByRegex","params":["***Username***"],"id":"90"}"]

As an avid gamer I will always support local esport services. One of them being Kayzr (previously besports), a Belgian based esports tournament organiser. While using their website I noticed a LOT of javascript, my analyzer gave Ink, Meteor, Moment.js, React, underscore.js, etc... And with a lot of client-sided generated content comes a lot of risks.Kayzr.com is well build with a ton of websocket traffic in order to load all the different modules on the site which creates a fast - but not very responsive ;) - website with some very cool features. With chrome we can analyze all this traffic.Whilst inspecting all the traffic while browsing the site my eyes fell on this reply. More specifically the 'password' field is what stood out the most.Out of nowhere I saw my personal information flash by: home address, email, my logged in IP's, what I assume my hashed password (probably salted, cross checked the regular hash of mine) and hashed session tokens. This is a way to much information to be send to back to a user. In the mess of the websocket traffic I didn't immediately find the correct request which triggered this response, so I kept browsing until I saw it again. Surely enough it returned a lot and found the evil function. Side note: 'usernameFromId' implies the function should only return the id from the user and not a full data dump of a user.In order to recreate the request I made my own websocket to connect to theirs with fancywebsocket.js. To succesfully create a connection I recreated their 'handshake'.When the connection was successfully made, I send the 'evil' method and it returned with all my personal info, awesome! Upon repeating the same request the server responded with an error and closed the connection. Strange. After some inspection of the id's I noticed the first 'id' is random generated used for tracking requests and when using the same id multiple times in one session the server closes the session. Now I needed the id's from other users. When using the search function on the site I found the exact function I needed.And as expected, the server returned the id's of the found usernames. And after an unauthenticated request with my own websocket, targeting my own account and bingo!, it replied.And at the end of the reply.Found leak, I was tired, went to sleepConfirmed the leakFirst contact with KayzrKayzr replied and asked to confirm with given usernameI repliedKayzr confirmed the error and deployed ASAPKayzr asked to try again, leak was fixedRewarded: 69.000 coins = A crate (24) Jupiler pilsThis wasn't a very difficult vulnerability but still one with a huge impact. Overall I'm very happy with the response of Kayzr, even though they don't have bug bounty program they greatly appreciated my help. This leak could have been used to get IP addresses of contestants of their hosted tournaments and DDOS, which can be very impactful in a game like CS:GO. Or to get home addresses for sore losers.Schol!