Apple's guideline 2.5.2 prohibits downloading and executing code after approval. Remote configuration that can enable gambling mechanics, cryptocurrency payments, adult content, or affiliate link injection after a binary passes review is treated as deliberate deception — the consequence is not just rejection but developer account termination, which affects every app in the account. The pattern is detectable: reviewers who see LaunchDarkly or Statsig in a binary will check what flags control and whether any could enable policy-violating behavior. Dynamic code construction from remote strings — eval-equivalent patterns — is a hard rejection regardless of what the code does.
High because enabling policy-violating features via remote config post-approval is treated by Apple as deception, with account termination (not just app removal) as the consequence.
Audit every remote config flag before submission. List each flag and what it gates — any flag controlling a feature category that wasn't present at review time is a risk.
// scripts/audit-feature-flags.ts
// Run before every App Store submission
const HIGH_RISK_FLAG_PATTERNS = [
/crypto|payment|gambling|adult|affiliate|porn/i,
];
const flags = await launchDarkly.getAllFlags();
for (const [key] of Object.entries(flags)) {
if (HIGH_RISK_FLAG_PATTERNS.some(p => p.test(key))) {
console.error(`HIGH RISK FLAG: ${key} — verify feature was present at last review`);
}
}
For any flag that could enable a new payment flow or major feature: disable it and submit a new app version with that feature already built in and visible to reviewers. Remove all patterns that construct logic from remote-fetched strings at runtime.
ID: app-store-review-blockers.technical-requirements.no-hidden-features
Severity: high
What to look for: Count all relevant instances and enumerate each. Search for remote configuration usage: firebase/remote-config, LaunchDarkly, Statsig, GrowthBook, expo-constants with server-fetched overrides, or any fetch('/api/config') call that returns feature flags applied at runtime. Look for feature flags that gate: payment flows, gambling mechanics, adult content, cryptocurrency features, affiliate linking, or any feature that would require App Store review if submitted initially. Also look for dynamic code execution patterns — runtime construction of executable logic from strings, dynamic require() calls loading from remote URLs, or script tags injected into WebViews from remote sources. Check for URL scheme handlers or deep links that could trigger hidden functionality.
Pass criteria: Remote configuration, if present, only controls: UI theming, A/B test copy variants, feature rollout percentages for already-reviewed features, or non-functional toggles. At least 1 implementation must be verified. No remote config key can enable a feature category that was not present and reviewable at submission time.
Fail criteria: Remote config can enable: adult content, gambling, cryptocurrency payments, affiliate link injection, or any feature that would be rejected if submitted for review. Dynamic code execution from remote strings present.
Skip (N/A) when: Never.
Detail on fail: "LaunchDarkly flag 'enable_crypto_payments' found — this could enable a feature requiring re-review post-approval" or "App constructs and runs code dynamically from remotely-fetched configuration strings"
Remediation: Apple guideline 2.5.2 prohibits apps from downloading executable code after approval. Using remote config to enable policy-violating features results in account termination.
Review the configuration in src/ or app/ directory for implementation patterns.
Cross-reference: For related patterns and deeper analysis, see the corresponding checks in other AuditBuffet audits covering this domain.