fix(pii): redact card authorization codes and brand+last4 in Sabre remarks - #80
Closed
armona wants to merge 1 commit into
Closed
fix(pii): redact card authorization codes and brand+last4 in Sabre remarks#80armona wants to merge 1 commit into
armona wants to merge 1 commit into
Conversation
…marks
An audit of every fixture for surviving card data found authorization lines leaking
two pieces of payment data beyond the PAN: the acquirer approval code and a
<brand><last four> fragment.
GetReservationRS was the worst case — "XXAUTH/<approval> *Z/<brand><last4>" and
"CC APVL/<approval>/TKT/<carrier>/<brand><last4>" passed through completely untouched,
leaking the last four digits of the card on the operation a customer had reported.
Trip_SearchRS already covered the card fragment via sabre.trip.card_fragment_remark
but left the approval code ("AUTH-APV/<code>", "XXAUTH/<code>") in the clear.
Both are already classified as payment data elsewhere in the baseline —
amadeus.transaction.payment redacts approvalCode and sabre.etkt.payment_approval masks
@ApprovalID — so the reservation and trip-search remark forms were an inconsistency,
not a new policy call. Redacted one-way, matching the existing payment action policy.
Markers, amounts, dates, carrier codes and the status lines that carry no card data are
preserved, as is the card brand word on its own; only the last four beside it is
sensitive. Patterns stay anchored on the literal AUTH/APVL markers.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Follow-up to #79. You asked whether the payloads carried credit-card data and whether it was
anonymized. Rather than answer from the earlier analysis alone, I audited every fixture for both
channels — redacting each through the real engine with the per-channel operation parser the forwarder
uses, then scanning the output for card shapes (masked PAN, bare PAN, expiry, CVV, approval codes,
<brand><last four>).Result: card numbers are covered everywhere, including the Travelfusion
CreditCardblock(
Number,SecurityCode,ExpiryDateall tokenized) and the Sabre/Amadeus card elements. But cardauthorization lines leak two other pieces of payment data:
XXAUTH/<approval> *Z/<brand><last4>GetReservationRSCC APVL/<approval>/TKT/<carrier>/<brand><last4>GetReservationRSAUTH-APV/<approval>/000/USD…Trip_SearchRSXXAUTH/<approval>/<masked PAN>/…Trip_SearchRSAUTH-AMEX/<brand><last4>/…Trip_SearchRSGetReservationRSis the operation the original customer report was about, and it was leaking thelast four digits of the card plus the acquirer approval code in cleartext.
This is an inconsistency rather than a new policy call: the baseline already classifies both as
payment data —
amadeus.transaction.paymentredactsapprovalCode, andsabre.etkt.payment_approvalmasks@ApprovalID. Only the reservation and trip-search remarkrenderings were uncovered.
What changed
Three rules, all one-way
replaceper the existing payment action policy, all anchored on theliteral
AUTH/CC APVLmarkers:sabre.res.auth_approval_code— approval code in the three renderings, across the remark path andboth history mirrors.
sabre.res.auth_card_fragment—<brand><last four>in theAUTHandCC APVLforms.sabre.trip.auth_approval_code— approval code onTrip_SearchRS.Preserved deliberately: the
AUTH-/XXAUTH//CC APVL/markers, amounts (USD423.20,USD388.90 - USED), dates, carrier codes (/TKT/DL/), theAUTH-AVS NOT SUPPORTEDandAUTH-CSC NOT SUPPLIEDstatus lines, and the card brand word on its own — a brand alone is notsensitive; the last four beside it is.
Testing
TestCardAuthorizationRemarks— 3 tests covering bothGetReservationRSrenderings, theTrip_SearchRSapproval code and fragments, and the operational-text negatives. Written failingfirst; 2 of 3 failed before the rules landed.
Re-ran the full card audit afterwards: zero real survivors across all fixtures for all five
channels. 695 tests pass.
Note, not a defect
Travelfusion encrypts the card
NumberandSecurityCode(CVV) reversibly, where Sabre/Amadeus use aone-way sentinel. That asymmetry looks deliberate — the relay must hand the real values to the
supplier on the request path to complete a booking — so I left it alone. Flagging it in case you want
that revisited separately.
🤖 Generated with Claude Code