Bump httpx2 to 2.12 to resolve four HTTP stack security advisories #34
No reviewers
Labels
No labels
bug
contribution welcome
duplicate
enhancement
good first issue
help wanted
invalid
question
upstream
No milestone
No assignees
3 participants
Notifications
Due date
No due date set.
Reference
marvin8/longwei!34
Loading…
Reference in a new issue
No description provided.
Delete branch "fix/issue-33-bump-httpx2-security"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The weekly pysentry audit reported 2 HIGH and 2 MEDIUM findings against the HTTP stack. This PR bumps the direct dependency
httpx2from~=2.3to~=2.12and adds an explicit floor for the transitivehttpcore2.Advisories resolved
wss://traffic sent plaintext through SOCKS proxiesNotes
Requires-Dist: httpcore2==2.12.0, verified from the published wheel metadata — so a correct install of httpx2 2.12.0 cannot pair with any other httpcore2, and downstream installs are protected by that pin alone. The deliberatehttpcore2>=2.12.0entry in[tool.uv] constraint-dependencies(0288996) remains as defence-in-depth: it enforces the floor for longwei's own builds and guards against a future httpx2 2.x release relaxing the pin. It is a uv-only setting and does not propagate to downstream resolvers — nor does it need to.pylock.tomlregenerated (resolved versions unchanged by the floor, so its diff is empty from0288996);Release-Notes.mdupdated — security fixes are user-facing.Verification
0288996CI run 596,6200129run 600, and subsequent heads: ruff, ty, interrogate, complexipy, pysentry (0 vulnerabilities; sources pinned to osv,pypi per6200129to stop the PyPA-fetch flake, #35), pytest on 3.11/3.12/3.13/3.14/3.14t, deptry, dependency_versions — all green, includinguv sync --lockedconsistency.Closes #33
WuMing
Found 5 issue(s). See inline comments below.
@ -10,3 +11,4 @@---Four security advisories were published against the httpx2 version longwei depends on. The most serious sends secure WebSocket traffic in plaintext through SOCKS proxies; the others allow memory-amplification denial of service from malicious servers, header injection in multipart uploads, and ambiguous HTTP framing that can enable request smuggling. longwei itself never uses SOCKS proxies, WebSockets, or raw multipart tuples, but any application fetching compressed responses through the old version was exposed to the memory-amplification issue.docs [MEDIUM]
This paragraph attributes all four advisories to httpx2 ("published against the httpx2 version longwei depends on"), but the advisory described in the very next sentence as "the most serious" — PYSEC-2026-3844 (httpcore2: wss:// plaintext through SOCKS proxies) — is an httpcore2 advisory, not an httpx2 one. A reader who cross-checks the PYSEC database will find the note inaccurate. Fix: say the advisories were published against "httpx2 and its httpcore2 dependency" (or against "the HTTP stack") rather than against httpx2 alone.
docs [LOW]
The absolute claim that "longwei itself never uses SOCKS proxies, WebSockets, or raw multipart tuples" is not substantiated anywhere in the PR description or diff, and it is materially reassuring to users of a security note. If longwei ever passes open file objects/tuples to httpx2 for multipart uploads (plausible for ActivityPub media uploads), this statement is wrong. Fix: verify the claim against the codebase and cite it, or soften to describe the actual exposure (e.g. "longwei's supported configuration does not use SOCKS proxies or WebSockets").
@ -12,1 +13,4 @@Four security advisories were published against the httpx2 version longwei depends on. The most serious sends secure WebSocket traffic in plaintext through SOCKS proxies; the others allow memory-amplification denial of service from malicious servers, header injection in multipart uploads, and ambiguous HTTP framing that can enable request smuggling. longwei itself never uses SOCKS proxies, WebSockets, or raw multipart tuples, but any application fetching compressed responses through the old version was exposed to the memory-amplification issue.The pinned dependency is now httpx2 2.12, which also pulls in the patched httpcore2 — all four advisories are resolved with no API changes to longwei, and the full test suite passes unchanged.docs [MEDIUM]
"which also pulls in the patched httpcore2" overstates the guarantee. Per the PR notes, httpx2 2.12.0 declares httpcore2 with no version floor, so upgrading httpx2 does not itself force the patched httpcore2 — the guarantee comes from the committed uv.lock/pylock.toml. Users who upgrade with the install command below (pip install longwei) resolve httpcore2 separately and could get an unpatched version. Fix: attribute the fix to the lockfile (e.g. "the committed lockfile pins httpcore2 2.12.0, which resolves the httpcore2 advisory") and mention the constraint-dependency fallback if the audit flags httpcore2 again.
@ -25,3 +25,3 @@requires-python = ">=3.11"dependencies = ["httpx2[http2]~=2.3","httpx2[http2]~=2.12",config [HIGH]
Only the direct dependency is bumped, but one of the two HIGH advisories (PYSEC-2026-3844) is against the transitive package httpcore2. The PR notes concede that httpx2 2.12.0's metadata declares httpcore2 with no version floor, so nothing in pyproject.toml prevents the resolver from re-selecting a vulnerable httpcore2 (2.3.0) on the next
uv lock/ in a fresh environment — the entire mitigation rests on the committed lock, and this diff shows no uv.lock hunks at all, so it is not even clear the guarantee the PR relies on was regenerated. Add an explicit floor, e.g.[tool.uv] constraint-dependencies = ["httpcore2>=2.12.0"](or declare httpcore2 as a direct dependency), and regenerate both uv.lock and pylock.toml so the patched HTTP stack is enforced by declared constraints rather than by lockfile state alone.security [MEDIUM]
A06: The direct dependency
httpx2[http2]~=2.12does not enforce a secure floor for the transitivehttpcore2dependency. As noted, httpx2 2.12.0 metadata declares httpcore2 without a version floor, so non-lock installs from pyproject may still select the vulnerable httpcore2 2.3.0 affected by PYSEC-2026-3844. Add an explicit constraint such ashttpcore2>=2.12to ensure the fixed version is required.✅ Fixed — all five findings addressed in commit
0288996pyproject.toml✅ Added
"httpcore2>=2.12.0", # PYSEC-2026-3844to[tool.uv] constraint-dependencies(alphabetically sorted, house convention).uv.lockandpylock.tomlregenerated in the same commit so the floor is enforced by declared constraints, not lockfile state alone.pyproject.toml✅ Same finding as 3042 (identical wuming:sha256) — covered by the same constraint in commit
0288996.Release-Notes.md✅ Reworded in commit
0288996: the notes now attribute the guarantee to the explicithttpcore2>=2.12floor plus the committed lockfiles, and tell downstreampip install longweiusers that their resolver picks httpx2/httpcore2 independently (advise 2.12+ on both).Release-Notes.md✅ Reworded in commit
0288996: "published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency".Release-Notes.md✅ Softened and grounded in commit
0288996: the claim is now scoped to what a search of the library source confirms — no SOCKS proxy, WebSocket, or multipart file-tuple usage — with the decompression-amplification exposure called out separately.WuMing
Found 4 issue(s). See inline comments below.
@ -5,11 +5,18 @@ visibility: publiclongwei 2.1.2- **Security:** mkdocs-material now pinned to version 9.7.7 or higher to address GHSA-xvg9-69gf-fjrf- **Security:** httpx2 pinned to 2.12+ with an explicit httpcore2>=2.12 floor, clearing four advisories in the HTTP stack (PYSEC-2026-3844/3846/3848/3849)docs [HIGH]
This release note claims an "explicit httpcore2>=2.12 floor", but the PR description explicitly states that no
constraint-dependenciesentry was needed because httpx2 2.12.0 pulls httpcore2 up on its own, and no dependency-manifest change (e.g. pyproject.toml) appears in this diff. Publishing a security note that asserts a dependency floor longwei does not actually enforce is misleading. Either add the floor to the dependency manifest so the statement is true, or reword to describe what actually protects users (the committeduv.lockresolving httpcore2 to 2.12.0) and drop the reference to an explicit floor.@ -12,1 +13,4 @@Four security advisories were published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency. The most serious sends secure WebSocket traffic in plaintext through SOCKS proxies; the others allow memory-amplification denial of service from malicious servers, header injection in multipart uploads, and ambiguous HTTP framing that can enable request smuggling. longwei's own code has no SOCKS proxy, WebSocket, or multipart file-tuple usage (a search of the library source confirms this), but any application fetching compressed responses through the old httpx2 was exposed to the memory-amplification issue.longwei now pins httpx2 ~=2.12 and enforces an explicit httpcore2>=2.12 floor, and the committed lockfiles resolve both to the patched 2.12.0 releases. If you install longwei into your own project, your resolver picks httpx2 and httpcore2 from PyPI independently — make sure your environment resolves httpx2 2.12+ and httpcore2 2.12+. No API changes to longwei, and the full test suite passes unchanged.docs [HIGH]
Same unsupported claim repeated in the body: "enforces an explicit httpcore2>=2.12 floor". Per the PR description, httpx2 2.12.0 declares httpcore2 without a version floor, so nothing in this change enforces httpcore2>=2.12 for downstream installers. The paragraph then correctly tells readers their resolver picks httpcore2 independently — which contradicts the "enforces" wording. Rewrite to say longwei pins httpx2 ~=2.12 and that the lockfiles resolve httpcore2 to 2.12.0, while downstream users must ensure their own resolver does the same.
@ -25,3 +25,3 @@requires-python = ">=3.11"dependencies = ["httpx2[http2]~=2.3","httpx2[http2]~=2.12",config [MEDIUM]
The PR notes rely on the committed uv.lock as the actual guarantee that httpcore2 stays at the patched version ("httpx2 2.12.0 metadata declares httpcore2 without a version floor"), but the diff only contains the
--- a/uv.lockheader with no pin changes shown. If uv.lock was not regenerated alongside pyproject.toml,uv sync --locked/ CI installs will fail on the unsatisfiedhttpx2[http2]~=2.12requirement, or the audited environment may still resolve the vulnerable 2.3.0. Regenerate and commit uv.lock in this change and confirm it pins httpx2 2.12.0 and httpcore2 2.12.0.@ -51,6 +51,7 @@ dev = [constraint-dependencies = ["click>=8.3.3", # PYSEC-2026-2132"h2>=4.4.1", # GHSA-6hr6-w5qg-qmwg"httpcore2>=2.12.0", # PYSEC-2026-3844config [LOW]
The PR description explicitly states "no
constraint-dependenciesentry was needed" because httpx2 2.12.0 pulls httpcore2 2.12.0 in transitively, yet this line adds exactly such a constraint. Pick one story: either the constraint is required (httpx2's metadata declares httpcore2 with no version floor, as the notes say) and the PR text should be corrected to say the floor was added deliberately as a durable guard, or it is redundant and should be dropped so the lockfile remains the single source of truth. Leaving the code and the description in disagreement makes the security guarantee ambiguous.Wave 2 — 2 actioned, 1 declined with evidence, 1 resolved by PR-body update
pyproject.toml✅ PR description corrected — it now states the
httpcore2>=2.12.0floor was added deliberately in0288996as a durable guard (httpx2's metadata has no version floor on httpcore2), no longer claiming "no constraint needed".pyproject.toml🔴 Declined with evidence — the premise no longer holds on the current head. Commit
0288996does modifyuv.lock; the hunk is:near the top of the file, which may be why a truncated diff view showed only the header.
uv sync --lockedsucceeded in CI run 596 on that commit, proving lock/pyproject consistency, and the lock resolves httpcore2 to 2.12.0.pylock.tomlwas also regenerated (uv export) — its output was byte-identical because the floor changes no resolved versions and the pylock format carries no constraint metadata, hence no diff hunk.Release-Notes.md✅ Reworded in commit
aec2334— the sentence now scopes the floor to longwei's own build ("enforced by an explicit httpcore2>=2.12 constraint in the project's dependency configuration and recorded in the committed lockfiles") and leaves downstream guidance standalone.Release-Notes.md✅ Same paragraph as 3054 — fixed by the same reword in
aec2334. The floor does exist inpyproject.tomlas of0288996; the note no longer describes it as something downstream installs inherit.WuMing
Found 3 issue(s). See inline comments below.
@ -5,11 +5,18 @@ visibility: publiclongwei 2.1.2- **Security:** mkdocs-material now pinned to version 9.7.7 or higher to address GHSA-xvg9-69gf-fjrf- **Security:** httpx2 pinned to 2.12+ with an explicit httpcore2>=2.12 floor, clearing four advisories in the HTTP stack (PYSEC-2026-3844/3846/3848/3849)docs [LOW]
"pinned to 2.12+" is inaccurate: the dependency is declared as
httpx2~=2.12, which is a compatible-release floor (>=2.12, <3.0), not a pin — future 2.x releases are still allowed. The same wording recurs at line 16. Also, the constraint ishttpcore2>=2.12.0; writinghttpcore2>=2.12invites confusion about whether 2.12.0 is actually required. Suggest: "httpx2 requirement raised to ~=2.12 with an explicit httpcore2>=2.12.0 floor..."@ -10,3 +11,4 @@---Four security advisories were published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency. The most serious sends secure WebSocket traffic in plaintext through SOCKS proxies; the others allow memory-amplification denial of service from malicious servers, header injection in multipart uploads, and ambiguous HTTP framing that can enable request smuggling. longwei's own code has no SOCKS proxy, WebSocket, or multipart file-tuple usage (a search of the library source confirms this), but any application fetching compressed responses through the old httpx2 was exposed to the memory-amplification issue.docs [LOW]
The exposure assessment enumerates only three of the four advisories: it states longwei has no SOCKS, WebSocket, or multipart file-tuple usage, but says nothing about the request-smuggling advisory (PYSEC-2026-3849) — e.g. whether longwei ever sets Transfer-Encoding or relies on httpx2's auto-generated Content-Length. Complete the sentence (or state that this advisory cannot be triggered by longwei) so readers can tell whether they are affected by all four findings.
@ -12,1 +13,4 @@Four security advisories were published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency. The most serious sends secure WebSocket traffic in plaintext through SOCKS proxies; the others allow memory-amplification denial of service from malicious servers, header injection in multipart uploads, and ambiguous HTTP framing that can enable request smuggling. longwei's own code has no SOCKS proxy, WebSocket, or multipart file-tuple usage (a search of the library source confirms this), but any application fetching compressed responses through the old httpx2 was exposed to the memory-amplification issue.longwei pins httpx2 ~=2.12, and longwei's own build resolves httpcore2 to the patched 2.12.0 — enforced by an explicit httpcore2>=2.12 constraint in the project's dependency configuration and recorded in the committed lockfiles. If you install longwei into your own project, your resolver picks httpx2 and httpcore2 from PyPI independently — make sure your environment resolves httpx2 2.12+ and httpcore2 2.12+. No API changes to longwei, and the full test suite passes unchanged.docs [MEDIUM]
"recorded in the committed lockfiles" is misleading. The floor lives in
pyproject.tomlunder[tool.uv] constraint-dependencies— that is the file that enforces it — while of the two lockfiles onlyuv.lockchanged; thepylock.tomldiff in this PR is empty (as noted in the PR body, the floor changed no resolved versions). Naming an unspecified "project's dependency configuration" also makes the claim impossible for a reader to verify. Suggest: "enforced by an explicithttpcore2>=2.12.0entry in[tool.uv] constraint-dependenciesinpyproject.tomland reflected inuv.lock".Wave 3 — all three actioned in commit
3da2737Release-Notes.md✅ Bullet and line-16 wording corrected: "httpx2 requirement raised to ~=2.12 (>=2.12, <3.0)" and the constraint written exactly as
httpcore2>=2.12.0.Release-Notes.md✅ Adopted your phrasing: "enforced by an explicit
httpcore2>=2.12.0entry in[tool.uv] constraint-dependenciesinpyproject.tomland reflected inuv.lock" — the enforcing file is now named, and "lockfiles" plural is gone.Release-Notes.md✅ Exposure assessment completed: the note now states longwei sets no
Transfer-EncodingorContent-Lengthheaders itself, so the request-framing advisory (PYSEC-2026-3849) cannot be triggered through longwei's API. Grounded the same way as the other exposure claims — a search ofsrc/finds no such header handling.WuMing
Found 2 issue(s). See inline comments below.
@ -10,3 +11,4 @@---Four security advisories were published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency. The most serious sends secure WebSocket traffic in plaintext through SOCKS proxies; the others allow memory-amplification denial of service from malicious servers, header injection in multipart uploads, and ambiguous HTTP framing that can enable request smuggling. longwei's own code has no SOCKS proxy, WebSocket, or multipart file-tuple usage (a search of the library source confirms this), nor does it set Transfer-Encoding or Content-Length headers itself, so the request-framing advisory cannot be triggered through longwei's API — but any application fetching compressed responses through the old httpx2 was exposed to the memory-amplification issue.docs [LOW]
Clarity: this is a single dense run-on paragraph covering four advisories, their impacts, longwei's exposure analysis, and a consumer-impact caveat, and it never names the PYSEC IDs that the summary bullet on line 8 lists. Readers cannot map each described impact to its advisory or tell which findings actually affect them. Suggest reformatting as a short bulleted list, one advisory per bullet with its PYSEC ID and scope (e.g. "affects longwei users" vs. "not reachable via longwei's API"), and splitting the exposure/verification claim into its own sentence.
@ -12,1 +13,4 @@Four security advisories were published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency. The most serious sends secure WebSocket traffic in plaintext through SOCKS proxies; the others allow memory-amplification denial of service from malicious servers, header injection in multipart uploads, and ambiguous HTTP framing that can enable request smuggling. longwei's own code has no SOCKS proxy, WebSocket, or multipart file-tuple usage (a search of the library source confirms this), nor does it set Transfer-Encoding or Content-Length headers itself, so the request-framing advisory cannot be triggered through longwei's API — but any application fetching compressed responses through the old httpx2 was exposed to the memory-amplification issue.longwei raises its httpx2 requirement to ~=2.12 (>=2.12, <3.0), and longwei's own build resolves httpcore2 to the patched 2.12.0 — enforced by an explicit `httpcore2>=2.12.0` entry in `[tool.uv] constraint-dependencies` in `pyproject.toml` and reflected in `uv.lock`. If you install longwei into your own project, your resolver picks httpx2 and httpcore2 from PyPI independently — make sure your environment resolves httpx2 2.12+ and httpcore2 2.12+. No API changes to longwei, and the full test suite passes unchanged.docs [MEDIUM]
Accuracy: the note states longwei's build "resolves httpcore2 to the patched 2.12.0", but the mechanism described is a floor (
httpcore2>=2.12.0), so a resolver will pick the newest 2.x that satisfies it (e.g. 2.13.x), not necessarily 2.12.0. Stating an exact resolved version in permanent release notes is inaccurate today and will go stale as soon as a newer httpcore2 ships. Reword to reflect the constraint, e.g. "longwei's own build resolves httpcore2 to at least 2.12.0", and keep the exact-version detail in uv.lock where it is verifiable.Wave 4 — both actioned in commit
7f8ea93Release-Notes.md✅ Reworded exactly as suggested: "longwei's own build resolves httpcore2 to at least 2.12.0" — the exact-version detail now lives only in
uv.lockwhere it is verifiable.Release-Notes.md✅ Reformatted as one bullet per advisory with its PYSEC ID, severity, and explicit reachability scope ("not reachable through longwei's API" vs "affects longwei users"), with the exposure method (source search) split into its own sentence.
WuMing
Found 5 issue(s). See inline comments below.
@ -10,3 +11,4 @@---Four security advisories were published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency:docs [LOW]
This new advisory write-up is inserted between the longwei 2.1.2 changelog entry (which ends at the hashtag line 10) and the standing 'Install / upgrade:' boilerplate at line 27, and it carries no heading of its own. Rendered, it reads as an unlabelled block floating between the release entry and the installation instructions. Consider moving it inside the release entry (before line 10) or giving it an explicit heading (e.g. '### Security detail') so readers can tell which release it documents.
@ -13,0 +15,4 @@- **PYSEC-2026-3844** (httpcore2, HIGH): secure `wss://` WebSocket traffic sent in plaintext through SOCKS proxies — not reachable through longwei's API (no proxy or WebSocket usage).- **PYSEC-2026-3846** (httpx2, HIGH): decompression amplification causing memory exhaustion — affects longwei users fetching compressed responses.- **PYSEC-2026-3848** (httpx2, MEDIUM): multipart part-header injection via the `files=` tuple API — not reachable through longwei's API (no multipart file-tuple usage).docs [MEDIUM]
The non-reachability claim is narrower than the advisory it describes. PYSEC-2026-3848 concerns multipart part headers built from caller-supplied Content-Type/headers, and httpx2's
files=parameter also accepts a dict of file-like objects (and raw body content can be multipart too), so ruling out only 'file-tuple usage' does not by itself establish non-reachability. Either widen the evidence (e.g. 'longwei performs no multipart uploads at all, and never passes caller-controlled part headers') or drop the reachability claim, so the note cannot be read as a guarantee that has not been verified.@ -13,0 +16,4 @@- **PYSEC-2026-3844** (httpcore2, HIGH): secure `wss://` WebSocket traffic sent in plaintext through SOCKS proxies — not reachable through longwei's API (no proxy or WebSocket usage).- **PYSEC-2026-3846** (httpx2, HIGH): decompression amplification causing memory exhaustion — affects longwei users fetching compressed responses.- **PYSEC-2026-3848** (httpx2, MEDIUM): multipart part-header injection via the `files=` tuple API — not reachable through longwei's API (no multipart file-tuple usage).- **PYSEC-2026-3849** (httpx2, MEDIUM): conflicting Content-Length/Transfer-Encoding framing enabling request smuggling — not reachable through longwei's API (it sets neither header itself).docs [LOW]
The parenthetical is ambiguous: the pronoun 'it' has no clear antecedent in this sentence (longwei? httpx2?). Since the reachability argument is the load-bearing part of the claim, name the subject explicitly, e.g. 'longwei sets neither Content-Length nor Transfer-Encoding itself'.
@ -13,0 +18,4 @@- **PYSEC-2026-3848** (httpx2, MEDIUM): multipart part-header injection via the `files=` tuple API — not reachable through longwei's API (no multipart file-tuple usage).- **PYSEC-2026-3849** (httpx2, MEDIUM): conflicting Content-Length/Transfer-Encoding framing enabling request smuggling — not reachable through longwei's API (it sets neither header itself).The exposure claims reflect a search of the library source. Applications fetching compressed responses through the old httpx2 were exposed to PYSEC-2026-3846.docs [LOW]
'The exposure claims reflect a search of the library source' is too vague to be verifiable for a security note — it does not say what was searched or how. Make the method reproducible (e.g. name the symbols/patterns searched: proxy/trust_env, WebSocket, files=/multipart, Transfer-Encoding. Also note this sentence largely restates line 17; consider merging the two to avoid repeating the same reachability statement.
@ -13,0 +20,4 @@The exposure claims reflect a search of the library source. Applications fetching compressed responses through the old httpx2 were exposed to PYSEC-2026-3846.longwei raises its httpx2 requirement to ~=2.12 (>=2.12, <3.0), and longwei's own build resolves httpcore2 to at least 2.12.0 — enforced by an explicit `httpcore2>=2.12.0` entry in `[tool.uv] constraint-dependencies` in `pyproject.toml` and reflected in `uv.lock`. If you install longwei into your own project, your resolver picks httpx2 and httpcore2 from PyPI independently — make sure your environment resolves httpx2 2.12+ and httpcore2 2.12+. No API changes to longwei, and the full test suite passes unchanged.docs [MEDIUM]
The consumer guidance here is inaccurate on one point: an installing project does not resolve httpx2 'independently' of longwei, because longwei's own package metadata now declares
httpx2~=2.12, which every resolver (pip, uv, poetry) must satisfy. Only httpcore2 is unconstrained downstream, since[tool.uv] constraint-dependenciesis a uv-local setting that applies to longwei's own environment and is never exported to consumers. As written, readers may think the declared floor protects their installs, and may waste effort pinning httpx2 while missing that httpcore2 is the real risk. Suggested fix: state that httpx2 2.12+ is guaranteed by longwei's declared requirement for all installers, that thehttpcore2>=2.12.0constraint applies only to longwei's own uv environment, and that projects installing longwei that resolve dependencies with other tools should pinhttpcore2>=2.12.0themselves.WuMing
Found 6 issue(s). See inline comments below.
@ -5,11 +5,25 @@ visibility: publiclongwei 2.1.2- **Security:** mkdocs-material now pinned to version 9.7.7 or higher to address GHSA-xvg9-69gf-fjrf- **Security:** httpx2 requirement raised to ~=2.12 with an explicit httpcore2>=2.12.0 floor, clearing four advisories in the HTTP stack (PYSEC-2026-3844/3846/3848/3849)docs [LOW]
The slash-joined advisory list "PYSEC-2026-3844/3846/3848/3849" is not a valid identifier and is hard to search or copy; list the full IDs (as done in lines 16–19) or link them. Also wrap the constraint in backticks for consistency with the code formatting used elsewhere in these notes:
httpcore2>=2.12.0.@ -10,3 +11,4 @@---Four security advisories were published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency:docs [LOW]
A new prose section is inserted after the entry's hashtag line (line 10) and horizontal rule (line 12) without a heading, so the release entry appears to end before this text begins and the new block reads as orphaned. Add a heading (e.g.
## Security advisories addressed in this release) and move the block above the#Python #PyPI #ActivityPub #OpenSourcetag line so the hashtags remain the last line of the entry.@ -13,0 +14,4 @@Four security advisories were published against the HTTP stack longwei depends on — three in httpx2 and one in its httpcore2 dependency:- **PYSEC-2026-3844** (httpcore2, HIGH): secure `wss://` WebSocket traffic sent in plaintext through SOCKS proxies — not reachable through longwei's API (no proxy or WebSocket usage).- **PYSEC-2026-3846** (httpx2, HIGH): decompression amplification causing memory exhaustion — affects longwei users fetching compressed responses.docs [LOW]
This bullet broadens the advisory scope: PYSEC-2026-3846 concerns decompression amplification on streaming responses, but the note says it "affects longwei users fetching compressed responses" without the streaming qualifier. Either scope the statement to streaming responses explicitly, or state plainly that any compressed-response fetch with httpx2 <2.12 was affected, so users can judge whether they are impacted. The tense also shifts between bullets ("affects") and line 21 ("were exposed") — align on past tense for fixed issues.
@ -13,0 +16,4 @@- **PYSEC-2026-3844** (httpcore2, HIGH): secure `wss://` WebSocket traffic sent in plaintext through SOCKS proxies — not reachable through longwei's API (no proxy or WebSocket usage).- **PYSEC-2026-3846** (httpx2, HIGH): decompression amplification causing memory exhaustion — affects longwei users fetching compressed responses.- **PYSEC-2026-3848** (httpx2, MEDIUM): multipart part-header injection via the `files=` tuple API — not reachable through longwei's API (no multipart file-tuple usage).- **PYSEC-2026-3849** (httpx2, MEDIUM): conflicting Content-Length/Transfer-Encoding framing enabling request smuggling — not reachable through longwei's API (it sets neither header itself).docs [LOW]
The pronoun "it" is ambiguous — it reads as though it refers to httpx2, but httpx2 is exactly what auto-generates Content-Length (the root of this advisory). A reader could therefore take the sentence as contradicting itself. Reword to name the subject explicitly, e.g. "…not reachable through longwei's API, since longwei sets neither header itself."
@ -13,0 +18,4 @@- **PYSEC-2026-3848** (httpx2, MEDIUM): multipart part-header injection via the `files=` tuple API — not reachable through longwei's API (no multipart file-tuple usage).- **PYSEC-2026-3849** (httpx2, MEDIUM): conflicting Content-Length/Transfer-Encoding framing enabling request smuggling — not reachable through longwei's API (it sets neither header itself).The exposure claims reflect a search of the library source. Applications fetching compressed responses through the old httpx2 were exposed to PYSEC-2026-3846.docs [MEDIUM]
This is process/meta commentary about how the exposure assessment was performed ("a search of the library source"), which belongs in the PR description or a security advisory, not in user-facing release notes. "The exposure claims" is also self-referential and vague about what is being claimed. Recommend deleting the first sentence and keeping only the user-relevant impact statement (e.g. "Applications that fetched compressed responses with httpx2 <2.12 were exposed to PYSEC-2026-3846."), and noting the scope (streaming responses) consistently with line 17.
@ -13,0 +20,4 @@The exposure claims reflect a search of the library source. Applications fetching compressed responses through the old httpx2 were exposed to PYSEC-2026-3846.longwei raises its httpx2 requirement to ~=2.12 (>=2.12, <3.0), and longwei's own build resolves httpcore2 to at least 2.12.0 — enforced by an explicit `httpcore2>=2.12.0` entry in `[tool.uv] constraint-dependencies` in `pyproject.toml` and reflected in `uv.lock`. If you install longwei into your own project, your resolver picks httpx2 and httpcore2 from PyPI independently — make sure your environment resolves httpx2 2.12+ and httpcore2 2.12+. No API changes to longwei, and the full test suite passes unchanged.docs [MEDIUM]
The downstream guidance is misleading for httpx2. longwei declares httpx2 as a direct dependency with
~=2.12, so any environment that installs this version of longwei is already forced to resolve httpx2 >=2.12,<3.0 — users cannot get an unpatched httpx2 from a correct install, and the two packages are not chosen "independently" in the same sense. Only httpcore2 lacks a floor in httpx2 2.12's metadata, so only httpcore2 needs a user-side or downstream constraint. Also,uv.lockis a lockfile that only matters for longwei's own development/CI, not for consumers, so mentioning it here can confuse readers. Suggest rewording to something like: "longwei's own environment is pinned via an explicithttpcore2>=2.12.0constraint in[tool.uv] constraint-dependencies; because httpx2 2.12 does not declare a httpcore2 floor, consumers whose projects resolve httpcore2 independently should ensure their own environment resolves httpcore2 2.12+." Consider also splitting this long single block into two short paragraphs.WuMing
Found 1 issue(s). See inline comments below.
@ -5,3 +5,3 @@longwei 2.1.2- **Security:** mkdocs-material now pinned to version 9.7.7 or higher to address GHSA-xvg9-69gf-fjrf- **Security:** httpx2 requirement raised to ~=2.12 with an explicit httpcore2>=2.12.0 floor, clearing four advisories in the HTTP stack (PYSEC-2026-3844/3846/3848/3849)docs [MEDIUM]
This line replaces the pre-existing security bullet for the mkdocs-material pin (GHSA-xvg9-69gf-fjrf) rather than being added alongside it, so the 2.1.2 entry now silently drops a previously documented security fix — readers of the release notes no longer learn that mkdocs-material is pinned to >=9.7.7. Restore the mkdocs-material bullet as its own list item and add the httpx2/httpcore2 bullet as a second item, so both security changes remain documented.
Release-Notes.md🔴 Declined — deliberate maintainer decision. The mkdocs-material pin (GHSA-xvg9-69gf-fjrf) shipped in the already-released 2.1.2 (commit
b8b2d0fonmain, before the 2.1.1 → 2.1.2 version bump), so its bullet is stale content for this pending announcement rather than a dropped fix. The removal inb1fe70eis intentional; the constraint itself remains in[tool.uv] constraint-dependencies.Waves 284/285 — maintainer triage: 2 dismissed with evidence, 9 noted but not actioned this release
Dismissed — downstream httpcore2 exposure is structurally impossible
#3073 · #3081
🔴 The premise no longer holds: the maintainer reviewed the httpx2 2.12 source and confirmed it requires httpcore2 of the same version. Verified independently from the published httpx2 2.12.0 wheel metadata:
That is an exact pin — a correct install of httpx2 2.12.0 cannot pair with any other httpcore2, so there is no downstream httpcore2 exposure for the guidance to address, and no resolver freedom for users to check. The release-notes text stays as the maintainer wrote it; the committed
httpcore2>=2.12.0constraint remains purely as defence-in-depth.Not actioned this release — maintainer has reviewed the list and is shipping the notes as-is
files=dict-of-file-objects path is a fair observation for a future pass.None of these block the release; the maintainer has seen the full list and chosen to keep this announcement's wording for 2.1.x, folding the rest into a future docs pass.
WuMing
Found 4 issue(s). See inline comments below.
@ -5,3 +5,3 @@longwei 2.1.2- **Security:** mkdocs-material now pinned to version 9.7.7 or higher to address GHSA-xvg9-69gf-fjrf- **Security:** httpx2 requirement raised to ~=2.12 with an explicit httpcore2>=2.12.0 floor, clearing four advisories in the HTTP stack (PYSEC-2026-3844/3846/3848/3849)docs [MEDIUM]
The summary bullet calls the httpcore2 floor part of the "requirement", but the floor lives only in longwei's dev-only
[tool.uv] constraint-dependenciesand is not part of the publishedhttpx2~=2.12requirement. Reword to distinguish the published requirement (httpx2~=2.12) from the build-time/dev constraint that forces httpcore2>=2.12.0, so readers do not assume the floor is enforced during their own install.@ -13,0 +17,4 @@- **PYSEC-2026-3848** (httpx2, MEDIUM): multipart part-header injection via the `files=` tuple API — not reachable through longwei's API (no multipart file-tuple usage).- **PYSEC-2026-3849** (httpx2, MEDIUM): conflicting Content-Length/Transfer-Encoding framing enabling request smuggling — not reachable through longwei's API (it sets neither header itself).The exposure claims reflect a search of the library source. Applications fetching compressed responses through the old httpx2 were exposed to PYSEC-2026-3846.docs [LOW]
"The exposure claims reflect a search of the library source" is too vague to support the four reachability verdicts above it: it names no revision/tag, no tooling, and no date. Add the specific revision searched and how it was searched (e.g. "grep of longwei @ <commit/ref> for
proxy=,files=,Transfer-Encoding"), or drop the sentence, so the "not reachable" claims are verifiable.@ -13,0 +19,4 @@The exposure claims reflect a search of the library source. Applications fetching compressed responses through the old httpx2 were exposed to PYSEC-2026-3846.longwei raises its httpx2 requirement to ~=2.12 (>=2.12, <3.0), and longwei's own build resolves httpcore2 to at least 2.12.0 — enforced by an explicit `httpcore2>=2.12.0` entry in `[tool.uv] constraint-dependencies` in `pyproject.toml` and reflected in `uv.lock`. Installing longwei into your own project resolves both for you: resolvers must satisfy longwei's declared `httpx2~=2.12` requirement, and httpx2 pins its matching httpcore2 exactly (`httpcore2==2.12.0`), so no manual version checks are needed. No API changes to longwei, and the full test suite passes unchanged.docs [CRITICAL]
Factually wrong and contradicts this PR's own rationale. The PR notes that httpx2 2.12.0 declares httpcore2 with no version floor, so the patched httpcore2 is only guaranteed by the declared constraint. Stating that "httpx2 pins its matching httpcore2 exactly (
httpcore2==2.12.0)" tells users the transitive dependency is safe regardless of the floor, which is not true. Rewrite to say httpx2 does not narrow httpcore2 and that the floor is what guarantees >=2.12.0 (and only for builds that apply longwei's constraints).docs [HIGH]
[tool.uv] constraint-dependenciesis a uv-only setting in the project's own pyproject.toml; it is not part of the published package metadata and is ignored by pip/Poetry/other resolvers. So the httpcore2 floor does not propagate to users installing longwei, and—since httpx2's metadata has no floor—a downstream resolve can still pick an unpatched httpcore2. The sentences "Installing longwei into your own project resolves both for you ... so no manual version checks are needed" therefore overstate the protection. Either add the floor to the published dependency metadata (e.g. a realhttpcore2>=2.12.0requirement) or reword to state clearly that consumers using non-uv resolvers may need to pin httpcore2 themselves.Wave 287 — CRITICAL/HIGH dismissed with artifact evidence; source of the confusion (our PR body) corrected
The premise shared by both high-severity findings — "httpx2 2.12.0 declares httpcore2 with no version floor" — is false. It was inherited from this PR's own description, which has now been corrected. The published httpx2 2.12.0 wheel metadata states:
That is an exact pin, enforced by every resolver (pip, uv, poetry) from the wheel's METADATA — not a uv.lock rendering artifact. A correct install of httpx2 2.12.0 cannot pair with any other httpcore2. (The uv.lock entry shows no specifier because uv bakes exact pins into the resolved entry; the wheel is the authoritative artifact for what downstream resolvers enforce.)
Release-Notes.md#3094🔴 Declined — the sentence "httpx2 pins its matching httpcore2 exactly (
httpcore2==2.12.0)" is factually correct per the wheel metadata above. The "contradiction" was with the PR body's stale note, which is the text that was wrong; it has been rewritten to state the exact pin and reframe the[tool.uv]floor as defence-in-depth for longwei's own builds.Release-Notes.md#3095🔴 Declined — the finding's true premise (constraint-dependencies is uv-only and does not propagate) is acknowledged and now stated explicitly in the PR body. But its conclusion does not follow: downstream protection does not come from the floor, it comes from httpx2's own
==2.12.0pin, which pip/Poetry enforce. "No manual version checks are needed" is therefore accurate — non-uv resolvers cannot pick an unpatched httpcore2 alongside httpx2 2.12.0.Release-Notes.md#3096🟡 Noted for the maintainer — the bullet's "with an explicit httpcore2>=2.12.0 floor" phrasing sits next to the published-requirement wording, and distinguishing build-time constraint from published requirement is a fair point. Left as-is pending the maintainer's call (the notes have been through their review).
Release-Notes.md#3097🔴 Repeat of the search-method cluster already dispositioned in the waves-284/285 triage (consolidated reply) — same substance, recomputed hash. Stays noted, not actioned this release.
Release-Notes.md✅ Actioned in commit
8b764f8— the bullet now reads "httpx2 requirement raised to ~=2.12 (which pins its matching httpcore2)", attributing the httpcore2 clearance to the upstream pin rather than the build-side constraint. The published requirement and the[tool.uv]defence-in-depth floor are no longer conflated in the bullet.WuMing
Found 3 issue(s). See inline comments below.
@ -5,3 +5,3 @@longwei 2.1.2- **Security:** mkdocs-material now pinned to version 9.7.7 or higher to address GHSA-xvg9-69gf-fjrf- **Security:** httpx2 requirement raised to ~=2.12 (which pins its matching httpcore2), clearing four advisories in the HTTP stack (PYSEC-2026-3844/3846/3848/3849)docs [MEDIUM]
This bullet replaces the existing changelog entry rather than adding to it: the line "- Security: mkdocs-material now pinned to version 9.7.7 or higher to address GHSA-xvg9-69gf-fjrf" is deleted in this diff. If that mkdocs-material fix is still part of the 2.1.2 release, the changelog now loses a security item that users were previously told about. Fix: keep the mkdocs-material bullet and add the httpx2 bullet as a separate line (or confirm and state explicitly in the PR that the mkdocs-material note is being withdrawn).
@ -13,0 +17,4 @@- **PYSEC-2026-3848** (httpx2, MEDIUM): multipart part-header injection via the `files=` tuple API — not reachable through longwei's API (no multipart file-tuple usage).- **PYSEC-2026-3849** (httpx2, MEDIUM): conflicting Content-Length/Transfer-Encoding framing enabling request smuggling — not reachable through longwei's API (it sets neither header itself).The exposure claims reflect a search of the library source. Applications fetching compressed responses through the old httpx2 were exposed to PYSEC-2026-3846.docs [LOW]
"The exposure claims reflect a search of the library source" is too vague to be verifiable by a reader and does not say what was searched or how. Fix: name the check concretely, e.g. "based on a grep of longwei's source for proxy configuration, WebSocket use, multipart
files=tuples, and explicit Content-Length/Transfer-Encoding headers", so the non-reachability claims on lines 15-18 can be independently validated.@ -13,0 +19,4 @@The exposure claims reflect a search of the library source. Applications fetching compressed responses through the old httpx2 were exposed to PYSEC-2026-3846.longwei raises its httpx2 requirement to ~=2.12 (>=2.12, <3.0), and longwei's own build resolves httpcore2 to at least 2.12.0 — enforced by an explicit `httpcore2>=2.12.0` entry in `[tool.uv] constraint-dependencies` in `pyproject.toml` and reflected in `uv.lock`. Installing longwei into your own project resolves both for you: resolvers must satisfy longwei's declared `httpx2~=2.12` requirement, and httpx2 pins its matching httpcore2 exactly (`httpcore2==2.12.0`), so no manual version checks are needed. No API changes to longwei, and the full test suite passes unchanged.docs [HIGH]
This sentence says the
httpcore2>=2.12.0constraint is "reflected inuv.lock", but the PR description states the project's lockfile ispylock.toml("pylock.tomlregenerated ... its diff is empty from0288996"). Naming a lockfile that the project does not use will send users looking in the wrong place, and since the resolution was unchanged by the floor, "reflected in" the lock is also misleading. Fix: refer topylock.toml, and reword to say the lock already pins httpcore2 at 2.12.0 (the constraint is declarative defence-in-depth, not something that changed the pinned version).Wave 288 — one declined with evidence, two duplicates of dispositioned findings
Release-Notes.md#3103🔴 Declined — the premise conflates the repo's two lockfiles. This project has both:
uv.lock(uv's) andpylock.toml(the PEP 751 export). The PR body's note says only thatpylock.toml's diff was empty from0288996(the floor changes no resolved versions and the pylock format carries no constraint metadata); it does not saypylock.tomlis the project's lockfile. "Reflected inuv.lock" is verifiably true — the constraints block gained this line in0288996, as quoted in the wave-2 reply:Release-Notes.md#3104🔴 Duplicate of the wave-286 finding (declined here): the mkdocs-material pin shipped in the already-released 2.1.2 (
b8b2d0fpredates the 2.1.2 version bump), so its bullet is stale content for this pending announcement and its removal was a deliberate maintainer decision.Release-Notes.md#3105🔴 Duplicate of the search-method cluster, third re-raise — dispositioned as noted-not-actioned in the waves-284/285 triage. Unchanged: the maintainer has the list and is shipping this announcement's wording as-is.