Skip to content

fix(analytics): validate hashed conversion inputs - #9234

Merged
mikehardy merged 2 commits into
invertase:mainfrom
OskarEichler:codex/analytics-validate-hashed-conversion-inputs
Sep 1, 2026
Merged

fix(analytics): validate hashed conversion inputs#9234
mikehardy merged 2 commits into
invertase:mainfrom
OskarEichler:codex/analytics-validate-hashed-conversion-inputs

Conversation

@OskarEichler

Copy link
Copy Markdown
Contributor

Description

Validate and safely decode the SHA-256 values passed to the hashed on-device conversion APIs.

React Native exposes the hashes as hex strings, while Firebase's Apple SDK requires the decoded 32-byte SHA-256 value. The previous decoder accepted any string, parsed non-hex pairs as lossy zero-like bytes, and indexed past the end of odd-length input. It could therefore pass malformed data to Firebase or raise an Objective-C exception.

This change:

  • requires exactly 64 hexadecimal characters at the public JavaScript boundary;
  • validates the same contract again at the native boundary;
  • decodes directly into a bounded 32-byte buffer;
  • documents the React Native hex-string representation.

Firebase's on-device conversion guide specifies that the SDK value must be a 32-byte SHA-256 digest rather than a hexadecimal string; this bridge decodes the validated 64-character representation before calling it.

Breaking changes

No public API or type changes.

This is an observable input-validation correction: malformed, non-hex, or non-64-character hash strings now reject instead of being silently decoded into invalid bytes or triggering an out-of-bounds exception. Valid lowercase and uppercase SHA-256 hex strings are unchanged.

Related issues

No matching open issue found.

Release Summary

Validated and safely decoded hashed Analytics on-device conversion inputs on iOS.

Checklist

  • I read the Contributor Guide and followed the process outlined there for submitting PRs.
    • Yes
  • My change supports the following platforms;
    • Android (shared JavaScript validation/no-op contract)
    • iOS
    • Other (shared validation and macOS compilation)
  • My change includes tests;
    • e2e tests added or updated in packages/**/e2e
    • jest tests added or updated in packages/**/__tests__
  • I have updated TypeScript types that are affected by my change. (No types are affected.)
  • This is a breaking change;
    • Yes
    • No

Test Plan

  • Analytics compile and existing Jest suites: 59/59 passing.
  • Focused temporary boundary control: 7/7 passing across valid lower/uppercase hashes, empty/short/long/odd/non-hex input; no test file is included in the patch.
  • Full JavaScript lint, dependency-cruiser validation, and TypeScript compile: passing.
  • iOS formatting and git diff --check: passing.
  • Fresh iOS and macOS pod installs: passing.
  • Android, iOS simulator, and macOS builds: passing.
  • Android native unit suite: passing.
  • Focused app + Analytics iOS E2E with valid hashed email and phone calls reaching native: 104 passing, 5 pending.

@mikehardy
mikehardy force-pushed the codex/analytics-validate-hashed-conversion-inputs branch from cee7526 to fefaa1e Compare August 30, 2026 23:05
@mikehardy

Copy link
Copy Markdown
Collaborator

Rebased onto current main and added coverage for the SHA-256 hashed on-device conversion contract.

Tests

  • Jest: empty / short / odd / long / non-hex reject, plus valid lowercase and uppercase 64-hex accept, for both hashed email and hashed phone. Hashed-phone non-strings are rejected as strings before the E.164 check.
  • E2e (analytics area): the same JS matrix on Android, iOS, and macOS. On iOS, NativeModules bypass hits the native decoder reject paths (empty / odd / non-hex) so the 32-byte hex decode is actually exercised.

Also in this update

  • Hashed-phone validation order is now string → E.164 → 64-character hex.
  • E.164 error text mentions the 64-character SHA-256 hex contract.

Local verification (Android ∥ iOS ∥ macOS)

  • Jest 74/74
  • Android 117 passing, iOS 123, macOS 110
  • 100% on reachable touched JS validation lines and the iOS native decoder

@mikehardy mikehardy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @OskarEichler 👋

Thanks for the PR - this looks like a real problem to me. I ran local Jest/unit plus the android/ios/macos e2e suite against it here and it came out clean. Pending CI, then I'll merge.

Cheers

@mikehardy mikehardy added the Workflow: Pending Merge Waiting on CI or similar label Aug 30, 2026
@codecov

codecov Bot commented Aug 30, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 68.59%. Comparing base (688775c) to head (7e65114).
⚠️ Report is 25 commits behind head on main.

Additional details and impacted files
@@             Coverage Diff              @@
##               main    #9234      +/-   ##
============================================
- Coverage     68.62%   68.59%   -0.03%     
- Complexity     1917     2096     +179     
============================================
  Files           525      441      -84     
  Lines         38250    25163   -13087     
  Branches       5206     4256     -950     
============================================
- Hits          26247    17257    -8990     
+ Misses        10203     6528    -3675     
+ Partials       1800     1378     -422     
Flag Coverage Δ
android-native 65.06% <ø> (+1.27%) ⬆️
e2e-ts-android 54.09% <66.67%> (+0.15%) ⬆️
e2e-ts-ios 53.62% <66.67%> (+0.12%) ⬆️
e2e-ts-macos 49.88% <66.67%> (+0.18%) ⬆️
ios-native ?
ios-ruby ?
jest 47.23% <100.00%> (+0.10%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@mikehardy
mikehardy force-pushed the codex/analytics-validate-hashed-conversion-inputs branch from fefaa1e to b8606ef Compare September 1, 2026 11:11
@mikehardy
mikehardy force-pushed the codex/analytics-validate-hashed-conversion-inputs branch from b8606ef to 7e65114 Compare September 1, 2026 11:14
@mikehardy
mikehardy merged commit 0470b71 into invertase:main Sep 1, 2026
3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Workflow: Pending Merge Waiting on CI or similar

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants