Every year during March Madness, my company’s landlord runs a bracket challenge, in which all tenants are free to join and submit their picks. They offer some prizes to the top bracket submissions, using CBS Sports’ March Madness bracket manager to manage the submissions and calculate the winners. I don’t know a lot about basketball, but I was certainly interested in how secure the bracket manager application was. I decided to research the process of submitting my own picks.

Before you can submit a bracket, you must first join a bracket pool. This is usually password-protected and understandably has a cut-off date, meaning a user can’t join the bracket past a specific date (chosen by the bracket administrator). Being that I was joining the challenge very close to the cut-off, I decided to record the request used to join the pool. After the cut-off date, I intended on manually joining the pool with the same request (using a different account). That request looked like this:

// Assuming test user is already logged in $post_data = array( 'dummy::form' => '1', 'form::form' => 'form', 'form::_eid_' => 'U2FsdGVkX1979oCGIr2AL8eM0iP-c7z6VnKl8Xfa0TBuTzKgDDKfTQV24rNCNrOs', 'form::password' => '***REMOVED***', '_submit' => ' OK ' ); curl("http://kpg1.mayhem.cbssports.com/e", $post_data);

Success! The lockout wasn’t being enforced server-side, rather just the display logic was changed to suggest the pool was now closed. Not a very serious vulnerability, but interesting nonetheless. I wondered what else there might be.

Next up was to actually submit my bracket. Again, users were allowed to submit their bracket up to a specific time, after which no more submissions would be allowed, nor could they be edited as the results of March Madness became known. Right?! While submitting my bracket, I noticed a very interesting parameter in the payload of the POST here:

{ "team_id": "REMOVED", "manager_action": "0", "bracket_number": "1", "tiebreaker": null, "action": "save", "validate_picks": 1, "picks": [ "REMOVED" ] }

Is the application relying on the client to determine if the requesting user is a manager? Let’s hope not! I waited until bracket submissions were closed and attempted to send a POST request with some new picks, changing the “manager_action” in the payload to “1”. Surprisingly, the request was successful and my picks were updated. This could potentially be a very serious vulnerability, since an ordinary user could likely run any bracket functions as the “bracket manager”. This might include viewing the contact information for other participants, up to compromising the integrity of the entire pool’s results. Time to responsibly disclose the vulnerabilities CBS Sports and get it fixed.

Contact info for CBS Sports was a little difficult to find. Eventually, I was able to get in contact with a member of their security team, who had a patch out rather quickly. Here’s the timeline:

2014-03-20: Vulnerabilities identified and initial emails sent for contacts/reporting

2014-03-25: Contact reached and proof-of-concept delivered

2014-03-28: Confirmation of deployed fix

CBS Sports was very receptive of the report and extended their appreciation for my findings.

Share this: