fix(ingestion): patch PySpark-bundled CVE jars in ingestion-slim image; dedupe jar surgery across Dockerfiles - #30751
Conversation
…park jar surgery The ingestion-slim image (ingestion/operators/docker/Dockerfile*) shipped vulnerable jars bundled by PySpark 3.5.6 that the earlier CVE fix (#30516) never patched — that fix only touched the airflow image (ingestion/Dockerfile*), so the PySpark jar surgery never reached the slim image. AWS Inspector kept flagging zookeeper, jackson-asl, netty, and a phantom black finding on it. Extract the jar patch into a single SHA256-pinned script and run it in all four ingestion Dockerfiles so the two images can no longer drift: - zookeeper 3.6.3 -> 3.7.2 CVE-2023-44981 (SASL quorum auth bypass) - jackson-mapper/core-asl 1.9.13 CVE-2019-10202 (removed; no upstream fix) - netty-codec-http 4.1.96 -> 4.1.135 CVE-2026-42581 / CVE-2026-42584 (both fixed in 4.1.133.Final; staying on the 4.1.x line keeps binary compatibility with PySpark's sibling netty 4.1.96 jars — verified pyspark and SparkSession still import) Also strip spacy's bundled tests/package/requirements.txt from the slim images: it pins an old black that scanners misreport as an installed package (CVE-2026-31900). The file is test-only and never imported at runtime. Left as documented residuals (no drop-in fix for this runtime): - derby 10.14.2.0 (CVE-2022-46337): only fix needs Java 21, image is Java 17; vulnerable LDAP path unused - jetty 9.4.x (CVE-2026-2332): shaded inside hadoop-client-runtime / spark-core uber-jars, not a swappable standalone jar; clears on a future pyspark bump Verified against a local build of the slim CI image: patched jars present, jackson-asl and the black fixture gone, pyspark imports cleanly. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
❌ PR checklist incompleteThis PR cannot be merged until the following are addressed on its linked issue:
The fields live on the linked issue in the Shipping project (open the issue → right sidebar → Projects). After you set them, re-run this check (or push a commit) — issue/project changes do not re-trigger it automatically. Maintainers can bypass this check by adding the |
There was a problem hiding this comment.
Pull request overview
This PR closes a security gap where PySpark-bundled vulnerable JARs were previously patched only in the Airflow ingestion images, leaving the ingestion-slim images still carrying the flagged CVEs. It extracts the JAR “surgery” into a shared script and wires it into both image families to prevent future drift.
Changes:
- Adds a shared, SHA256-pinned script to patch/remove vulnerable PySpark-bundled JARs (ZooKeeper, Jackson ASL, Netty codec-http).
- Replaces the previously inlined Airflow-image patch block with a call to the shared script.
- Applies the patch for the first time to ingestion-slim images and removes a spacy test-fixture
requirements.txtthat triggers a phantom scanner finding.
Reviewed changes
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| ingestion/scripts/patch_pyspark_jars.sh | New shared script to patch/remove vulnerable PySpark-bundled JARs with SHA256 verification. |
| ingestion/Dockerfile | Replaces inline jar patch logic with a call to the shared patch script. |
| ingestion/Dockerfile.ci | Replaces inline jar patch logic with a call to the shared patch script. |
| ingestion/operators/docker/Dockerfile | Adds shared patch script invocation + removes spacy test fixture requirements file in slim image. |
| ingestion/operators/docker/Dockerfile.ci | Adds shared patch script invocation + removes spacy test fixture requirements file in slim CI image. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (1)
ingestion/scripts/patch_pyspark_jars.sh:20
- The header comment’s Netty version string doesn’t match the actual jar being fetched (
netty-codec-http-4.1.135.Final.jar). This can mislead future updates/audits; align the comment with the real artifact/version suffix (Final).
# netty-codec-http 4.1.96 -> 4.1.135 CVE-2026-42581 / CVE-2026-42584 (HTTP request smuggling);
# both fixed in 4.1.133.Final, so staying on the 4.1.x line keeps
# binary compatibility with PySpark's sibling netty 4.1.96 jars.
|
@harshsoni2024 I reviewed the current head ( I think the following need to be addressed before merge:
Please also add an exact release-chain regression check that builds the final slim target and asserts: old vulnerable JARs are absent, replacement JAR hashes match, the scanner-only fixture is absent, and an unexpected PySpark import failure fails the build. The current operator build job exercises the default Separately, repository guidance asks bug-fix PRs to include a linked issue and a regression test; this PR currently has neither (the metadata check was bypassed with Recommendation: request changes, primarily because the final shipped release image can still contain the vulnerabilities this PR intends to remediate. |
✅ Playwright Results — workflow succeededValidated commit ✅ 107 passed · ❌ 0 failed · 🟡 0 flaky · ⏭️ 3 skipped · 🧰 0 lifecycle flaky PerformanceBlocking targets: ✅ met · Optimization targets: 🟡 in progress Shard-job maxima below are not the full workflow wall time; the linked run includes build, fixture, planning, and reporting. 🕒 Full workflow signal wall (to summary) 48m 39s ⏱️ Max setup 2m 57s · max shard execution 11m 48s · max shard-job elapsed before upload 17m 55s · reporting 3s 🌐 208.10 requests/attempt · 1.76 app boots/UI scenario · 0.00% common-shard skew Optimization targets still in progress:
How to debug locally# Download playwright-test-results-<shard> artifact and unzip
npx playwright show-trace path/to/trace.zip # view trace |
…cleanup into jar patch Address review feedback on the PySpark CVE-jar remediation: - Detection no longer fails open. Previously `python -c 'import pyspark' 2>/dev/null || true` treated a broken-but-installed pyspark the same as an absent one, letting an image with unpatched jars ship silently. The script now distinguishes three cases via exit code: genuinely absent (skip), installed-but-unimportable (fail the build), importable (patch). - Fold the spaCy test-fixture cleanup (spacy/tests/**/requirements.txt, the phantom black CVE-2026-31900) into patch_pyspark_jars.sh so it runs wherever the patch runs, and drop the separate per-Dockerfile `find ... -delete` RUN lines that could drift. Self-guarding and idempotent: no-op when pyspark is absent (INGESTION_DEPENDENCY=slim builds), active when present (default `all`). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.
Suppressed comments (1)
ingestion/scripts/patch_pyspark_jars.sh:20
- The header comment says netty-codec-http is patched to "4.1.135", but the script actually installs
netty-codec-http-4.1.135.Final.jar. Aligning the comment to the exact artifact version avoids confusion when auditing scanner results.
# netty-codec-http 4.1.96 -> 4.1.135 CVE-2026-42581 / CVE-2026-42584 (HTTP request smuggling);
# both fixed in 4.1.133.Final, so staying on the 4.1.x line keeps
# binary compatibility with PySpark's sibling netty 4.1.96 jars.
…ils closed instead of skipping
|
@harshsoni2024 I completed a follow-up review of the current head ( The earlier functional blockers are substantially improved: installed-but-broken PySpark now fails closed, the shared script is invoked from all four OpenMetadata Dockerfiles, the replacement hashes match, and the Collate extension now invokes the remediation after its final The remaining changes I believe are needed before merge are:
The JAR replacement itself looks sound based on the targeted runtime validation; my request-changes recommendation remains because the security invariants are still manual and the spaCy path can fail open. |
To briefly address above comments. |
There was a problem hiding this comment.
Pull request overview
Copilot reviewed 5 out of 5 changed files in this pull request and generated no new comments.
Suppressed comments (1)
ingestion/scripts/patch_pyspark_jars.sh:20
- The header comment says netty-codec-http is patched to
4.1.135, but the script actually fetchesnetty-codec-http-4.1.135.Final.jar. Aligning the documented version with the actual jar name avoids confusion when scanning image contents.
# netty-codec-http 4.1.96 -> 4.1.135 CVE-2026-42581 / CVE-2026-42584 (HTTP request smuggling);
# both fixed in 4.1.133.Final, so staying on the 4.1.x line keeps
# binary compatibility with PySpark's sibling netty 4.1.96 jars.
|
🚦 Removed from the merge queue —
|
Code Review ✅ Approved 4 resolved / 4 findingsCentralizes PySpark-bundled CVE jar remediation and spaCy test fixture cleanup into a shared, checksum-verified script applied across all ingestion Dockerfiles, addressing concerns around jar surgery duplication, netty compatibility, and build failure handling. ✅ 4 resolved✅ Edge Case: jackson-asl jars removed without replacement may break Hive path
✅ Quality: netty 4.1.135 codec-http mixed with 4.1.96 siblings only import-tested
✅ Bug: spaCy fixture cleanup skipped when PySpark absent
✅ Quality: find -delete can fail build (lost
|
| Compact |
|
Was this helpful? React with 👍 / 👎 | Gitar | Powered by Gitar — free for open source



Describe your changes
AWS Inspector flagged CRITICAL CVEs on the ingestion-slim image.
Every flagged Java finding traced to PySpark's bundled jars under
.../site-packages/pyspark/jars/— not topom.xml(the slim image compiles noJava; the jars come from the
deltalake/pysparkpip dependency).What changed
ingestion/scripts/patch_pyspark_jars.sh— the jarsurgery, extracted so the airflow and slim images can no longer drift. It is
SHA256-pinned and self-guarding (no-op when PySpark isn't installed).
drop their ~30-line inline block for a 4-line call to the shared script; the
two slim Dockerfiles gain the patch for the first time.
spacy/tests/package/requirements.txt— a spacy CItest fixture that pins an old
black, which scanners misreport as an installedpackage (CVE-2026-31900). The file is test-only, never imported at runtime.
CVEs resolved
netty stays on the 4.1.x line (both CVEs fixed in 4.1.133.Final) to keep
binary compatibility with PySpark's ~18 sibling netty 4.1.96 jars — a 4.2.x jump
would risk a
LinkageError.Documented residuals (no drop-in fix for this runtime)
Java 21; the image ships Java 17. No Java-17 backport exists upstream. The
vulnerable path is Derby's LDAP authenticator, which OM's embedded metastore
never uses.
hadoop-client-runtime/spark-coreuber-jars as ~2,600 loose class files,not a swappable standalone jar. "Fixed in 12.1.7" is a 3-major rewrite
(Jakarta EE) that Hadoop/Spark 3.5 can't run on. Clears on a future PySpark bump.
yet; already covered by the
--only-upgradeblock (no-op until Debian ships it).Type of change
How was this tested
Built the slim CI image locally (
ingestion/operators/docker/Dockerfile.ci) andverified in-image:
pyspark/jars/now haszookeeper-3.7.2.jar,netty-codec-http-4.1.135.Final.jar,and no
jackson-*-asljars;derby-10.14.2.0.jarintentionally retained.spacy/tests/**/requirements.txtis gone.python -c "import pyspark; from pyspark.sql import SparkSession"succeeds —confirming the netty swap doesn't break Spark.
Checklist
🤖 Generated with Claude Code
Greptile Summary
The PR centralizes PySpark dependency remediation in a shared image-build script.
Confidence Score: 5/5
The PR appears safe to merge.
No blocking failure remains.
Important Files Changed
Flowchart
%%{init: {'theme': 'neutral'}}%% flowchart LR D1[Airflow Dockerfile] --> S[patch_pyspark_jars.sh] D2[Airflow CI Dockerfile] --> S D3[Slim Dockerfile] --> S D4[Slim CI Dockerfile] --> S S --> P{PySpark installed?} P -->|No| K[Skip jar patch] P -->|Broken| F[Fail image build] P -->|Yes| J[Remove vulnerable bundled jars] J --> V[Download SHA-256-pinned replacements] S --> X[Remove spaCy scanner fixture]Reviews (6): Last reviewed commit: "fix: spacy cleanup" | Re-trigger Greptile