Skip to content

[AAASM-6240] 🐛 (deps): Clear the uncovered critical pyjwt alert plus urllib3 and oauthlib - #658

Merged
Chisanan232 merged 3 commits into
mainfrom
v0.0.1/AAASM-6240/fix/clear_pyjwt_urllib3_oauthlib
Oct 1, 2026
Merged

Chisanan232 merged 3 commits into
mainfrom
v0.0.1/AAASM-6240/fix/clear_pyjwt_urllib3_oauthlib

Conversation

@Chisanan232

Copy link
Copy Markdown
Contributor

What changed

Three lock-only commits across 14 uv.lock files. No manifest, no source, no workflow.

commit change directories
a799546 pyjwt 2.13.0 -> 2.15.1 python/semantic-kernel-tool-policy
5d3f40b urllib3 2.7.0 -> 2.8.0 all 13 python/*
fc3211b oauthlib 3.3.1 -> 4.0.0 python/crewai-research-crew

Why

These are open Dependabot alerts that no Dependabot pull request has ever been opened for, including this repository's only critical alert. The alerts are raised correctly; what is missing is any remediation PR, so they are fixed at source rather than waited on.

.github/dependabot.yml sets open-pull-requests-limit: 10 on pip. A version-update PR is throttled by that limit; a security-update PR is not. With 19 Python bumps wanted and the version-update slots saturated, coverage is throttled while the critical sits open. Every alert shares created_at = 2026-10-01, so this is a single bulk advisory ingestion plus a saturated limit — not a disabled surface. Dependabot, code scanning and secret scanning are all enabled and readable here.

The critical, and why the obvious floor is wrong

GHSA-ffc3-869f-jxw9 (critical), PyJWT <= 2.13.0, transitive, in python/semantic-kernel-tool-policy/uv.lock. Thirteen distinct pyjwt advisories land in that one manifest, and two of them break the naive reading:

advisory vulnerable range declared patch
GHSA-gvp8-978c-rx2q >= 2.11.0, <= 2.13.0 NONE
GHSA-42vr-xj54-vc7v >= 2.0.0a1, <= 2.14.0 2.15.0
the other 11 various, all <= 2.13.0 2.14.0

GHSA-gvp8-978c-rx2q declares no patched version, but its range ends at 2.13.0 — anything above escapes it. A missing declared patch is not the same as unfixable. Conversely GHSA-42vr-xj54-vc7v is not cleared by 2.14.0, even though eleven siblings say 2.14.0 is enough.

The floor is therefore the maximum over advisories and a separate range-escape check: 2.15.0. Taking 2.14.0 would have left one advisory open; concluding "no fix available" from the first row would have left the critical open.

Verification

Each change is minimal

Every name -> version pair in each lock was compared before and after by parsing the TOML, not by reading the diff. In all 14 locks exactly one package version moved, with nothing added and nothing removed:

OK  crewai-research-crew                       {'urllib3': ('2.7.0', '2.8.0')}
OK  google-adk                                 {'urllib3': ('2.7.0', '2.8.0')}
OK  haystack-tool-policy                       {'urllib3': ('2.7.0', '2.8.0')}
OK  langchain-basic-agent                      {'urllib3': ('2.7.0', '2.8.0')}
OK  langchain-research-agent                   {'urllib3': ('2.7.0', '2.8.0')}
OK  langgraph                                  {'urllib3': ('2.7.0', '2.8.0')}
OK  llamaindex-tool-policy                     {'urllib3': ('2.7.0', '2.8.0')}
OK  microsoft-agent-framework-tool-policy      {'urllib3': ('2.7.0', '2.8.0')}
OK  openai-agents-sdk                          {'urllib3': ('2.7.0', '2.8.0')}
OK  pydantic-ai                                {'urllib3': ('2.7.0', '2.8.0')}
OK  semantic-kernel-tool-policy                {'urllib3': ('2.7.0', '2.8.0')}
OK  smolagents-tool-policy                     {'urllib3': ('2.7.0', '2.8.0')}
OK  strands-agents-tool-policy                 {'urllib3': ('2.7.0', '2.8.0')}
non-conforming dirs: 0

with pyjwt: ('2.13.0', '2.15.1') and oauthlib: ('3.3.1', '4.0.0') as the sole changes in their respective locks. Diffstat: 14 files, 42 insertions / 42 deletions, every hunk a version string.

Each lock still installs and agrees with its manifest

uv sync --locked --all-extras in all 13 directories, with the exit status of uv itself captured rather than a pipeline tail:

crewai-research-crew                       uv_rc=0  oauthlib 4.0.0  pyjwt 2.15.0  urllib3 2.8.0
google-adk                                 uv_rc=0  urllib3 2.8.0
haystack-tool-policy                       uv_rc=0  urllib3 2.8.0
langchain-basic-agent                      uv_rc=0  urllib3 2.8.0
langchain-research-agent                   uv_rc=0  urllib3 2.8.0
langgraph                                  uv_rc=0  urllib3 2.8.0
llamaindex-tool-policy                     uv_rc=0  urllib3 2.8.0
microsoft-agent-framework-tool-policy      uv_rc=0  pyjwt 2.15.0  urllib3 2.8.0
openai-agents-sdk                          uv_rc=0  pyjwt 2.15.0  urllib3 2.8.0
pydantic-ai                                uv_rc=0  pyjwt 2.15.0  urllib3 2.8.0
semantic-kernel-tool-policy                uv_rc=0  pyjwt 2.15.1  urllib3 2.8.0
smolagents-tool-policy                     uv_rc=0  pyjwt 2.15.1  urllib3 2.8.0
strands-agents-tool-policy                 uv_rc=0  pyjwt 2.15.0  urllib3 2.8.0

--locked is the load-bearing flag: it makes uv refuse rather than silently relock, so a green run proves the committed lock is what got installed. The resolved versions are read back from the installed environment, not from the lock that produced it.

Worth noting from that table: ten directories were already on a safe pyjwt >= 2.15.0. Only semantic-kernel-tool-policy was behind, which is exactly what the alert data said — the fix is targeted, not a blanket sweep.

The oauthlib major is verified, not assumed

oauthlib arrives transitively via kubernetes 36.0.2 -> requests-oauthlib 2.0.0, and requests-oauthlib 2.0.0 declares oauthlib>=3.0.0, so 4.x is admissible to the resolver. For a major, admissible is not the same as safe — requests-oauthlib 2.0.0 predates oauthlib 4. So behaviour was compared directly in two isolated venvs pinned to requests-oauthlib==2.0.0 + kubernetes==36.0.2, differing only in the oauthlib version:

probe oauthlib 3.3.1 oauthlib 4.0.0
OAuth1 Authorization header, fixed nonce n0 + timestamp 1700000000, sha256 prefix 9c2de00c9c86a37fb5c6eaf8 9c2de00c9c86a37fb5c6eaf8
authorization_url query string ?response_type=code&client_id=cid&redirect_uri=https%3A%2F%2Fx%2Fcb&scope=openid&state=ST byte-identical
kubernetes.config.kube_config OIDC loader import clean clean

The nonce and timestamp are pinned precisely so the signature is deterministic and the two runs are comparable; without that, HMAC output differs every call and the comparison would prove nothing. Identical signature bytes mean the signing path — the part requests-oauthlib actually drives — is unchanged across the major.

Deliberately held, not ignored

The 7 @grpc/grpc-js high alerts (>= 1.14.0, < 1.14.5, CVE-2026-101916, improper certificate validation) in node/*/pnpm-lock.yaml and scenarios/live-core-enforcement/node-agent/pnpm-lock.yaml are not in this PR. Eight Dependabot PRs are currently rebasing against those same lockfiles. Editing them here would conflict with the bot's own work, and per bot-PR policy a lockfile conflict is the bot's to resolve. They are tracked in AAASM-6240 AC7 and will be re-checked once those PRs land.

This PR is confined to python/**, so it is line-disjoint from every in-flight node PR.

No screenshots or recordings are attached: this workstation's data-handling policy keeps visual artifacts local, and the evidence above is complete without them.

Closes AAASM-6240.

🤖 Generated with Claude Code

Chisanan232 and others added 3 commits October 1, 2026 13:24
The only directory in this repo still on pyjwt 2.13.0, and the only one with
no Dependabot pull request covering it, so GHSA-ffc3-869f-jxw9 (critical,
asymmetric-PEM detection bypass) was live here with nothing in flight to fix
it. 2.15.1 also clears GHSA-42vr-xj54-vc7v, which 2.14.0 does not.

Verified that exactly one package version moved: pyjwt 2.13.0 -> 2.15.1.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GHSA-vp3f-5p7w-v63m (high) covers urllib3 < 2.8.0. Every python example
resolved 2.7.0, so the advisory was live in all 13 directories at once.
No Dependabot security-update pull request exists for any of them.

Verified per lock that exactly one package version moved, urllib3
2.7.0 -> 2.8.0, with no package added or removed in any of the 13.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
GHSA-hj66-6f7g-4r5v and GHSA-xpv3-w29h-x7cv both declare 4.0.0 as the only
patched release, and GHSA-xpv3-w29h-x7cv's range is >= 3.0.0, < 4.0.0, so no
3.x version escapes either. The major is forced, not chosen.

oauthlib arrives transitively via kubernetes 36.0.2 -> requests-oauthlib 2.0.0,
which declares oauthlib>=3.0.0 and so admits 4.x. Verified it is not merely
resolvable but behaviourally identical on every surface requests-oauthlib and
kubernetes touch: a fixed-nonce OAuth1 signature hashes the same under both
3.3.1 and 4.0.0, authorization_url emits a byte-identical query string, and
kubernetes.config.kube_config imports its OIDC loader clean.

Verified exactly one package version moved: oauthlib 3.3.1 -> 4.0.0.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@sonarqubecloud

sonarqubecloud Bot commented Oct 1, 2026

Copy link
Copy Markdown

@Chisanan232
Chisanan232 merged commit 7a46410 into main Oct 1, 2026
29 checks passed
@Chisanan232
Chisanan232 deleted the v0.0.1/AAASM-6240/fix/clear_pyjwt_urllib3_oauthlib branch October 1, 2026 06:24
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant