expo icon indicating copy to clipboard operation
expo copied to clipboard

Build-time secrets extraMavenRepos.credentials bundled into APK/AAB

Open MatthieuLemoine opened this issue 11 months ago • 0 comments

Minimal reproducible example

https://github.com/MatthieuLemoine/expo-app-config-leak

Steps to reproduce

I already reached out to Expo Support through [email protected]/[email protected] who asked me to create an issue with a minimal reproduction

Summary

When using the extraMavenRepos option in expo-build-properties, credentials defined in the app config are written to both gradle.properties (which is correct) and also included in the final APK/AAB, as part of the bundled app.config.

This results in a critical security issue: Maven repository credentials are exposed to anyone who downloads the app.

How to reproduce

  1. Create a new Expo project:
npx create-expo-app@latest
  1. Install expo-build-properties and configure it in app.json:
"plugins": [
  [
    "expo-build-properties",
    {
      "android": {
        "extraMavenRepos": [
          {
            "url": "https://example.com/maven",
            "authentication": "header",
            "credentials": {
              "name": "x-api-key",
              "value": "MY_API_KEY"
            }
          }
        ]
      }
    }
  ]
]
  1. Generate Android native project:
npx expo prebuild --clean --platform android
  1. Run a release build:
npx expo run:android --variant release
  1. Find the generated APK or AAB in android/app/build/outputs/apk/release and inspect its contents (replace extension by .zip then unarchive).
  2. You will find assets/app.config included in the binary, with the full structure and credentials in cleartext.

Why this is a problem

  • app.config is bundled for runtime needs (e.g. Expo Go or updates), but includes many build-only properties.
  • The current implementation leaks secrets like:
    • Maven repository credentials
    • Apple team ID
    • EAS project ID
    • All expo-build-properties settings

This goes against secure-by-default principles and can lead to credential leaks in production apps.

Expected Behavior

  • Only runtime-relevant properties should be bundled in the release build.
  • Build-time data, including anything under expo-build-properties, should be stripped automatically.
  • Credentials should never end up in the app binary.

Suggested Fixes

  • Remove support for credentials in extraMavenRepos, or emit a loud warning.
  • Redesign what parts of the app config are bundled with the final binary.

Environment

expo-env-info 1.3.3 environment info:
    System:
      OS: macOS 15.4.1
      Shell: 5.9 - /bin/zsh
    Binaries:
      Node: 18.19.0 - ~/Library/Caches/fnm_multishells/39044_1746633985892/bin/node
      Yarn: 1.22.21 - /opt/homebrew/bin/yarn
      npm: 10.2.3 - ~/Library/Caches/fnm_multishells/39044_1746633985892/bin/npm
      Watchman: 2025.03.10.00 - /opt/homebrew/bin/watchman
    Managers:
      CocoaPods: 1.16.2 - /opt/homebrew/bin/pod
    SDKs:
      iOS SDK:
        Platforms: DriverKit 24.1, iOS 18.1, macOS 15.1, tvOS 18.1, visionOS 2.1, watchOS 11.1
    IDEs:
      Android Studio: 2024.3 AI-243.22562.218.2431.13114758
      Xcode: 16.1/16B40 - /usr/bin/xcodebuild
    npmPackages:
      expo: ~53.0.9 => 53.0.9 
      expo-router: ~5.0.6 => 5.0.6 
      react: 19.0.0 => 19.0.0 
      react-dom: 19.0.0 => 19.0.0 
      react-native: 0.79.2 => 0.79.2 
      react-native-web: ~0.20.0 => 0.20.0 
    npmGlobalPackages:
      eas-cli: 16.4.0
    Expo Workflow: managed

Expo Doctor Diagnostics

15/15 checks passed. No issues detected!

MatthieuLemoine avatar May 09 '25 13:05 MatthieuLemoine