Skip to content

Keep bridge call parameters and results out of release logcat - #523

Merged
shanerbaner82 merged 1 commit into
NativePHP:mainfrom
prosenthal828:fix/android-bridge-jni-release-logging
Oct 11, 2026
Merged

shanerbaner82 merged 1 commit into
NativePHP:mainfrom
prosenthal828:fix/android-bridge-jni-release-logging

Conversation

@prosenthal828

Copy link
Copy Markdown
Contributor

Problem

resources/androidstudio/app/src/main/cpp/bridge_jni.cpp logs every NativePHPCall with LOGI: the function name, the full parameter JSON and the full result JSON. It also logs every NativePHPCan lookup. Nothing guards these lines, so release builds write all bridge traffic to logcat.

Bridge payloads can carry tokens, keys and user data. Logcat is readable over adb and ends up in bug reports. In a release build installed from Play internal testing (installer com.android.vending), logcat showed the Parameters JSON / Result JSON lines for each bridge call. That included the full result of a Play Integrity call (the plugin's integrity-token payload), in plain text.

Fix

  • New LOGT macro. It is LOGI in debug builds and a no-op when NDEBUG is defined. CMake defines NDEBUG for Release/RelWithDebInfo, which Gradle uses for release builds.
  • The per-call lines in NativePHPCan / NativePHPCall use LOGT. Debug output keeps the same text at the same INFO level.
  • LOGE error lines (function name only, no payloads) and the one-time init lines are unchanged.

Tests

tests/Unit/Support/BridgeJniLoggingTest.php checks:

  • the NDEBUG guard on LOGT
  • that NativePHPCan / NativePHPCall contain no LOGI
  • that no always-on log receives parametersJSON or resultStr

The 4 tests fail on main and pass here. Full suite: 1496 passed, 3 skipped, 4 risky (same as main).

Tested on real devices

Galaxy A54 (SM-A546U1), app on core 4.5.2 with this change:

  • Debug build (assembleDebug): BridgeJNI still logs every call. One launch gave 58 Parameters JSON / Result JSON lines, for example NativeUI.Theme.Set with its parameters and Result JSON: {}.
  • Release build (assembleRelease): the compiled libphp_wrapper.so no longer contains the Parameters JSON / Result JSON format strings (0 matches, against 2 and 1 in the debug .so). The error strings are still there.
  • Release build on device (assembleRelease, not debuggable): one launch made 13 bridge calls, among them Biometric.Prompt, AppLock.State and Device.GetInfo. BridgeJNI logged only its init and Element lines. The logcat buffer had 0 Parameters JSON / Result JSON lines.

Not in this PR (follow-ups)

Other native logs that also run in release builds:

  • PHP.c logs request cookies at INFO (HTTP_COOKIE from env: ... and Parsed cookie → key = value). That includes the Laravel session cookie.
  • php_bridge.c logs every SAPI response header at INFO (SAPI header: ...), including Set-Cookie.
  • On iOS, BridgeRouter.swift print()s call parameters. That goes to stdout, which isn't in the device's unified log unless a debugger is attached.

The same LOGT pattern would cover the Android ones. I'm happy to send that separately.

🤖 Generated with Claude Code

bridge_jni.cpp logged every NativePHPCall's parameter JSON and result JSON
(and each NativePHPCan lookup) with LOGI, in release builds too. Bridge
payloads can carry tokens, keys and user data, and logcat is readable over
adb and in bug reports.

Per-call tracing now goes through LOGT, which is LOGI in debug builds and
compiled out when NDEBUG is defined (CMake Release/RelWithDebInfo, which
Gradle uses for release builds). LOGE error lines and the one-time init
lines are unchanged. A source test guards the macro and that no always-on
log receives parametersJSON or resultStr.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@shanerbaner82
shanerbaner82 merged commit 7eb46b2 into NativePHP:main Oct 11, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants