CLI-801 Parse Web Push params by name and support aes128gcm#13
CLI-801 Parse Web Push params by name and support aes128gcm#13cassiostp wants to merge 2 commits into
Conversation
Pre-existing lint failures that kept 'yarn lint' red on master. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Since 2026-06-04 a fraction of FCM deliveries carry crypto-key values with multiple parameters (dh=<key>;p256ecdsa=<key>). Slicing fixed offsets feeds garbage into ECDH, so decryption throws "Public key is not valid for specified curve" and the push is lost and redelivered on every reconnect. Extract dh/salt by name instead, accepting ';' and ',' separators in any order. Missing-parameter errors now name the parameters present (never their values, which may be key material) and embed the 'crypto-key is missing'/'salt is missing' substrings so Client drops and acks such messages instead of throwing unhandled. Also decrypt aes128gcm (RFC 8291) envelopes, where keys travel in the payload's binary header — observed FCM envelopes already carry a content-encoding field, suggesting that migration is being staged. Bump version to 2.1.6. CLI-801 Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
83abea2 to
0007c21
Compare
Could you link me to logs where we see this? Or if there are no logs how do we know this? EDIT: |
|
@zindlerb By the original ticket description this happened before but stopped at some point, but bugsnag confirms it started happening again on june 4 I added some extra logging to staging, as we have a very similar pattern there and got these results |
|
@cassiostp Makes sense thanks |
zindlerb
left a comment
There was a problem hiding this comment.
This seems reasonable to me. Thanks for the investigation here!
Before we merge this could you make a change to the _onDataMessage error handling?
Since we rarely touch this code I'm worried that we silence some of the errors and might not be able to see if theres a new issue introduced. I alsop Could we update it so we raise error for:
case error.message.includes(
'Unsupported state or unable to authenticate data'
):
case error.message.includes('crypto-key is missing'):
case error.message.includes('salt is missing'):
these? Would still do this._persistentIds.push before raising.
Want to do this in a diff pr so we have baseline errors before this change. It also would be good to get visibility into those errors in general.
Since June 4, Google's FCM delivery layer sends a fraction of pushes (~0.8% of messages, ~36% of Superhuman desktop's push-active devices daily) with a
crypto-keyvalue of the formdh=<key>;p256ecdsa=<key>.decryptslices fixed offsets out ofcrypto-key/encryption, so these envelopes feed garbage into ECDH and die with the unhandled "Public key is not valid for specified curve" — the push is lost, and because it is never acked, MCS redelivers it on every reconnect. The wire format was confirmed by instrumentation in the Superhuman desktop shell (staging capture,crypto_key_params: dh;p256ecdsacorrelated with the curve error on the same message). This extractsdh/saltby name, accepting;/,separators in any order.Two deliberate details worth reviewing closely. First, the new missing-parameter errors name the parameters present but never echo values (which may be key material), and they intentionally embed the existing
crypto-key is missing/salt is missingsubstrings —Client._onDataMessage's catch matches on those, so malformed envelopes now drop-and-ack instead of crash-looping, with zero changes to client.js. Second, envelopes whosecontent-encodingappData saysaes128gcm(RFC 8291 — keys travel in the payload's binary header,crypto-keydisappears) are decrypted via http_ece's aes128gcm support; the captured envelopes already carry acontent-encodingfield, which suggests Google is staging that migration.test/decrypt.test.jsis the repo's first hermetic suite (real http_ece round-trips, no FCM credentials — the existingnotification.test.jsneeds live keys): old format, both new formats, aes128gcm, and the error contracts. The first commit fixes two pre-existing semicolon lint errors insrc/gcmsoyarn lintis green again. Version is bumped to 2.1.6 per repo convention; after merge this needs a manualnpm publishby an@superhumannpm maintainer, then the desktop repo picks it up via a yarn resolution override (CLI-801 has the full investigation).