Keep every ciphertext column out of JSON, and guard the rule library-wide

Fixkamo-shared-library
Shipped
September 17, 2026 at 1:57 AM UTC
Author
Kamo
Commit
034378d

Follow-up to 096feaa1 (Organization's GoDaddy credentials were being served by an endpoint that needs no session). A scan of every **************** found fourteen more columns holding ciphertext with no Jackson guard, beside fifteen that had always been @JsonIgnore: Borrower.ssnEncrypted, Borrower.itinEncrypted Asset / Liability / ReoLien.accountNumberEncrypted PlatformOAuthClient / OrgOAuthClient .secretCiphertext and .extraSecretsCiphertext **************** (the TOTP secret) DevMachineAccount.secretCipher **************** **************** .refreshTokenCiphertext All fourteen are now @JsonIgnore. Audited before changing, on origin/main of every repository that uses these entities: each is encrypted and decrypted only on rows loaded through JPA, every endpoint answers with a hand-built DTO or map, request bodies carry plaintext that the server encrypts, and nothing reads the ciphertext back out of JSON (no readValue/convertValue into these types, no JSON cache, no service-to-service transfer of the entities). For those ten entities this closes no live leak — it removes the one-line change (returning the entity, or nesting it) that would have opened one. @JsonIgnore rather than WRITE_ONLY so a request body bound to the entity cannot plant ciphertext either. **************** asserts it by reflection over every persistent type, the way JsonbBindingTest guards jsonb bindings: a column is ciphertext when its field says cipher or its column says CIPHER, ENCRYPTED or ends _ENC, and it must be @JsonIgnore or WRITE_ONLY. It failed on exactly these fourteen before the change, and its companion test proves the scan still sees ciphertext named four different ways.

All changes

Like what you see shipping?

All of it arrives in your workspace on its own. Start on the free plan and read this page again in a month.

Start Free ForeverView Pricing