Security

    Does Apple Review Hardcoded API Keys?

    Illustration of an iOS IPA archive being unzipped on macOS while a developer searches the binary for hardcoded API keys before submitting to App Store Connect

    Your iOS build is sitting in the App Store Connect queue and you are looking at the API keys you embedded last week. The honest answer is that Apple is not going to pull those keys out of your IPA, and that fact cuts both ways.

    Short answer

    Apple's App Review does not run a secrets scanner against your binary. The static-analysis pipeline targets malware signatures, undocumented APIs, and policy violations defined in the App Review Guidelines. Hardcoded API keys are a security defect under OWASP MASWE-0005, API keys hardcoded in the app package, but they are invisible to Apple's automated layer and rarely caught by human reviewers. Anyone who downloads your IPA can extract them in minutes using tools that ship with macOS.

    What you should know

    • Apple's static pass is for malware and policy, not credentials. According to Apple's App Review Guidelines, the focus is user-facing behavior, Privacy Manifests, and entitlement use, not secret hygiene.
    • An IPA is a zip file. Anyone can rename it, open the bundle, and grep for api_key, Bearer , sk_live_, or domains like .firebaseio.com.
    • Guideline 1.6 sets expectation, not enforcement. It says developers must implement appropriate security measures. App Review does not audit those measures at the binary or backend layer.
    • Researchers have found this at scale. A 2023 Cybernews investigation of more than 156,000 iOS apps found that 71% leaked at least one secret in plaintext, with more than 815,000 hardcoded tokens recovered without any de-obfuscation.
    • The right place for a secret is a server. A backend proxy, an Edge Function, or a key-vault service holds the credential and signs requests on behalf of the app.

    Does Apple actually scan my IPA for API keys?

    No. The static-analysis pipeline that processes your build after upload to App Store Connect looks for things Apple is willing to enforce as policy: use of private APIs, missing or mismatched Privacy Manifest entries, malware signatures, encryption export compliance flags, and the structural validity of the bundle. According to Apple's App Review Guidelines, the review pass is governed by the Safety, Performance, Business, Design, and Legal categories. None of them mandate a secrets scanner.

    Human reviewers do exercise the app, but they spend their time on the things that show up to a user. They navigate the screens listed in your demo notes, they trip the App Tracking Transparency prompt, they check the disclosures in the data collection summary, and they confirm that the app does what the metadata promises. They do not unzip your IPA on the side and grep for AIza.

    That is consistent with the public position of independent mobile security testers. The NowSecure analysis of App Store review frames the review process as focused on malware and metadata accuracy, not on the kind of mobile application security and privacy issues that show up in third-party penetration tests.

    What gets caught and what gets through?

    A short comparison of where the App Review pipeline catches a defect, where it does not, and where a third party with the IPA can see the same defect in minutes.

    Issue typeCaught by static passCaught by human reviewerVisible to a third party with the IPA
    Use of private APIYesRareYes, with static analysis
    Missing Privacy Manifest declarationYesSometimesYes
    Missing purpose stringYes (runtime crash)YesYes
    Hardcoded API key in Info.plistNoNoYes, in seconds
    Hardcoded API key in Hermes bundleNoNoYes, with hermes-dec
    Firebase database URL with open rulesNoNoYes
    Stripe restricted key in appNoNoYes
    Test credentials shipped to productionNoNoYes

    The pattern is consistent. Apple's pipeline gates on what Apple can defend in policy terms. Backend-side configuration and credential hygiene sit on the developer side of the line.

    How does an attacker actually pull keys out of an IPA?

    On macOS the flow takes about five minutes and no specialized tools. Download the IPA from your account using Apple Configurator or iMazing, rename the extension to .zip, open the archive, and look inside Payload/YourApp.app/. From there run strings against the main binary, run unzip against any embedded asset packs, and search for the obvious tokens: sk_, pk_, AIza, Bearer , xoxb-, ghp_, eyJ, anything that looks like a JWT, anything that ends in .amazonaws.com or .supabase.co.

    For React Native or Expo builds the bundle is main.jsbundle and the keys are in plaintext JavaScript, or in a Hermes binary that decompiles with hermes-dec. For Flutter apps the App.framework/App binary holds the Dart snapshot, and string constants come out with flutter_decompiler or a Ghidra script. For native Swift the secrets are usually in the binary's __cstring section, recoverable with one pass of strings.

    That is the methodology behind the 2023 Cybernews investigation that found more than 815,000 hardcoded secrets across 156,000 iOS apps. The researchers did not de-obfuscate. They just looked at plaintext files inside the archive. The takeaway is that anyone with the same five minutes and an App Store login can do the same thing to your app.

    What does OWASP MASVS say I should do instead?

    The relevant control is OWASP MASWE-0005, API keys hardcoded in the app package. It treats the presence of any usable credential inside the binary as a defect, not a slip. The fix path has three layers.

    1. Move the secret to a server. A backend proxy, a serverless function, or a key-vault service holds the credential. The mobile app authenticates the user, the server signs the third-party request, the third-party answer comes back through the server. The mobile app never sees the raw key.
    2. Use platform secure storage for per-user tokens. Use the iOS Keychain (or the Android Keystore) for the per-user session token your server hands out after login. The Keychain entry is bound to the user's device passcode and is not visible to a static IPA scan.
    3. Apply runtime obfuscation only as defense in depth. The OWASP Mobile Application Security Verification Standard treats obfuscation as a secondary layer, not as a primary control. An obfuscated key still resolves at runtime, and a determined attacker recovers it in minutes.

    For builders shipping AI-coded or no-code projects where the Supabase, Firebase, OpenAI, or Stripe keys were wired up by an agent and never reviewed by hand, PTKD.com (https://ptkd.com) is one of the platforms focused on pre-submission scanning of compiled IPA and APK files for OWASP MASVS issues, including detection of common API key formats inside the bundle before submission to App Store Connect.

    Why does Apple leave hardcoded keys out of the review?

    There are two reasons that fit the pattern of how Apple sets up review.

    The first is liability. A secret-scanning pass that flags a third-party key implicitly tells the developer the key is unsafe to ship. That is a security claim Apple does not want to make on every build, because the determination of whether a key is sensitive depends entirely on what the key is allowed to do server side. A Stripe publishable key is fine in the bundle. A Stripe restricted key is not. Apple has no way to know which is which without context, so it stays out of the call.

    The second is throughput. App Review handles millions of submissions a year. A secrets scanner is expensive at that scale and would create a long tail of false positives that require a human decision. According to the App Review Guidelines, Apple's focus is on the user-facing surface, where the cost of a false positive is small and the benefit of catching a real problem is high. Hardcoded keys do not fit that economics.

    The practical consequence is that the responsibility sits with the developer. Post-launch, if a leaked key causes a public incident with user data, Apple can act under Guideline 5.1.1(vi), which targets surreptitious collection or exposure of private information. That is enforcement after the fact, not prevention at submission, and it tends to arrive with a researcher writeup or a press story attached.

    What to watch out for

    A few patterns recur in vibe-coded and AI-generated app submissions.

    The first is treating App Store approval as a security stamp. App Review approval means the build cleared policy. It does not mean the app cleared a security audit, and it does not mean an attacker cannot read your keys.

    The second is rotating a single leaked key without finding the rest. If one API key was visible inside the IPA, the others usually are too. A clean fix involves identifying every credential in the build, rotating each one, and rebuilding without any of them embedded.

    The third is shipping a .env file inside the bundle. A common pattern in Expo and Capacitor builds is to copy a .env into the bundle so that runtime references resolve, then forget that the file is shipped. The file ends up under Payload/YourApp.app/ as plaintext, and any future grep finds every variable inside.

    The fourth is assuming obfuscation buys real time. A JavaScript bundle minified with esbuild is readable in seconds with jsbeautify. A Hermes binary decompiles in under a minute. A native iOS binary still exposes string constants through strings. The cost of recovery is measured in minutes for any non-trivial token, not days.

    Key takeaways

    • Apple's App Review does not run a secrets scanner across your IPA. The static pass targets malware and policy, not credential hygiene. A build with hardcoded API keys will usually pass review and then expose those keys to anyone who downloads it.
    • OWASP MASWE-0005 treats hardcoded API keys in the app package as a defect. The fix is to move the secret to a server, not to obfuscate it inside the bundle.
    • A third party with your IPA and five minutes can extract every plaintext token inside the archive. The 2023 Cybernews study recovered 815,000 such secrets across 156,000 iOS apps without any de-obfuscation.
    • Post-launch, Apple can enforce against the consequences under Guideline 5.1.1(vi) when leaked keys lead to user data exposure. Prevention before submission is on the developer.
    • For an external read of a compiled iOS or Android build, including detection of common API key shapes inside the bundle, PTKD.com (https://ptkd.com) is one of the platforms focused on OWASP MASVS pre-submission scanning.
    • #api-keys
    • #hardcoded-secrets
    • #app-review
    • #ios
    • #owasp-masvs
    • #mobile-security
    • #ipa-extraction

    Frequently asked questions

    Does the App Review static-analysis pipeline look for API keys?
    No. According to Apple's App Review Guidelines, the static pass targets malware signatures, private API use, Privacy Manifest declarations, and bundle validity. Credential hygiene is not in scope. A build with a Firebase Admin key or a Stripe restricted key embedded inside the IPA will usually clear the pipeline. Reviewers then exercise the app for behavior, not for the contents of plaintext files inside the archive.
    Can a hardcoded API key still get my app rejected?
    Indirectly, in narrow cases. If the key authenticates a documented private API, Guideline 2.5.1 applies. If the key powers a hidden feature the metadata does not describe, Guideline 2.3.1 applies. The key itself is not a rejection reason. The behaviors the key enables can be, when those behaviors fall under documented policy categories, but the secret material is not the trigger.
    Are publishable keys like the Supabase anon key or Stripe publishable key safe to ship?
    Yes, when the backend behind them is configured for it. The Supabase anon key relies on Row Level Security policies in Postgres. The Stripe publishable key only authorizes the creation of tokens, not charges. Both are designed to be public. The unsafe pattern is shipping the matching secret key by mistake, or relying on a publishable key against an unprotected backend without any policies.
    What is the fastest way to find every secret in my own build?
    Take the IPA from App Store Connect, rename it to .zip, and open the archive. Run `strings -a` against the main binary, run `unzip -l` against the assets, and grep for token prefixes: `sk_`, `pk_`, `Bearer `, `eyJ`, `AIza`, `xoxb-`, `ghp_`. Add domain patterns like `.supabase.co`, `.firebaseio.com`, `.openai.com`. The same five minutes is what an attacker spends.
    Does code obfuscation hide hardcoded keys from extraction?
    Not meaningfully. JavaScript bundles minified by esbuild restore with `jsbeautify` in seconds. Hermes binaries decompile with `hermes-dec`. Native iOS binaries still expose string constants through `strings`. OWASP MASVS treats obfuscation as a secondary defense, not a primary control. Any token that resolves at runtime is recoverable by a static or dynamic analyst in minutes, not days.

    Keep reading

    Scan your app in minutes

    Upload an APK, AAB, or IPA. PTKD returns an OWASP-aligned report with copy-paste fixes.

    Try PTKD free