Doesn’t seem too crazy for a generic react native app but of course coming from the official US government, it’s pretty wide open to supply chain attacks. Oh and no one should be continually giving the government their location. Pretty crazy that the official government is injecting JavaScript into web views to override the cookie banners and consent forms.
Giving people a taste of web with Ublock Origin annoyance filters applied, refreshing. Can’t believe orange man regime is doing one thing right.
In their defense, this is the first thing the Trump admin has done that's unambiguously positive for ordinary people.
I am sure if you decompile other apps used by hundreds of thousands of people, you would find all sorts of tracking in there.
Thanks for helping the White House improve their app security for free though.
You'd be surprised how many apps inside have hacks and workarounds because deadlines.
I've noticed Claude Code is happy to decompile APKs for you but isn't very good at doing reachability analysis or figuring out complex control flows. It will treat completely dead code as important as a commonly invoked function.
So at least it does something actually beneficial for the user! I wish it could go even further, the way Reader Mode in a browser would go.
Rare Trump administration W. I'm assuming there's one particular website they open in the app that shows a cookie popup, and this was a dev's heavy-handed way of making that go away.
Did you find something malicious in the random GitHub repo? If so, you should write an article about that instead.
I'd verify all this stuff for myself, but Play won't install it in my phone so I can't really get the APK. Maybe because I use Graphene...? but I don't know all the ways they can restrict it, maybe it's something else (though for a pixel 9a it's rather strange if it's hardware based).
--- EDIT ---
To be specific / add what I can check, this is what my Play Store "about -> permissions" is showing:
Version 47.0.1 may request access to
Other:
run at startup
Google Play license check
view network connections
prevent phone from sleeping
show notifications
com.google.android.c2dm.permission.RECEIVE
control vibration
have full network access
which appears fairly normal, and does not include location, and I think Play includes runtime location requests there. Maybe there's a version-rollout happening, or device-type targeting?Cross referencing these different things in the article to other apps that exist was my first thought as these seem pretty generic and probably reused from somewhere else.
To mix the metaphors further, they (the politicians and their supporters) fancy themselves the kind to dream of things that never were and ask why not. Why not have a war in Iran? You won't know until you give it a try.
The article does not claim the app requests the location. It claims it can do it with a single JS call.
from the iphone app store: version 47.0.1 - minor bug fixes - 34 minutes ago
while the parent posted 18 minutes ago
they may have patched the location stuff as part of the “minor bug fixes”?
Imagine being in a cafe nearby, say, embassy of the certain north African country known for pervasive and wide espionage actions, which decides to hijack traffic in this cafe.
Or imagine living in the country where almost all of the cabinet is literally (officially) being paid by the propaganda/lobbying body of such country.
Or living int he country where lawful surveillance can happen without the jury signoff, but at a while of any police officer.
Maybe its not common but frequent enough.
This is bad for security.
Imagine they're downloading a project directly from your GitHub account. Even if you're not doing anything malicious and have no intention of doing anything malicious even after you've been aware of this, now all of a sudden your GitHub account / email is a huge target for anyone that wants to do something malicious.
If any of those 3 is true, the bar should be higher than what someone just did in their free time? I would surely expect more.
so can ... any other code anywhere on a mobile device? That is how API work...
No location permission request prompting encountered. In system settings, where each app requesting location data is listed, it isn't present either.
How would they get your phone to trust their CA? Connecting to a Wi-Fi network doesn’t change which CAs a device trusts.
I'm well aware of supply chain attacks. But this isn't a supply chain attack. If it were, the article would be way more interesting.
The supply chain attack articles are interesting exactly because this is so common. So what's special here other than it being loosely related to a disliked political figure? HN isn't supposed to be an especially political website.
"A common app is doing the same thing that basically every other app is doing."
Is that a good headline? No. And this isn't a good article.
Is there a cabinet member for the Department of Apps?
It's a throwaway app, probably written by someone that posts here.
From the (limited) article, it doesn't seem they do this: https://thereallo.dev/blog/decompiling-the-white-house-app#p...
----
EDIT: I'm mistaken. From the Play Store[0] it has access to
* approximate location (network-based)
* precise location (GPS and network-based)
[0] https://play.google.com/store/apps/details?id=gov.whitehouse...
This seems to disagree with:
> The location permissions aren't declared in the AndroidManifest but requested at runtime
*shrug*, someone should dig deeper. It looks like the article may not match reality.
How would you have written it differently
I’d prefer they not release shoddily build propaganda apps
https://www.eff.org/deeplinks/2011/08/iranian-man-middle-att...
https://support.apple.com/en-us/126047
The chances of zero of these CAs having been compromised by state-level actors seems… slim.
Do you trust "Hongkong Post Root CA 3" not to fuck with things?
Your link's from 2011; the US government was still in the trusted list until 2018. https://www.idmanagement.gov/implement/announcements/04_appl...
China telecom regularly has BGP announcements that conflict with level3's ASNs.
Just as a hint in case you want to dig more into the topic, RIR data is publicly available, so you can verify yourself who the offenders are.
Also check out the Geedge leaked source code, which also implements TLS overrides and inspection on a country scale. A lot of countries are customers of Geedge's tech stack, especially in the Middle East.
Just sayin' it's more common than you're willing to acknowledge.
The White House released an app on the App Store and Google Play. They posted a blog about it. "Unparalleled access to the Trump Administration."
It took a few minutes to pull the APKs with ADB, and threw them into JADX.
Here is everything I found.
It's a React Native app built with Expo (SDK 54), running on the Hermes JavaScript engine. The backend is WordPress with a custom REST API. The app was built by an entity called "forty-five-press" according to the Expo config.
The actual app logic is compiled into a 5.5 MB Hermes bytecode bundle. The native Java side is just a thin wrapper.
Version 47.0.1. Build 20. Hermes enabled. New Architecture enabled. Nothing weird here. Let's keep going.
Two things stand out here. First, there's a plugin called withNoLocation. Second, there's a plugin called withStripPermissions. Remember these. They become relevant very soon.
OTA updates are disabled. The Expo update infrastructure is compiled in but dormant.
I extracted every string from the Hermes bytecode bundle and filtered for URLs and API endpoints. The app's content comes from a WordPress REST API at whitehouse.gov with a custom whitehouse/v1 namespace.
Here are the endpoints:
| Endpoint | What It Serves |
|---|---|
/wp-json/whitehouse/v1/home |
Home screen |
/wp-json/whitehouse/v1/news/articles |
News articles |
/wp-json/whitehouse/v1/wire |
"The Wire" news feed |
/wp-json/whitehouse/v1/live |
Live streams |
/wp-json/whitehouse/v1/galleries |
Photo galleries |
/wp-json/whitehouse/v1/issues |
Policy issues |
/wp-json/whitehouse/v1/priorities |
Priorities |
/wp-json/whitehouse/v1/achievements |
Achievements |
/wp-json/whitehouse/v1/affordability |
Drug pricing |
/wp-json/whitehouse/v1/media-bias |
"Media Bias" section |
/wp-json/whitehouse/v1/social/x |
X/Twitter feed proxy |
Other hardcoded strings from the bundle: "THE TRUMP EFFECT", "Greatest President Ever!" (lol), "Text President Trump", "Send a text message to President Trump at 45470", "Visit TrumpRx.gov", "Visit TrumpAccounts.gov".
There's also a direct link to https://www.ice.gov/webform/ice-tip-form. The ICE tip reporting form. In a news app.
It's a content portal. News, live streams, galleries, policy pages, social media embeds, and promotional material for administration initiatives. All powered by WordPress.
Now let's look at what else it does.
The app has a WebView for opening external links. Every time a page loads in this WebView, the app injects a JavaScript snippet. I found it in the Hermes bytecode string table:
Read that carefully. It hides:
It forces body { overflow: auto !important } to re-enable scrolling on pages where consent dialogs lock the scroll. Then it sets up a MutationObserver to continuously nuke any consent elements that get dynamically added.
An official United States government app is injecting CSS and JavaScript into third-party websites to strip away their cookie consent dialogs, GDPR banners, login gates, and paywalls.
The native side confirms this is the injectedJavaScript prop on the React Native WebView:
Every page load in the in-app browser triggers this. It wraps the injection in an IIFE and runs it via Android's evaluateJavascript().
Remember withNoLocation from the Expo config? The plugin that's supposed to strip location? Yeah. The OneSignal SDK's native location tracking code is fully compiled into the APK.
270,000 milliseconds is 4.5 minutes. 570,000 is 9.5 minutes.
To be clear about what activates this: the tracking doesn't start silently. There are three gates. The LocationManager checks all of them before the fused location API ever fires.
First, the _isShared flag. It's read from SharedPreferences on init and defaults to false. The JavaScript layer can flip it on with setLocationShared(true). The Hermes string table confirms both setLocationShared and isLocationShared are referenced in the app's JS bundle, so the app has the ability to toggle this.
Second, the user has to grant the Android runtime location permission. The location permissions aren't declared in the AndroidManifest but requested at runtime. The Google Play Store listing confirms the app asks for "access precise location only in the foreground" and "access approximate location only in the foreground."
Third, the start() method only proceeds if the device actually has a location provider (GMS or HMS).
If all three gates pass, here's what runs. The fused location API requests GPS at the intervals defined above:
This gets called on both onFocus() and onUnfocused(), dynamically switching between the 4.5-minute foreground interval and the 9.5-minute background interval.
When a location update comes in, it feeds into the LocationCapturer:
Latitude, longitude, accuracy, timestamp, whether the app was in the foreground or background, and whether it was fine (GPS) or coarse (network). All of it gets written into OneSignal's PropertiesModel, which syncs to their backend.
The data goes here:
There's also a background service that keeps capturing location even when the app isn't active:
So the tracking isn't unconditionally active. But the entire pipeline including permission strings, interval constants, fused location requests, capture logic, background scheduling, and the sync to OneSignal's API, all of them are fully compiled in and one setLocationShared(true) call away from activating. The withNoLocation Expo plugin clearly did not strip any of this. Whether the JS layer currently calls setLocationShared(true) is something I can't determine from the native side alone, since the Hermes bytecode is compiled and the actual call site is buried in the 5.5 MB bundle. What I can say is that the infrastructure is there, ready to go, and the JS API to enable it is referenced in the bundle.
OneSignal is doing a lot more than push notifications in this app. From the Hermes string table:
addTag - tag users for segmentationaddSms - associate phone numbers with user profilesaddAliases - cross-device user identificationaddOutcomeWithValue / addUniqueOutcome - track user actions and conversionsOneSignal-notificationClicked - notification tap trackingOneSignal-inAppMessageClicked / WillDisplay / DidDisplay / WillDismiss / DidDismiss - full in-app message lifecycle trackingOneSignal-permissionChanged / subscriptionChanged / userStateChanged - state change trackingsetLocationShared / isLocationShared - location togglesetPrivacyConsentRequired / setPrivacyConsentGiven - consent gatingThe local database tracks every notification received and whether it was opened or dismissed:
Your location, your notification interactions, your in-app message clicks, your phone number if you provide it, your tags, your state changes. All going to OneSignal's servers.
The app embeds YouTube videos using the react-native-youtube-iframe library. This library loads its player HTML from:
That's a personal GitHub Pages site. If the lonelycpp GitHub account gets compromised, whoever controls it can serve arbitrary HTML and JavaScript to every user of this app, executing inside the WebView context.
This is a government app loading code from a random person's GitHub Pages.
The app loads third-party JavaScript from Elfsight to embed social media feeds:
Elfsight is a commercial SaaS widget company. Their JavaScript runs inside the app's WebView with no sandboxing. Whatever tracking Elfsight does, it does it here too. Their code can change at any time. The Elfsight widget ID 4a00611b-befa-466e-bab2-6e824a0a98a9 is hardcoded in an HTML embed.
whitehouse.us10.list-manage.com/subscribe/post-json handles email signups. User emails go to Mailchimp's infrastructure.ucarecdn.com hosts content images via six hardcoded UUIDs.static-assets-1.truthsocial.com, and a "Follow on Truth Social" button.facebook.com/plugins/page.php.None of these are government-controlled infrastructure.
The app uses standard Android TrustManager for SSL with no custom certificate pinning. If you're on a network with a compromised CA (corporate proxies, public wifi with MITM, etc.), traffic between the app and its backends can be intercepted and read.
The build has some sloppy leftovers.
A localhost URL made it into the production Hermes bundle:
That's the React Native Metro bundler dev server.
A developer's local IP is hardcoded in the string resources:
The Expo development client (expo-dev-client, expo-devlauncher, expo-devmenu) is compiled into the release build. There's a dev_menu_fab_icon.png in the drawable resources. The Compose PreviewActivity is exported in the manifest, which is a development-only component that should not be in a production APK.
The AndroidManifest itself is pretty standard for a notification-heavy app:
Plus about 16 badge permissions for Samsung, HTC, Sony, Huawei, OPPO, and other launchers. These just let the app show notification badge counts. Not interesting.
The interesting permissions are the ones that aren't in the manifest but are hardcoded as runtime request strings in the OneSignal SDK, as covered above. Fine location. Coarse location. Background location.
The Google Play listing also mentions: "modify or delete the contents of your shared storage", "run foreground service", "this app can appear on top of other apps", "run at startup", "use fingerprint hardware", "use biometric hardware."
The file provider config is also worth mentioning:
That exposes the entire external storage root. It's used by the WebView for file access.
68+ libraries are compiled into this thing. The highlights:
| Category | Libraries |
|---|---|
| Framework | React Native, Expo SDK 54, Hermes JS engine |
| Push/Engagement | OneSignal, Firebase Cloud Messaging, Firebase Installations |
| Analytics/Telemetry | Firebase Analytics, Google Data Transport, OpenTelemetry |
| Networking | OkHttp 3, Apollo GraphQL, Okio |
| Images | Fresco, Glide, Coil 3, Uploadcare CDN |
| Video | ExoPlayer (Media3), Expo Video |
| ML | Google ML Kit Vision (barcode scanning), Barhopper model |
| Crypto | Bouncy Castle |
| Storage | Expo Secure Store, React Native Async Storage |
| WebView | React Native WebView (with the injection script) |
| DI | Koin |
| Serialization | GSON, Wire (Protocol Buffers) |
| License | PairIP license check (Google Play verification) |
25 native .so libraries in the arm64 split. The full Hermes engine, React Native core, Reanimated, gesture handler, SVG renderer, image pipeline, barcode scanner, and more.
The official White House Android app:
Injects JavaScript into every website you open through its in-app browser to hide cookie consent dialogs, GDPR banners, login walls, signup walls, upsell prompts, and paywalls.
Has a full GPS tracking pipeline compiled in that polls every 4.5 minutes in the foreground and 9.5 minutes in the background, syncing lat/lng/accuracy/timestamp to OneSignal's servers.
Loads JavaScript from a random person's GitHub Pages site (lonelycpp.github.io) for YouTube embeds. If that account is compromised, arbitrary code runs in the app's WebView.
Loads third-party JavaScript from Elfsight (elfsightcdn.com/platform.js) for social media widgets, with no sandboxing.
Sends email addresses to Mailchimp, images are served from Uploadcare, and a Truth Social embed is hardcoded with static CDN URLs. None of this is government infrastructure.
Has no certificate pinning. Standard Android trust management.
Ships with dev artifacts in production. A localhost URL, a developer IP (10.4.4.109), the Expo dev client, and an exported Compose PreviewActivity.
Profiles users extensively through OneSignal - tags, SMS numbers, cross-device aliases, outcome tracking, notification interaction logging, in-app message click tracking, and full user state observation.
Is any of this illegal? Probably not. Is it what you'd expect from an official government app? Probably not either.