TripBFF exposed recent live latitude & longitude data and birth date for every user on their platform
TL;DR: The TripBFF App, which the founders say have over 1M downloads, 100k active users, and earns them over $1M ARR was found to be exposing exact user location and exact birthdays via an internal API to any end-user. We also found that we could move our location to any point in the world, and enumerate the local users in that area, giving us an accurate recent app-open location of every single active user on the app.
The TripBFF founders were incredibly receptive to our report and immediately fixed the identified privacy exposure. We were impressed with the rapid response by the TripBFF team. However, after initially responding warmly to the reported issues, the TripBFF team ended up ghosting, leaving a few open and unanswered questions.
I’m currently living the life of a digital nomad, traveling the world. I’ve been looking to meet fellow world travelers. When I saw the app TripBFF mentioned in a Reddit post I got curious. I installed the app and paid for a pro account. After poking around a bit, I was confronted with a map of Seattle with location pins of everyone using the app in the City.
While the app’s map prevented users zooming in far enough to get an accurate location on other users visually, my security research spidey sense was saying, “Huh, that location pin for me looks surprisingly accurate, I wonder what the client is receiving on the backend”. I was concerned that the zoom fidelity filter was only at a visual level within the app; so, I decided to take a deeper look.
Enter Adam Baldwin (aka. EvilPacket)
Adam and I have been friends since 2019. We first met at Microsoft’s micro-conference Package Con where a bunch of package maintainers came together to discuss the security of packaging ecosystems. At the time, I was representing Gradle, and Adam was representing pre-acquisition NPM. Over the years, I’ve called Adam up when I’ve been in over my head and have always appreciated his mentorship and support.
Adam lives in the greater Seattle area, and since I was in town, I figured I’d drive up to see him. I mentioned to him this app that I’d found earlier in the day and my curiosity regarding the map and we decided to sit down and take a crack at it.
Hacking TripBFF
I'd never tried any form of mobile hacking before, so this was an awesome opportunity to get my feet wet with someone more experienced than myself. In order to just get a bit of information regarding what internal tooling/libraries we were working with I decided to take a quick peek at the iOS application.
Initial pass was to download the iOS binary ipa file with a helpful tool called ipatool (majd/ipatool). This gave me insights into the libraries being used under the hood, including nanopb, Google Firebase, and MapBox for map rendering.
I was thinking that in order to do any dynamic testing, I was going to need to work with the app with something like Corellum, but Adam said "why don't we just intercept the traffic with BurpSuite". This isn't something I'd ever done before but after following PortSwigger's rather short and straightforward guide I was seeing HTTP traffic from my phone!
Aside: If trying to reproduce this, ensure you're not on a WiFi network at an internet cafe or library. Many public networks, and home guest networks - if securely configured - will have client isolation enabled, meaning this will not work. I tried to figure out how to make this work with TailScale, unfortunately without success. Late into this research I discovered ProxyMan for iOS that allows you to do this sort of on-device HTTP request/response inspection and rewriting without needing to route your HTTP traffic through your computer.
Findings
Although I’d chosen to sign up for the TripBFF premium trial, Adam did not. As such, we got the opportunity to observe how the application behaved differently between the two of us.
Looking at all the requests, we quickly saw the primary authentication mechanism for the back-end servers is a JWT token sent in the Authorization: header. This is generally easy to spot when you see a long string of characters that begin with eyj or even just ey.
You’re initially ”shadowBanned”: true
One of the first requests Adam saw was a call to POST /checkShadowbanStatus which, for his account, seemed to initially return "shadowbanned":true. Adam used a simple Burp find-and-replace rule to configure the proxy so that the endpoint always returned "shadowbanned":false instead. We believed that this would begin to unlock functionality of the app.
Ethan Brimhall, TripBFF’s CTO stated that: “This has nothing to do with paying customers and new users are not initially shadowbanned. We have an extensive algo to determine if a user is "spam" that is checked on every app open. Additionally, the "result" from that function does absolutely nothing client side. It’s always validated on the server.”
Given this context from Ethan, we’re not sure why the client makes a request for this API, but regardless, the API is one of the first API calls made when the app initially opens.
Request
POST /checkShadowbanStatus HTTP/2
Host: us-central1-travely-9bfbf.cloudfunctions.net
Accept: */*
Content-Type: application/json
Firebase-Instance-Id-Token: ...
Accept-Language: en-US,en;q=0.9
User-Agent: com.tripbffllc.Travely/7.2.1 iPhone/18.6.2 hw/iPhone15_3
Authorization: Bearer eyj...
Accept-Encoding: gzip, deflate, br
{
"data": {
"age": {
"@type": "type.googleapis.com\/google.protobuf.Int64Value",
"value": "31"
},
"gender": "Male",
"userCountryCode": "US",
"firstName": "Jonathan"
}
}
Response
{
"result": {
"shadowbanned": false
}
}
Location Data Sent to TripBFF Servers
After the POST request to /checkShadowbanStatus, the next interesting request we see sent from the TripBFF app to the backend servers is a POST request to /updateLocation. This seems to be how the app tells the TripBFF servers where you are in the world both via the 7 digit “geoHash”, and the ”latitude” and “longitude” values. The “neighbors” are also the neighboring geohash values of the 4 digit geoHash area surrounding the more precise “geoHash” value.
Request
POST /updateLocation HTTP/2
Host: us-central1-travely-9bfbf.cloudfunctions.net
Accept: */*
Content-Type: application/json
Firebase-Instance-Id-Token: ...
Accept-Language: en-US,en;q=0.9
User-Agent: com.tripbffllc.Travely/7.2.1 iPhone/18.6.2 hw/iPhone15_3
Authorization: Bearer eyJ...
Accept-Encoding: gzip, deflate, br
{
"data": {
"countryCodeOriginal": "US",
"geohash": "9qteue9",
"firstName": "Jonathan",
"age": {
"value": "31",
"@type": "type.googleapis.com\/google.protobuf.Int64Value"
},
"longitude": -115.815715000000000,
"latitude": 37.241223000000000,
"neighbors": [
"9qte",
"9qts",
"9qtu",
"9qtg",
"9qtf",
"9qtd",
"9qt6",
"9qt7",
"9qtk"
],
"travelLifestyle": "💻 Digital nomad",
"urlSmall": "https:\/\/firebasestorage.googleapis.com\/v0\/b\/travely-9bfbf.appspot.com\/o\/0rfqyEhcF5WBVXgtG1dGSfC7wN42-thumbnail?alt=media",
"country": "United States",
"gender": "Male",
"countryOriginal": "United States"
}
}
Response
HTTP/2 200 OK
Vary: Origin
Content-Type: application/json; charset=utf-8
Function-Execution-Id: ...
X-Cloud-Trace-Context: ...
Date: Wed, 10 Sep 2025 03:31:18 GMT
Server: Google Frontend
{
"result": {
"success": true,
"message": "Location updated successfully"
}
}
Exposing Location Data that is waaay too Accurate
One of the first things we spotted was a POST request to /fetchNearbyUsers. This POST request takes four arguments: isPremiumUser, latitude, longitude, and geoHash. The latitude, longitude, and geoHash values come from the user’s current location, except when they’ve used the in-app “Teleport” feature to move to a different location. Of course, for Adam isPremiumUser was false but for me, it was true. Again, with another few configuration tweaks to the Burp Proxy, and any proxied requests to /fetchNearbyUsers would automatically get set to true.
Request
POST /fetchNearbyUsers HTTP/2
Host: us-central1-travely-9bfbf.cloudfunctions.net
Accept: */*
Content-Type: application/json
Firebase-Instance-Id-Token: ...
Accept-Language: en-US,en;q=0.9
User-Agent: com.tripbffllc.Travely/7.2.1 iPhone/18.6.2 hw/iPhone15_3
Authorization: Bearer eyJ...
Accept-Encoding: gzip, deflate, br
{
"data":{
"isPremiumUser":true,
"longitude":-115.815715000000000,
"latitude":37.241223000000000,
"geohash":"9qteue9"
}
}
Interestingly, isPremiumUser is not validated by the backend. Adam, aka “Joe McPwnerson”, still running the app through a proxy, and having not paid for the app, set it to true to get full user data on any account without paying for it. In Burp Repeater, Adam set up an interceptor rule that replaced all “isPremiumUser”: false with “isPremiumUser”: true.
As a non-premium user, any user could easily reproduce this with a ProxyMan rule on your device, replacing the request data on every call, thus always returning more rich information, even if you weren’t paying for premium. However, a ProxyMan license costs $99/year if you’d like to continue to receive updates, which is more than TripBFF costs at $55.99/year.
Response
HTTP/2 200 OK
Vary: Origin
Content-Type: application/json; charset=utf-8
Function-Execution-Id: 1ez669s1vlu2
X-Cloud-Trace-Context: 782435517dea1eacde2e18c6f67adb40
Date: Wed, 10 Sep 2025 04:40:24 GMT
Server: Google Frontend
{
"result": {
"users": [
{
"id": "xqHuNfmQpGYsacHMnzKo23pLDys2",
"latitude": 0,
"longitude": 0,
"realLatitude": 37.241215000000000,
"realLongitude": -115.815725000000000,
"imageUrl": "https://firebasestorage.googleapis.com/v0/b/travely-9bfbf.appspot.com/o/xqHuNfmQpGYsacHMnzKo23pLDys2-thumbnail?alt=media",
"name": "Joe McPwnerson",
"age": 45,
"countryCode": "🇺🇸",
"distanceKM": "1 km",
"distanceMI": "1 mi",
"active": true
},
...
]
}
}
With Adam sitting right next to me, using the /fetchNearbyUsers API I was able to locate his user account in the list. I quickly grabbed the latitude and longitude data out of the entry tied to his account and dropped it into Google maps. Turning the Google Maps screen around to face him, I asked:
“That location pin is directly on your house, isn’t it?”
To which Adam replied with both a grimace and a laugh...
“Yes... Yes it is.”
Further, we were able to manipulate the latitude and longitude values in the POST request to /fetchNearbyUsers. This could have allowed us to scan the entire globe for the most recent app-open location of every single user of the app, without physically moving ourselves.
Because the TripBFF services introduced no randomization/jitter into the data sent to their services, and this exact data is retrievable by any other user, all users were able to view the exact location where any user last opened the app.
Additionally, the /fetchNearbyUsers response returns, in Seattle, a list of ~10 users. However, the app then makes another call to /fetchNumberOfNearbyUsersLast30Days which at time-of-writing, returns 224 users with each element containing both a filled out latitude and longitude value as well as realLatitude and realLongitude values. Interestingly, these two latitudes and longitudes are different from one another, usually starting at the decimal point. It’s not clear to me what these different values are intended to represent and why they deviate so far from one another.
The Security Protection That Won’t Save You
The app has a “Hide my nearby distance” feature that you can use to hide how close/far you are from another user. This is disabled by default but can be enabled by a user, presumably for additional security protections.
Unfortunately, this security protection had a critical security flaw. While the “distanceKM” and “distanceMI” values are changed to “Nearby”. The “realLatitude” and “realLongitude” values continue to expose the exact latitude and longitude of the user.
Below is a sample POST /fetchNearbyUsers response for a user with “Hide my nearby distance” enabled. Again, bogus but realistic latitude and longitude data.
Response
HTTP/2 200 OK
Vary: Origin
Content-Type: application/json; charset=utf-8
Function-Execution-Id: ...
X-Cloud-Trace-Context: ...
Date: Wed, 10 Sep 2025 04:40:24 GMT
Server: Google Frontend
{
"result": {
"users": [
{
"id": "xqHuNfmQpGYsacHMnzKo23pLDys2",
"latitude": 0,
"longitude": 0,
"realLatitude": 37.241215000000000,
"realLongitude": -115.815725000000000,
"imageUrl": "https://firebasestorage.googleapis.com/v0/b/travely-9bfbf.appspot.com/o/xqHuNfmQpGYsacHMnzKo23pLDys2-thumbnail?alt=media",
"name": "Joe McPwnerson",
"age": 45,
"countryCode": "🇺🇸",
"distanceKM": "Nearby",
"distanceMI": "Nearby",
"active": true
},
...
]
}
}
Basically, even when you had “Hide my nearby distance” enabled, your exact location data was still being leaked.
Saving Grace
As far as we can tell, the iOS app only updated your location (by sending a POST to /updateLocation) when you initially open the app, so as long as you’re actively moving you shouldn’t be easily trackable. However, if you’re using the app at home, hotel, AirBnB or hostel, you’d be easily traceable to your exact location.
I Know Your Birth Date
The birthday in the response from /fetchUserProfile, unfortunately, exposed the full user’s birthday using the unix epoch date that was provided during app sign-up.
Request
POST /fetchUserProfile HTTP/2
Host: us-central1-travely-9bfbf.cloudfunctions.net
Accept: */*
Content-Type: application/json
Firebase-Instance-Id-Token: ...
Accept-Language: en-US,en;q=0.9
User-Agent: com.tripbffllc.Travely/7.2.1 iPhone/18.6.2 hw/iPhone15_3
Authorization: Bearer eyJ...
Accept-Encoding: gzip, deflate, br
{
"data": {
"countryCode": "US",
"urlSmall": "https:\/\/firebasestorage.googleapis.com\/v0\/b\/travely-9bfbf.appspot.com\/o\/0rfqyEhcF5WBVXgtG1dGSfC7wN42-thumbnail?alt=media",
"country": "United States",
"uid": "xqHuNfmQpGYsacHMnzKo23pLDys2",
"firstName": "Jonathan"
}
}
Response
HTTP/2 200 OK
Vary: Origin
Content-Type: application/json; charset=utf-8
Function-Execution-Id: ...
X-Cloud-Trace-Context: ...
Date: Wed, 10 Sep 2025 04:12:15 GMT
Server: Google Frontend
{
"result": {
"user": {
"id": "xqHuNfmQpGYsacHMnzKo23pLDys2",
"firstName": "Joe McPwnerson",
"gender": "Male",
"country": "United States",
"countryCode": "US",
"birthday": {
"_seconds": 337404978,
"_nanoseconds": 0
},
"age": 45,
"bio": "",
"profilePicURL": "https://firebasestorage.googleapis.com/v0/b/travely-9bfbf.appspot.com/o/xqHuNfmQpGYsacHMnzKo23pLDys2?alt=media",
"profilePicURL2": "",
"profilePicURL3": "",
"profilePicURLLowQuality": "https://firebasestorage.googleapis.com/v0/b/travely-9bfbf.appspot.com/o/xqHuNfmQpGYsacHMnzKo23pLDys2-thumbnail?alt=media",
"notifToken": "",
"languages": [
"English"
],
"travelStatsCountries": [],
"travelStatsCountryCodes": [],
"interestsNEW": [],
"instagramUserName": "",
"tiktokUserName": "",
"subscriptionStatus": false,
"banned": false,
"proBadgeHidden": false,
"placesToVisit": [],
"travelLifestyle": "🎒 Backpacking"
},
"isFriend": false,
"isVerified": false,
"savedTrips": [],
"userPlans": []
}
}
Throwing the ”birthday”.”_seconds” value of 337404978 into an epoch converter, we are quickly able to determine that value maps to Wednesday, September 10, 1980, Joe McPwnerson’s fake birthday used at account creation.
Stealing Data En-Mass
Since the /fetchNearbyUsers endpoint allows you to set the location you’d like to search, it would be rather easy to create a script to walk the planet, searching the app’s databases for every single active user and exfiltrating that data. If this behaviour were to go undetected by the TripBFF developers, this could be used by third parties to track the locations of users of the TripBFF app on a near continuous basis.
The out-of-date Privacy Policy
In reviewing the TripBFF Privacy Policy (WayBack Machine: September 19th 2025) we found no mention of the fact that TripBFF collects location information. Although the iOS app does list that location data may be collected. Obviously, in order for the app and service to function properly, it must be collecting and storing user location information.
I pointed out this gap between the Privacy Policy and the app's obvious feature set to the TripBFF team, and while it was confirmed that they planned to fix this, as of the date of publication, the Privacy Policy has yet to be updated. Although I'm not a lawyer, I would assume that not explicitly stating what/how location data is being used for their EU users is likely a potential GDPR violation.
Proposed Fixes
When reported to the TripBFF team, we submitted the following proposed fixes for the identified data exposures:
- Fifteen decimal precision on latitude/longitudes is completely unnecessary to be sending to a backend server. Limit the accuracy to two decimal places of real data, with a third decimal place should be randomly generated, to create some skew/anonymization.
- All geohash values should be reduced to a maximum of 6 characters of precision. This would limit the granularity to a cell ≤ 1.22km width x 0.61km cell.
- Don’t send the full epoch birthday value back in the
/fetchUserProfileresponse. - Implement rate-limiting for users that request data from the
/fetchNearbyUsersendpoint too quickly as this could be an attempt by a malicious actor to scrape data from the API. - “Hide my Distance” should pin the user's location to the center of the nearest city, or do more to fully anonymize the location of the user that has enabled this setting.
Response by the TripBFF Team
The TripBFF team was incredibly receptive to our report. I initially reached out by simply asking where to report security issues like this to the team, and Ethan, the CTO, responded within 6 min of my having reached out.
Immediately upon receiving our full report the TripBFF team pushed to prod a change to skew the coordinates returned from the backend when fetching /fetchNearbyUsers as a short-term fix. They also committed to shipping an iOS update that would collect far less accurate coordinates (although as of November 18th, 2025 this has not occurred).
Further GET requests from /fetchNumberOfNearbyUsersLast30Days will no longer return the exact user's coordinates anymore. Coordinates now snap to a 1 km grid, and add a + or - 400 m jitter. This jitter has a minimum offset from the true location, and the jitter rotates daily. One concern that does arise from this solution is the question as to if it’s sufficient if the user lives in an incredibly rural area, or is, for example, hiking deep in the wilderness. There are only so many places someone could be along a linear trail, so 1km ± 400m might not be sufficient in all cases.
Additionally, the updates to the server also fix accounts so if “Hide My Nearby Distance” is enabled, the API will always just return 0.0, 0.0 instead of the real coordinates.
Finally, a change was pushed to the server to skew the birthday value returned, until they were able to push an iOS update to accept a returned “age” rather than a full date of birth.
Overall, these seem like adequate changes that add reasonable privacy protections for users while still offering the user experience desired by the app users. Overall we were impressed with TripBFF’s reception to our report and commend them on their fast response to quickly address the security concerns we raised.
All that being said, the TripBFF maintainers promised that they would “Reduce the accuracy of the coords being sent in /updateLocation POST”. However, as of writing, this fix has not materialized into any release I’ve tested. The data being sent to the TripBFF servers is still incredibly accurate latitude and longitude data. While not a concern if you trust TripBFF, this is something you should be aware of.
Areas for Further Exploration
We believe that the chat functionality may be leveraging gRPC using nanopb buffers. Using burp we were unable to proxy any of the traffic for any of the chat functionality in the app. We were curious what additional functionality within the app we could unlock, but was beyond what we were willing to explore in the time we had.
Conclusion
Given that TripBFF does collect user location information, if you’re concerned about your privacy, I’d advise not sharing your location data with the app. Additionally, I’d suggest that you be smart about location sharing, linking Instagram & TikTok to your physical location can be risky if you're in an at-risk population. You want to be even more careful if you’re planning on traveling to a very remote location, as it will be much easier for other users to locate you even with the skew randomization introduced. All that being said, sharing your location is kinda the whole point of the app, and a core feature of what makes it fun to connect with other travelers, so just understand the risk you’re signing up for.
Overall, I’ve been pretty impressed with the TripBFF app. The UI design was very clean and user friendly. As a world traveler, I've personally found it to be a fun and useful tool for meeting other travelers while exploring the world, especially in Europe. However, as with everything, the devil is in the implementation details. Just a brief dive into the internal interactions between the app and its backend servers were enough to quickly reveal the exposure of sensitive user information for other users. It’s imperative that developers releasing applications like this get their apps professionally pentested by third parties to see if they are exposing their end-users to data theft, especially when working with live or close-to-live location information.
📣 I’m on the Market
Like what you read? I’m currently exploring my next opportunity in software security, open source, or developer tooling. If this kind of work resonates with you, I’d love to connect.
📧 Email: Jonathan.Leitschuh@gmail.com
⛓️ LinkedIn: https://www.linkedin.com/in/jonathan-leitschuh/
📅 Schedule Time: https://calendly.com/jlleitschuh



Top comments (0)