[SPARK-57785][SQL][CONNECT] harden: spark connect client's reattachment mechanism a... in... - #57778
Open
anupamme wants to merge 5 commits into
Open
Conversation
Automated security fix generated by OrbisAI Security
Contributor
|
@anupamme , Thanks for the PR.
|
Member
|
Please keep the PR description template, file a JIRA and add it into PR title |
HyukjinKwon
reviewed
Aug 5, 2026
…tion fix Add a unit test that verifies a single-use generator passed as `metadata` to `ExecutePlanResponseReattachableIterator` is preserved across all subsequent RPCs (`ReattachExecute`, `ReleaseExecute`), not exhausted on the first call. Also extend `MockSparkConnectStub` to record the metadata kwarg received by each RPC method so tests can assert on it. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Author
addressed. pls review. |
uros-b
reviewed
Aug 5, 2026
…lized metadata The previous fix materialized metadata into self._metadata via list(metadata) but the initial ExecutePlan call still passed the raw metadata parameter. For a generator input, list(metadata) exhausts it first, so ExecutePlan would receive an empty iterator. Use self._metadata consistently for all RPCs. Update the generator exhaustion test to also assert the initial ExecutePlan received the header. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HyukjinKwon
reviewed
Aug 5, 2026
Add List to the typing imports and annotate self._metadata as List[Tuple[str, str]] to reflect that list(metadata) always produces a list, not a generic Iterable. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
HyukjinKwon
reviewed
Aug 5, 2026
…nect client Tighten metadata type annotations across the three connect client files that form the type chain: - ChannelBuilder.metadata() return type: Iterable -> List - ExecutePlanResponseReattachableIterator.__init__ param: Iterable -> List - ArtifactManager.__init__ param: Iterable -> List - ArtifactManager._metadata attribute: add List annotation + list() copy Co-Authored-By: Claude Sonnet 4.6 <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.
What changes were proposed in this pull request?
This PR changes SparkConnectClient in python/pyspark/sql/connect/client/reattach.py so that the gRPC metadata passed in is converted to a list at assignment time:
instead of storing it as-is:
This guarantees
self._metadatais a re-iterable sequence, since it is reused across multiple RPCs on the same client (ExecutePlan,ReattachExecute,ReleaseExecute).Why are the changes needed?
If metadata is ever passed as a one-shot iterable (e.g. a generator) rather than a list/tuple, it gets exhausted the first time it's iterated over. Because the same
self._metadatais reused for later RPCs (retries, reattach, release), any RPC after the first would silently send empty metadata, which could drop auth-related headers without raising any visible error. Converting to a list up front removes this class of bug regardless of what iterable type is passed in.No currently known caller passes a non-list iterable for metadata, so this is preventative hardening rather than a fix for an observed live bug.
Does this PR introduce any user-facing change?
No.
How was this patch tested?
Added a unit test for this change.
Existing unit tests for
SparkConnectClientcontinue to pass. Added/to-add: a unit test that passes a single-use generator asmetadata, issues two sequential RPCs (e.g.ReattachExecutethenReleaseExecute) on the same client, and asserts the metadata headers are present and unchanged on both calls.Vulnerability
V-003python/pyspark/sql/connect/client/reattach.py:329Description: Spark Connect client's reattachment mechanism allows resuming sessions using only the session_id without fresh authentication. An attacker who obtains a valid session_id (e.g., from logs or network traffic) can hijack the session.
Threat Model Context
This is a Python library - vulnerabilities affect applications that import this code.
Changes
python/pyspark/sql/connect/client/reattach.pyBehavior Preservation
The change is scoped to 1 file on the vulnerable path; it only tightens handling of untrusted input and leaves valid inputs unaffected.
Security Invariant
Regression test
This test guards against regressions — it's useful independent of the code change above.
This patch removes an exploit primitive — a code pattern that, while not independently exploitable today, could be chained with other weaknesses by automated exploit-development tooling. Proactive removal of such primitives raises the bar against increasingly capable automated attack tools.
Automated security fix by OrbisAI Security