feat(proxy): accept inbound EQL ciphertext payloads - #458
Open
freshtonic wants to merge 7 commits into
Open
Conversation
Signed-off-by: James Sadler <james@cipherstash.com>
Signed-off-by: James Sadler <james@cipherstash.com>
tobyhede
reviewed
Aug 20, 2026
tobyhede
left a comment
Contributor
There was a problem hiding this comment.
Reviewed the new inbound EQL ciphertext path. One security issue with two exploit paths, one design trade-off to confirm, and one operational gap. Each item was checked against the actual code on this branch and the cipherstash-client 0.42.2 dependency source before being posted here. Two items from an earlier automated pass did not hold up under verification and are not included: the "h" top-level key check is not dead code (it detects SteVec payloads, which carry no top-level c field), and the binary-parameter byte handling in bind.rs does not corrupt data (original bytes stay untouched, and a failed trial parse falls back safely).
See inline comments for details.
Signed-off-by: James Sadler <james@cipherstash.com>
freshtonic
commented
Aug 20, 2026
Scope the ZeroKMS cipher to CS_DEFAULT_KEYSET_ID whenever a connection has not selected an override. Previously Proxy only checked that the setting existed, then passed no identifier to ScopedCipher and could silently use the client's account default instead. Application-encrypted payloads use the configured keyset explicitly. When the account and configured defaults differ, Proxy derived searchable-encryption metadata with another index key and rejected valid inbound ciphertext during authentication. Preserve connection-level keyset precedence while making the configured fallback effective. Signed-off-by: James Sadler <james@cipherstash.com>
Inbound EQL authentication independently re-encrypts plaintext and compares its searchable-encryption metadata with the supplied payload. Match-index generation does not guarantee a stable ordering for Bloom-filter bit positions, so comparing serialized query operands rejected valid ciphertext whenever equivalent positions were emitted in another order. Compare scalar metadata field by field and normalize Bloom-filter positions before equality. Continue comparing identifiers, exact-match terms, ordered terms, versions, and structured SteVec operands exactly so altered metadata still fails closed. Add a regression test covering reordered equivalent Bloom-filter terms. Signed-off-by: James Sadler <james@cipherstash.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.
Summary
cipherstash-proxy-integrationTesting
cargo test -p cipherstash-proxy inbound_eql --libcargo test -p cipherstash-proxy --lib(135 passed; one environment-sensitive config test passed when rerun alone)cargo test -p cipherstash-proxy config::tandem::tests::missing_database_config --lib -- --exactcargo clippy -p cipherstash-proxy --all-targets -- -D warningscargo clippy -p cipherstash-proxy-integration -p showcase --all-targets -- -D warningscargo test -p cipherstash-proxy-integration --no-runcargo test -p showcase --no-runcargo fmt --all -- --checkThe runtime integration/showcase cases use the existing credentialed CI tasks. This checkout had no application/ZeroKMS credentials with which to start an isolated current-branch Proxy locally.
Linear: CIP-3822