How I Reverse Engineered BeReal
So BeReal had this annoying rule where you couldn’t see your friends’ posts unless you posted your own picture first. Every day, at a random time, the app would send a notification. You’d have two minutes to take a photo. Front and back camera at the same time, no filters, no retakes. Just raw, unedited life.
I mean it is a cool concept. But when you are not a party guy and rarely do anything others would find interesting, the idea of being forced to post something just to see what my friends are up to, doesn’t appeal to me. So i either had the option to uninstall the app, or post a random photo of my ceiling every day. Neither option was appealing.
So instead, I decided to figure out how BeReal actually works under the hood for security analysis purposes. Turns out, it wasn’t that hard to bypass their entire posting requirement.
UPDATE: This no longer works. BeReal has since changed their API to require a valid post before returning any data. But the process of reverse engineering the app is still the same, and the code is still available on GitHub if you want to check it out.
The Plan
The goal was simple for me was actually quite simple. I wanted to see if i could scrape all the data from BeReal without posting anything. This meant my friends’ photos, and surprisingly their exact geolocations, comments, reactions, everything. All without the app knowing I was lurking.
To do this, I needed to understand how the app talks to BeReal’s servers. This meant figuring out what API endpoints the app was hitting, what data it was sending, and how it was authenticating those requests.
So to begin with, this meant reverse engineering, or in other words, intercepting the traffic between the app and the servers to see exactly what was going on. Once I had that information, I could write a script to mimic the app’s behavior and pull all the data I wanted.
Step 1: Intercepting the Traffic
So the first problem was, how do you see what an app is sending to its servers? Mobile apps don’t have a built-in way to show you their network traffic. You can’t just open DevTools like you would with a website.
So, to my rescue, came Charles Proxy. If you haven’t heard of it, it’s a popular tool for web developers and security researchers to inspect and debug network traffic. It’s like Wireshark but for HTTP/HTTPS traffic, and it’s super user-friendly.
But this also means that Charles Proxy is basically a man-in-the-middle tool that sits between your phone and the internet. It captures every single HTTP request your phone makes and shows you exactly what’s being sent and received. It’s super useful for this kind of thing.
Here’s what I did:
- Downloaded Charles Proxy on my iPhone
- Set it up to intercept HTTPS traffic (which requires installing a certificate)
- Configured my iPhone to route all traffic through Charles
- Opened BeReal and clicked around
Charles immediately started showing me everything. Every API call. Every endpoint. Every piece of data going back and forth.
The goldmine was watching what happened when I opened the app. BeReal was making requests to endpoints like:
https://mobile.bereal.com/api/feeds/friendshttps://mobile.bereal.com/api/feeds/discoveryhttps://mobile.bereal.com/api/feeds/memories
Each one returned a massive JSON response with all the data the app needed. Photos, usernames, locations, timestamps, everything.
Step 2: Finding the Authentication
But there was a catch. You can’t just hit those endpoints directly. BeReal’s API requires authentication. Every request needs to prove you’re a real user, not some random person trying to scrape data.
This is where it got interesting.
I noticed that every API request included two important tokens in the headers:
- An access token (short-lived, expires quickly)
- A refresh token (long-lived, used to get new access tokens)
The access token is what actually authenticates you. But it expires after a while, so you need the refresh token to get a fresh one without logging in again.
Digging through Charles, I found a request to https://securetoken.googleapis.com. This was BeReal’s authentication endpoint. The request included a refreshToken in the body, and the response gave back a new access token.
Perfect. If I could grab that refresh token once, I could keep generating new access tokens whenever I needed them.
Step 3: Extracting the Tokens
Getting the tokens was surprisingly easy:
- Open Charles Proxy
- Start recording traffic
- Open BeReal and let it load
- Stop recording
- Find the request to
securetoken.googleapis.com - Copy the refresh token from the request body
- Save it
That refresh token is simply gold. As long as it’s valid, I can keep accessing BeReal’s API without ever logging in through the app again.
Step 4: Building the Scraper
Now that I had the tokens, I could build a script to automate everything.
For this, I wrote a Python script that does the following:
- Takes the refresh token from an environment variable
- Sends a request to the authentication endpoint to get a fresh access token
- Uses that access token to hit whatever BeReal endpoint I want
- Saves the JSON response to a file
Here’s basically how it works:
# Get a fresh access token
auth_response = requests.post(
'https://securetoken.googleapis.com/v1/token',
params={'key': API_KEY},
data={'refresh_token': REFRESH_TOKEN}
)
access_token = auth_response.json()['access_token']
# Use it to fetch data
headers = {'Authorization': f'Bearer {access_token}'}
response = requests.get(
'https://mobile.bereal.com/api/feeds/friends',
headers=headers
)
# Save the data
with open('bereal_data.json', 'w') as f:
json.dump(response.json(), f, indent=2) Super simple. But it worked perfectly.
What I Could Access
Once I had this working, I could basically pull everything:
Friends Feed - All the posts from people I’m connected with. Their photos (both front and back camera), exact timestamps, whether they posted late, their location data, comments, reactions, the whole thing.
Discovery Feed - Public posts from random users around the world. BeReal has this feature where some people choose to make their posts public, and you can browse them. I could scrape all of that.
Memories - Your own past posts. BeReal saves all your old photos in a “memories” section. I could download all of mine at once.
Friend Suggestions - The app recommends people you might know. I could see exactly who was being suggested and why.
Contact Data - The app scans your contacts to find friends. I could see what contact data it was accessing.
All of this without posting a single photo myself.
Why This Works
The thing is, BeReal’s API doesn’t actually check if you’ve posted today. It just checks if you’re authenticated. Once you have a valid access token, the API happily gives you whatever you ask for.
The app enforces the “post before you view” rule on the client side, meaning it’s just the app deciding not to show you stuff unless you post. But the API doesn’t care. If you bypass the app and talk directly to the API, that restriction disappears.
This is a pretty common security issue with apps. Developers trust the client (the app on your phone) to enforce rules, but anyone who knows how to use an HTTP client can just ignore those rules and talk to the API directly.
The Ethical Question
Now, you might be thinking: “Wait, isn’t this kind of sketchy?”
Fair question. Here’s my take:
I’m only accessing my own account and data that’s already being shown to me in the app. I’m not hacking into other people’s accounts. I’m not stealing private data. I’m just viewing the same stuff the app would show me, but without the artificial restriction of having to post first.
It’s like if a website said “you have to click this button before you can scroll,” and you just opened DevTools and scrolled anyway. You’re not breaking in. You’re just removing an annoying requirement that doesn’t actually protect anything.
That said, I’m not encouraging anyone to scrape BeReal at scale or do anything malicious with this. It’s just a cool technical exercise in understanding how apps work.
What BeReal Could Do
If BeReal wanted to actually enforce their posting requirement, they’d need to change how their API works. Instead of just checking authentication, the API would need to verify that you’ve posted within the last X hours before returning any data.
Something like:
if not user.has_posted_today():
return {"error": "Post something first"} Right now, that check only happens in the app, not on the server. That’s the vulnerability.
They could also implement rate limiting, monitor for suspicious access patterns, or use device fingerprinting to detect when someone’s accessing the API outside the official app. But all of that adds complexity and cost.
For a small social app, they probably just decided the client-side restriction was good enough. And honestly, for most users, it is. Most people aren’t going to fire up Charles Proxy and start reverse engineering the API.
What I Learned
This whole thing taught me a few things:
Apps are just API wrappers. Most mobile apps are basically just pretty interfaces for APIs. If you understand the API, you understand the app.
Client-side restrictions are suggestions. Never trust the client. If you want to enforce a rule, enforce it on the server.
Authentication is separate from authorization. BeReal’s API checks if you’re logged in, but it doesn’t check if you’re allowed to see specific data based on whether you’ve posted. Those are two different things.
Tools like Charles Proxy are incredibly powerful. Being able to see exactly what an app is doing makes reverse engineering way easier than you’d think.
The Code
I put the whole thing up on GitHub if you want to check it out or mess with it yourself. It’s a pretty simple Python script that handles the authentication flow and lets you fetch data from different BeReal endpoints.
You’ll need to get your own tokens using Charles Proxy, but once you have those, it’s just a matter of running the script and watching the data pour in.
Fair warning: BeReal could change their API at any time and break this. They could also decide to ban accounts that access the API outside their official app. Use at your own risk.
