Hacking FIFA World Cup Rosters
I think one of the first signs of “ohhhhh they really fucked up” was seeing the passport number for the barber listed for a national team in last year’s 2022 Qatar FIFA™ World Cup®™.
Here’s a quick story of how I spent the run-up to the World Cup last November. If you’re one of those people who love reading detailed, cutting-edge technical analysis of security vulnerabilities available in the platform that runs the largest event on the planet… well, give an actual security researcher’s blog a try, because this story has none of that.
The killer technology used in this exploit is just three keyboard keys: command, C
, and V
. Copy and paste, baby.
“Huh. That URL looks interesting.”
Virtually anyone who has ever seriously created software for the web has (at least) one sick compulsion: we look at URLs differently. Can’t help it. We all make (at least!) one fuck-up early in our career and the rest of our lives are spent making sure we don’t fuck up the URL again.
One of my other sick compulsions is soccer. (Or football, for you freaks who later renamed the sport.) Love playing it, love watching it, love reading about it, love it all.
The name of the game is eNgAGemEnT these days, so most clubs and national teams love pushing behind-the-scenes videos: the players in training, the players doing weird shit like cooking on-camera, the players answering questions about Taylor Swift, things like that. Ahead of the World Cup, many national teams record things like the manager FaceTiming individual players and letting them know they made the roster.
One of the hip things to video was a staffer pressing the actual submit button on the official roster submission into FIFA. Neat! See, the button means it’s been sent off and now we’re actually ready to head to the World Cup! How exciting! ENGAGEMENT!!!
This is where both my compulsions met up: one of the national teams included the URL bar in their behind-the-scenes footage. Basically something like this:
https://<roster submissions>.fifa.org/<sub directory>/45f8c989-4860-477e-8918-eef38805dc96
Those readers who are software developers will immediately notice the UUID at the end of the URL and already have this whole post figured out, of course, because you’re all a bunch of sick bastards. But I’ll dig into it a bit more.
It’s one URL, Michael. What could it cost? 10 dollars?
Any URL with a bunch of random characters in it will tend to raise eyebrows- though most of the time it won’t lead to security issues, sometimes it means the software developer is shoving something important where it shouldn’t be. In this case, it’s the key to the user session, which lets you do a kind of session fixation attack in order to hijack their session.
In basic terms, by having access to that URL, it’s like giving out the user’s username and password to log in as them. So like… yeah, not ideal, and something you learn pretty early on not to do. This is why it’s like catnip to developers; interesting-looking URLs are an exciting game of “oh shit, did they fuck that up?!”
cmd+c, cmd+v
This is always an easy thing to test- you just type in the URL and see what happens. But now that Apple has Live Text you can just screenshot the video, highlight the URL, copy it and paste it, so it’s just laughably easy to test these things out.
In this case, you get dropped into FIFA’s internal national team management portal, logged in as whichever staffer clicked the button in the video.
A couple interesting things that could be seen here:
- The full 55-player provisional roster, in addition to staff, as well as all their DOB, passport numbers, legal name, things of that nature.
- The full 26-player final roster and staff (including team barber and videographers and I think there was even a team chaplain listed).
- The submission of uniform colors, flags, national anthem music, and similar details.
- Legalese of team agreements to participate, similar documents.
This was fairly alarming, and it raised the question of whether you could actually submit a new roster. My life-long dream of participating in a World Cup was inching closer and closer to reality (and all these other suckers had to work hard on their bodies for decades to get to that point, pffft! Shoulda just copied and pasted!)
The team I was looking at had already made their official roster submission, but the code was still there to make a submission. I believe they literally just commented out the form rather than hide it server-side, so it would have been pretty trivial to use the existing HTML to try crafting a new roster submission and seeing if that worked.
Alas, I am no World Cup-caliber talent, and it started feeling like wrapping up was the sensible thing to do. Read-only access is one thing, mutable access is another, and the latter is more questionable when your goal is to map out the vulnerability to get patched up.
Responsible disclosure
One of the main takeaways besides “don’t write broken code” is to also assume you’re going to write broken code anyway and make it easy to report these problems to the right people. FIFA failed a bit on that account, but also did a lot better than I expected.
FIFA doesn’t have a specific responsible disclosure policy (although as an interesting side note, they do have a reporting system for disclosing physical safety concerns for children and vulnerable adults- goes to show that so often when we talk about “security” in the software industry, we forget how many organizations must describe “security” as far broader than just “software security”).
In lieu of an obvious reporting mechanism, I emailed contact@
and security@
, but also eventually found a more buried page about data protection (thank you EU!), and they were able to forward me to an information security email address for FIFA, in which case you kind of breathe a sigh of relief, because you finally found someone who knows something.
The process went really smoothly, in spite of global timezones. Took them a day or two to make changes to at least invalidate the session in question, which is pretty impressive considering the World Cup kicked off at that same time so I imagine they were pretty busy. I also contacted the federation who took down the original video within a couple hours and replaced it with the URL cut out of the shot (although strangely they never actually replied to my messages).
There are still some lingering concerns I had that I wasn’t able to confirm that they fixed up (can you iterate over the simple team ID parameter used all over the place to gain access to every team’s roster? etc), but such is software.
A happy ending!
A silly little error, sure, but I was pleasantly surprised to see a responsive technical team for a large organization able to make corrections quickly. AND! They’re going to give me a gift!
As a small sign of appreciation and only I you want, the FIFA Data Protection and Cybersecurity Risk team would like to send you a small gift. If you are interested, please share with us your contact details, where we could send you something.
So cool! Anyway, it’s been eleven months and I still haven’t received anything, FIFA. Maybe I fucked up with an address only on one continent instead of the obvious three that’s needed for some reason. My bad.