YinkoShield

Knowledge Center / Mobile runtime attacks / mobile runtime attacks · 2025·12

Transaction parameter tampering — modifying values between confirm and submit

On hybrid runtimes — React Native, Flutter, Capacitor, Cordova — the user-visible payload sits in the JavaScript or Dart heap before it crosses the bridge to native code and from there to the network. An attacker with code execution inside the process can rewrite the payload in that interval. The user sees one transaction; the network receives another.

[ transaction parameter tampering — confirm/submit race ] t₁ · user confirm amount = 50 payee = Mary K. UI render → confirm tap payload in JS heap user-visible state tampering window attacker code modifies payload JS heap rewrite · bridge intercept native hook on okhttp / URLConnection amount: 50 → 5000 payee: Mary K. → attacker window: ~10ms–seconds t₂ · network submit amount = 5000 payee = attacker arrives at backend · signed looks like a valid request backend-visible state substrate signal: binding.status { confirm_hash ≠ submit_hash }
The user confirms one set of values. Between confirm and submit, an attacker process modifies the payload. The backend receives different values from the ones the user agreed to.

1. Mechanism

The attack class targets the interval between two events that are typically separated in time by tens of milliseconds to seconds:

  • t₁ — user confirmation. The user reads the rendered payload (amount, beneficiary, reference) and presses confirm. The payload sits, momentarily, in application state.
  • t₂ — network submission. The application serialises the payload, hands it to the platform’s HTTP stack, and the request reaches the backend.

Between t₁ and t₂, the payload is mutable. A malicious process sharing the application’s address space — through library injection, a compromised JS bundle, a hooked native call, or a compromised dependency — can mutate the values. The backend receives a structurally valid request with attacker-chosen parameters, often signed by whatever credential the user just authenticated with.

2. Where in the runtime it operates

Two surfaces are common:

  • The interop layer (varies by framework).
    • React Native (legacy) uses an asynchronous JS-to-native bridge.
    • React Native New Architecture (default from 0.76) replaces the bridge with the JavaScript Interface (JSI), exposing native objects directly to JS [3].
    • Flutter compiles Dart to native AOT and crosses to platform code via MethodChannel / Pigeon; there is no JavaScript engine in the runtime.
    • Cordova / Capacitor run the payload inside a WebView (V8 / JavaScriptCore) and cross to native via WebView bridges. Hooks installed at any of these interop points — Frida, Xposed, a malicious dependency — can mutate values as they cross.
  • The HTTP stack. Native-level hooks on OkHttp.newCall(), URLConnection.connect(), or platform networking libraries intercept the outbound request and rewrite the body before transmission. OWASP MASTG documents this class of attack comprehensively [1, 2].

The hybrid-runtime case is the most common because the payload lives in a managed-language heap (JS, Dart) where dynamic modification is straightforward and where the surface area for hook attachment is wider.

3. Which checkpoints it bypasses

  • Play Integrity / App Attest / FIDO2. All produce valid responses for the moment they were called. The credential is authentic; the assertion is valid; the device is healthy. None of these checkpoints sign the transaction body.
  • EMV (HCE / SE-backed contact / contactless). The cryptogram (ARQC) is computed by the chip or secure element over the EMV-defined inputs that reach it. If the inputs handed to the chip were tampered in the application before the chip-side computation, the resulting cryptogram is valid for the tampered values.
  • 3DS2. The challenge / response is server-side at the Access Control Server; the device does not produce a payment cryptogram in the EMV sense. A device-side parameter-tampering attack changes what is submitted to the merchant / 3DS Requestor — not what the ACS signs. PSD2 dynamic linking (Commission Delegated Regulation (EU) 2018/389, Article 5) binds the SCA authentication code to amount and payee on the issuer side; a mid-flow change to amount or payee invalidates the code at the rail layer. Dynamic linking is the regulatory countermeasure to this attack class on the issuer side; the device-side gap remains the operator’s to close.
  • Behavioural biometrics. The session looks like the user because it is the user — only the payload that left the device differs from what they confirmed.

The attack succeeds because no standard checkpoint binds the confirmed payload at t₁ to the submitted payload at t₂. That binding has to be established outside the standard checkpoint substrates.

4. Which signals make it observable

binding.status. The Trusted Runtime Primitive observes both the user-confirmation event (the payload values rendered to the user and committed to confirm) and the network-submission event (the payload values handed to the HTTP stack). The substrate computes a hash over each and compares.

When the two hashes differ, the substrate signs a binding.status event recording the discrepancy.

5. Evidence Token shape when observed

The following example is illustrative; field names, type values, and schema are defined in YEI-001 §4 (available through the spec-access process).

{
  "ev": [
    {
      "ts":   "2026-06-15T10:23:11.420Z",
      "class": "binding.status",
      "type":  "confirm.bound",
      "data":  { "confirm_hash": "sha256:9a2c…b1" }
    },
    {
      "ts":   "2026-06-15T10:23:11.880Z",
      "class": "binding.status",
      "type":  "submit.divergence",
      "data": {
        "confirm_hash": "sha256:9a2c…b1",
        "submit_hash":  "sha256:e431…77",
        "delta_ms":     460
      }
    }
  ]
}

The operator’s verifier reads the submit.divergence as a signed claim that the values left the device differing from the values the user confirmed. Execution Evidence Infrastructure (EEI) — the device-identity infrastructure layer for banking and payments — closes the device-side end of the gap that PSD2 dynamic linking covers on the issuer side.

6. Cross-references

7. External references

[1] OWASP. Mobile Application Security Testing Guide (MASTG). mas.owasp.org/MASTG/. Cited 2025-12-22.

[2] OWASP MASTG. Android Platform Internals. mas.owasp.org/MASTG/Android/0x05a-Platform-Overview/. Cited 2025-12-22.

[3] React Native. New Architecture — JavaScript Interface (JSI). reactnative.dev/architecture/landing-page. Cited 2025-12-22.

[4] European Commission. Commission Delegated Regulation (EU) 2018/389 — RTS on Strong Customer Authentication, Article 5 (Dynamic linking). EUR-Lex CELEX:32018R0389. Cited 2025-12-22.