# No debug APIs or test endpoints in release build

- **Pattern:** `ab-001941` (`mobile-store-readiness.build-config.no-debug-in-release`)
- **Severity:** high
- **Lifecycle:** active
- **Last modified:** 2026-04-18
- **Canonical URL:** https://auditbuffet.com/patterns/ab-001941
- **License:** CC-BY-4.0 — attribute to AuditBuffet Pattern Catalog (https://auditbuffet.com/patterns/ab-001941)

## Why it matters

A production build that points to staging APIs or includes debug tooling exposes real users to test data, unstable endpoints, and developer-only interfaces. More critically, staging endpoints typically have weaker auth, lower rate limits, and no data residency guarantees — a production release hitting a staging backend may log user PII into non-compliant systems. CWE-489 (active debug code) and CWE-200 (information exposure) both apply: redux-logger printing state trees to device logs, or a `localhost` URL falling back to a staging server, creates information exposure paths that violate user trust and may constitute a GDPR Art. 5 processing purpose violation. App store reviewers who discover staging URLs during dynamic analysis can reject the binary.

## Severity rationale

High because production builds pointing to staging APIs expose real user data to non-compliant endpoints and give reviewers grounds to reject binaries containing active debug tooling.

## Remediation

Gate all debug tooling behind `__DEV__` and drive API URLs from environment variables, never from hardcoded strings in source.

```ts
// src/config.ts
export const API_URL = process.env.EXPO_PUBLIC_API_URL ?? 'https://api.yourapp.com';

// Conditionally load debug middleware
const middleware: Middleware[] = [thunk];
if (__DEV__) {
  const { createLogger } = await import('redux-logger');
  middleware.push(createLogger());
}
```

Set `EXPO_PUBLIC_API_URL` as an EAS secret for production builds (`eas secret:create --scope project --name EXPO_PUBLIC_API_URL --value https://api.yourapp.com`). Verify by running `eas build --profile production --local` and grepping the bundle for staging hostnames before submitting.

## Detection

- **ID:** `no-debug-in-release`
- **Severity:** `high`
- **What to look for:** Search for strings like `__DEV__`, `debug`, `test`, `localhost`, `127.0.0.1`, staging API endpoints, or mock data endpoints in source files. Check for environment-based API URL selection. Verify that release/production builds point to production APIs, not staging or test endpoints. Look for debug logging libraries (e.g., `redux-logger`, `react-native-debugger`) and verify they're excluded from release builds.
- **Pass criteria:** Enumerate all source files for debug patterns. Release/production builds use production API endpoints. No more than 0 references to `localhost`, `127.0.0.1`, or staging URLs should appear in non-test source files. Development-only libraries are excluded via conditional imports or build flags. Report even on pass: "Scanned X source files, found Y debug references (all properly guarded by __DEV__ or environment checks)."
- **Fail criteria:** Production build references staging API endpoints (e.g., `api-staging.example.com`), includes debug tools or logging, or contains hardcoded localhost/test URLs outside of `__DEV__` guards.
- **Skip (N/A) when:** Never — releasing debug code to production creates security and data issues.
- **Cross-reference:** The Security Headers audit (`security-headers`) covers production endpoint security that complements this build configuration check.
- **Detail on fail:** Specify the issue. Example: `"Release build uses staging API: https://api-staging.example.com instead of production API"` or `"redux-logger is imported and enabled in production bundle"`
- **Remediation:** Production builds must point to production APIs and exclude development tools. Use environment-based configuration:
  1. Set up environment files:
     ```
     .env.development  (for local testing)
     .env.staging      (for staging builds)
     .env.production   (for release builds)
     ```
  2. In your app configuration:
     ```ts
     const API_URL = process.env.REACT_APP_API_URL || 'https://api.example.com';
     ```
  3. For Expo, use EAS Secrets:
     ```bash
     eas secret:create --scope project --name API_URL --value https://api.example.com
     ```
  4. Conditionally import debug tools:
     ```ts
     let middlewares = [];
     if (__DEV__) {
       middlewares.push(require('redux-logger').default);
     }
     ```
  5. Verify release build points to production APIs before submitting to store

## External references

- cwe CWE-489
- cwe CWE-200
- gdpr Art. 5

Taxons: placeholder-hygiene

HTML version: https://auditbuffet.com/patterns/ab-001941
