Picture this: you’ve just had the perfect wedding. The vows were spoken, the cake was eaten, the dance floor was packed, and an endless stream of photos captured it all. You’re floating on cloud nine, relishing in the happily ever after, when suddenly you discover your precious wedding photos, including some rather embarrassing party snaps, splashed across a stock photo site or in the hands of a blackmailer. Thankfully, this did not happen to me, but as we journey through this story, you’ll realize that this privacy nightmare is frighteningly possible.
It all started when I was planning my wedding. I sought a user-friendly app that our guests could use to conveniently share their photos from our big day with each other. Therefore, I installed some of the apps that appear on top when searching for “Party Pictures” or “Wedding Pictures” on the Android app store and advertise the option to share pictures. The concept of such apps is simple: create an event and share the invite code with your guests. Once logged in, guests could upload pictures and view other photos.
The first app I installed already promised all the required features. Yet, after creating an event, I received a 6-digit invite code, which let me question the safety of my uploaded pictures. Such a short code provides just 1 million possible combinations which makes it easy to brute force. Thus, I thought it might be worth checking the app’s general security. As it turned out, a few moments later I was able to access pictures of more than 7000 events… and all just with a simple click. Of course, I notified them, still waiting for a response or at least a fix of the issue, I decided to withhold the details until a 90-days disclosure deadline. But no worries, this app was only the beginning.
Next, I tested Wedbox as a photo-sharing app for my wedding. Same as for the app before, I registered an event in the app and it generated a 6-character invite code (characters, not digits this time). It’s not perfect but it seemed secure enough until I dug a little deeper. The app uses a WebSocket API to communicate with the server. First, it calls the endpoint /wedding_tokens/<invite code> to request information about the event from the server, such as the title or the wedding ID. From this request on, the app uses the wedding ID to upload and request pictures.
"welcomemessage":"This could be a welcome message"
Naturally, I played around with this endpoint to force an error message that would give me more information about the underlying technology. When I left the ID empty, the surprise hit me — my WebSocket connection started receiving lots and lots of data. It took me a second until I realized that the API sends information about all events when no ID is specified. And that was information about more than 300,000 weddings! Once again, I reported my findings and realized that security is probably not the number one priority for these apps — so I analyzed a few more.
Next up was Wedding Photo Swap, but it proved no better. The first thing I realized was that the password to my created event was simply the name of the partner entered during setup with the event’s default public title being “Florian and <partner name>”. This made it child’s play to invite myself to another wedding as other invite pages were again easy to find due to sequential wedding IDs (https://www.weddingphotoswap.com/<wedding ID>). However, it got worse and I even found an easier way to participate in other weddings. One of the API endpoints is used to list all wedding info for the app (/albums/displayPhotosOnApp/<wedding ID>). As you might expect, this endpoint had no safeguards preventing unauthorized users from enumerating all events and thus receiving pictures and email addresses.
And if this is not enough, the app has an unsecured endpoint that allows users to add photos to their photo album. Since this functionality was also not adequately secured, an unauthorized user could add pictures of other events to their own photo album by enumerating photo IDs. Photos from over 40,000 events were at risk because of these oversights.
My final attempt was with an app called Wedshoots that seems to belong to a bigger wedding website collection (bodas.net, hitched.co.uk, etc.). They secured their weddings with an 8-character invite code starting with the country code for each individual website.
Although that code seemed secure enough, I wanted to know whether they checked for brute force attempts (i.e., trying random invite codes automatically). Who would have guessed? They implemented no rate limiting, which means that after just a few minutes and 15k requests, I was again a guest at another party. I know, this kind of attack is boring, but nevertheless, it shouldn’t be possible. That many requests should be blocked. In addition to that, they had no XSS mitigation (e.g., CSP) but an XSS flaw in an error message and another one in the wedding name, making account takeovers possible.
Driven to frustration and time rapidly ticking away to my wedding day, I put a halt to my security experiment. My venture had included 6 apps in total of which the 4 aforementioned had significant security flaws (Celebrate and The Big Day both seemed to have a better handle on user security; however, it only means that nothing struck me immediately). Since more than half of the apps I tested had critical issues, I decided to take matters into my own hands and built my own solution, which worked flawlessly during our wedding.
So what happened after the wedding? To my disappointment, I never heard back from most, only one company acknowledged the security concerns I’d brought to their attention, and still one has not fixed the vulnerabilities. This is sad to read but, unfortunately, the reality for the security in our world wide web. I mean, of course no product is perfect and sometimes, even the most stringent security audits might overlook a loophole. However, the least you could do is be responsive when someone brings it to light. Creating an easy solution for researchers to report findings on your site, perhaps by using a security.txt or providing a dedicated contact, would be a good first step.
And in retrospect, what can we take away from this? Clearly, the security state of such apps is miserable. They reflect perfectly web priorities today — usability over security, resulting in user information and pictures of more than 300,000 events being exposed on the internet. What makes me frustrated is the fact that these problems are easily avoidable as a few tiny modifications to the source code would make such apps significantly more secure: brute force detection, random event IDs like UUIDs, longer invite codes embedded in invite URLs or QR codes and secure APIs — that’s no magic, that’s common practice every developer should know and learn about. And even worse is the silence of these companies. It makes me angry to see companies ignore glaring issues or remain mute even when fixing them. A simple word of appreciation would be enough!
Stepping into married life and peering into the future, I can only hope that we soon see a more security-aware digital landscape. Until that day arrives, the responsibility unfortunately lies solely on us, the users, who need to be cautious and vigilant about the apps we trust with our precious moments. After all, the last thing we want on our special day is an uninvited guest.
02.06. I notified [First App]
04.06. I notified Wedbox
11.06. I notified Wedding Photo Swap
12.06. I notified Bodas.net, and asked Wedbox and [First App] for a status update
20.06. I asked for Bodas.net and Wedding Photo Swap for a status update
26.06. I asked the German CERT-Bund for help contacting [First App] and Wedding Photo Swap
28.06. I received confirmation that the German CERT-Bund had notified [First App] and Wedding Photo Swap
19.07. I received a mail from Wedding Photo Swap that they are fixing the problem
Prior to publishing this post, I offered each company an opportunity to give a statement on the issue, but unfortunately, I received no response.