fix(security): remove unused vulnerable httpx2 dependency - #558
fix(security): remove unused vulnerable httpx2 dependency#558seonghobae wants to merge 3 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Advanced Run ID: 📒 Files selected for processing (3)
💤 Files with no reviewable changes (3)
Included review availability: Your plan provides up to 1 included review per hour; 0 remain after this review. 📝 WalkthroughWalkthrough개발 및 런타임 의존성에서 Changes의존성 정리
Priority: ⬆️ High Estimated code review effort: 1 (Trivial) | ~5 minutes Merge Risk: ⚪ Minimal · up to The dependency removal has no supported unresolved merge-blocking risk in the available evidence. 🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches 💡 1🛠️ Fix failing CI checks 💡
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@jules Please continue this Draft from the live head, preserving the two existing commits. Regenerate |
|
@coderabbitai review |
✅ Action performedReview finished.
|
|
@coderabbitai review Current-head scope for re-review: |
🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
target='21824f77e9ee4c26c42bb1f21f00eaa3ae21fb6d'
git rev-parse --verify "${target}^{commit}"
parent="$(git rev-parse "${target}^")"
printf '%s\n' '=== exact commit metadata ==='
git show -s --format='commit=%H%nparent=%P%nsubject=%s' "$target"
printf '%s\n' '=== exact dependency-removal diff ==='
git diff --no-ext-diff --unified=80 "$parent" "$target" -- \
requirements.txt pyproject.toml requirements-lock.txt
printf '%s\n' '=== lockfile header and package blocks ==='
sed -n '1,80p' requirements-lock.txt
rg -n -i -C 3 '^(httpx2|httpcore2|httpx|httpcore)==|#.*\b(httpx2|httpcore2)\b|\b(httpx2|httpcore2)\b' \
requirements-lock.txt requirements.txt pyproject.toml || true
printf '%s\n' '=== tracked references outside lock artifacts ==='
git grep -n -i -E '(^|[^[:alnum:]_])(httpx2|httpcore2)([^[:alnum:]_]|$)|from[[:space:]]+(httpx2|httpcore2)([[:space:].]|$)|import[[:space:]]+(httpx2|httpcore2)([[:space:],.]|$)' \
"$target" -- \
':!requirements-lock.txt' ':!*.lock' ':!*.egg-info/*' || true
printf '%s\n' '=== dependency declarations and common import names ==='
git grep -n -i -E '(^|[^[:alnum:]_])(httpx2|httpcore2)([^[:alnum:]_]|$)' \
"$target" -- \
requirements.txt pyproject.toml setup.py setup.cfg tox.ini noxfile.py Makefile Dockerfile docker-compose.yml \
'.github' 2>/dev/null || true
printf '%s\n' '=== direct packages and their lock attribution ==='
rg -n -A 12 -B 3 '^(httpx|httpcore|anyio|idna|typing-extensions)==' requirements-lock.txtLength of output: 38199 🏁 Script executed: #!/bin/bash
set -euo pipefail
printf '%s\n' '=== declared dependency inputs ==='
cat -n requirements.txt
printf '%s\n' '--- pyproject dependency sections ---'
rg -n -A 80 -B 5 '^\[project(\.optional-dependencies)?\]|^(dependencies|dev)[[:space:]]*=' pyproject.toml
printf '%s\n' '=== empty lockfile attribution blocks ==='
python - <<'PY'
from pathlib import Path
import re
lines = Path("requirements-lock.txt").read_text().splitlines()
starts = [i for i, line in enumerate(lines) if re.match(r'^[A-Za-z0-9][A-Za-z0-9_.-]*==', line)]
for pos, start in enumerate(starts):
end = starts[pos + 1] if pos + 1 < len(starts) else len(lines)
block = lines[start:end]
via = [line.strip() for line in block if line.strip().startswith("# via")]
attribution = [line.strip() for line in block if line.strip().startswith("# ")]
if via and not attribution:
print(f"{start + 1}: {block[0].rstrip(' \\')}")
PY
printf '%s\n' '=== exact tracked-file consumer scan ==='
git ls-tree -r --name-only 21824f77e9ee4c26c42bb1f21f00eaa3ae21fb6d \
| grep -E '\.(py|pyi|toml|txt|ini|cfg|yml|yaml|md|sh|json)$|(^|/)(Dockerfile|Makefile)$' \
| while IFS= read -r file; do
git show "21824f77e9ee4c26c42bb1f21f00eaa3ae21fb6d:${file}" \
| grep -n -i -E '(^|[^[:alnum:]_])(httpx2|httpcore2)([^[:alnum:]_]|$)|^[[:space:]]*(from|import)[[:space:]]+(httpx2|httpcore2)([[:space:].,]|$)' \
&& printf ' file=%s\n' "$file" || true
done
printf '%s\n' '=== dependency-install and pip-compile workflow references ==='
rg -n -i -C 3 'pip-compile|requirements-lock\.txt|require-hashes|requirements\.txt' \
.github . -g '!requirements-lock.txt' -g '!**/.git/**' 2>/dev/null | head -n 300Length of output: 6156 🏁 Script executed: #!/bin/bash
set -euo pipefail
target='21824f77e9ee4c26c42bb1f21f00eaa3ae21fb6d'
printf '%s\n' '=== empty lockfile attribution blocks ==='
python - <<'PY'
from pathlib import Path
import re
lines = Path("requirements-lock.txt").read_text().splitlines()
starts = [i for i, line in enumerate(lines) if re.match(r'^[A-Za-z0-9][A-Za-z0-9_.-]*==', line)]
for pos, start in enumerate(starts):
end = starts[pos + 1] if pos + 1 < len(starts) else len(lines)
block = lines[start:end]
has_via = any(line.strip().startswith("# via") for line in block)
attribution = [line.strip() for line in block if line.strip().startswith("# ")]
if has_via and not attribution:
package = block[0].rstrip().rstrip("\\").rstrip()
print(f"{start + 1}: {package}")
PY
printf '%s\n' '=== exact tracked-file consumer scan ==='
matches=0
while IFS= read -r file; do
if git show "${target}:${file}" |
grep -n -i -E '(^|[^[:alnum:]_])(httpx2|httpcore2)([^[:alnum:]_]|$)|^[[:space:]]*(from|import)[[:space:]]+(httpx2|httpcore2)([[:space:].,]|$)'; then
printf 'file=%s\n' "$file"
matches=1
fi
done < <(
git ls-tree -r --name-only "$target" |
grep -E '\.(py|pyi|toml|txt|ini|cfg|yml|yaml|md|sh|json)$|(^|/)(Dockerfile|Makefile)$' || true
)
printf 'consumer_match_found=%s\n' "$matches"
printf '%s\n' '=== truststore declarations and exact package block ==='
git grep -n -i -E '(^|[^[:alnum:]_-])truststore([^[:alnum:]_-]|$)' "$target" -- \
':!requirements-lock.txt' ':!*.lock' ':!*.egg-info/*' || true
sed -n '550,562p' requirements-lock.txtLength of output: 2584
I found no source, test, or tooling consumer of Finding — Regenerate the lockfile with the header command. This should remove the orphaned
|
|
@coderabbitai review Please review only the current exact head |
|
Tip For best results, initiate chat on the files or code changes. 🧩 Analysis chain🏁 Script executed: #!/bin/bash
set -euo pipefail
target='21824f77e9ee4c26c42bb1f21f00eaa3ae21fb6d'
git rev-parse --verify "${target}^{commit}" >/dev/null
parent="$(git rev-parse "${target}^")"
printf '%s\n' '=== exact commit ==='
git show -s --format='commit=%H%nparent=%P%nsubject=%s' "$target"
printf '%s\n' '=== exact three-file diff ==='
git diff --no-ext-diff --unified=40 "$parent" "$target" -- \
requirements.txt pyproject.toml requirements-lock.txt
printf '%s\n' '=== dependency declarations ==='
cat -n requirements.txt
printf '%s\n' '--- pyproject dependency sections ---'
rg -n -A 100 -B 4 '^\[project(\.optional-dependencies)?\]|^(dependencies|dev)[[:space:]]*=' pyproject.toml
printf '%s\n' '=== lockfile header and relevant blocks ==='
sed -n '1,70p' requirements-lock.txt
rg -n -A 18 -B 3 \
'^(httpx2|httpcore2|httpx|httpcore|anyio|idna|typing-extensions|truststore)==' \
requirements-lock.txt || true
printf '%s\n' '=== removed-package references in tracked files at exact head ==='
git grep -n -i -E \
'(^|[^[:alnum:]_])(httpx2|httpcore2)([^[:alnum:]_]|$)|^[[:space:]]*(from|import)[[:space:]]+(httpx2|httpcore2)([[:space:].,]|$)' \
"$target" || true
printf '%s\n' '=== lock attribution integrity ==='
python - <<'PY'
from pathlib import Path
import re
path = Path("requirements-lock.txt")
lines = path.read_text(encoding="utf-8").splitlines()
starts = [i for i, line in enumerate(lines)
if re.match(r'^[A-Za-z0-9][A-Za-z0-9_.-]*==', line)]
empty_via = []
for n, start in enumerate(starts):
end = starts[n + 1] if n + 1 < len(starts) else len(lines)
block = lines[start:end]
package = block[0].split("==", 1)[0]
has_via = any(line.strip() == "# via" for line in block)
sources = [line.strip()[3:] for line in block if line.strip().startswith("# ")]
if has_via and not sources:
empty_via.append((start + 1, package))
print("empty_via_blocks=", empty_via)
for pkg in ("httpx2", "httpcore2", "truststore"):
found = [(i + 1, line) for i, line in enumerate(lines)
if line.lower().startswith(pkg + "==")]
print(f"{pkg}_entries=", found)
PYLength of output: 28636
I found no tracked source, test, or tooling reference to
Finding — Regenerate I excluded the separately owned central CodeQL settlement failure from this review. You are interacting with an AI system. |
|
Fresh independent consumer evidence from #562 exact head |
Finding
Protected
main@47c6fd27de13b0da37a7db64697b869941909351still carries unusedhttpx2==2.5.0. Exact Trivy evidence from the same protected dependency contract reported CVE-2026-84382 (HIGH) plus CVE-2026-84378/84379/84380 (MEDIUM). Repository source/test search found nohttpx2consumer contract, so retaining and upgrading an unused network client is broader than removing it.Minimal causal repair
Current exact head:
21824f77e9ee4c26c42bb1f21f00eaa3ae21fb6d.httpx2fromrequirements.txtand thedevoptional dependencies inpyproject.toml;httpx2/httpcore2and their now-unreachable lock attribution fromrequirements-lock.txt;Fresh protected-base compare remains three dependency files only. #557 and security PR #562 must not duplicate or fork this dependency owner; consumers should adopt the immutable protected descendant after this lane is accepted.
Exact-head verification
On unchanged
21824f77e9ee4c26c42bb1f21f00eaa3ae21fb6d:34544999020: SUCCESS across the repository matrix;34544998906: SUCCESS, so the Trivy gate that established the vulnerable dependency RED is GREEN after removal;34544998881: SUCCESS;34544998878: SUCCESS;34544998904: FAILURE at the central settlement path, not a leaf finding. Python/actions compatibility consumers finished failure at 00:30:36Z / 00:30:32Z, while the same generation's authoritative dispatch job did not start until 00:38:05Z and then succeeded at 00:38:14Z. This is the existing producer/consumer ordering defect owned by.github; no leaf no-op commit, synthetic verdict, alternate scanner, or gate waiver is permitted.Acceptance
Keep Draft until the unchanged exact head has the required central CodeQL receipt settled successfully and a qualifying independent current-head formal review confirms that no real
httpx2consumer was omitted. The repository CI/Security/SAST/fuzz GREEN above is current-head evidence, not permission to bypass the remaining gates.If a real consumer is later found, do not preserve removal by force; redesign against a vendor-fixed released contract. No force push, destructive rebase, self-approval, bypass, gate weakening, scanner suppression, or predecessor-GREEN transfer.