fix(deps): override limacharlie's pins to clear the cryptography and Pygments advisories - #95
Conversation
…ts GHSAs Two open Dependabot alerts could not be fixed by an ordinary lockfile bump: #4 cryptography 48.0.1 HIGH PKCS#7 EnvelopedData Bleichenbacher oracle #3 Pygments 2.19.1 LOW ReDoS in GUID matching Both were held open by limacharlie, which exact-pins ten of its dependencies — cryptography==48.0.1, pygments==2.19.1, requests==, pyyaml==, rich==, click==, and more. `uv lock --upgrade-package cryptography` is a no-op against an `==` constraint, and no released SDK relaxes it: 5.5.2 through 5.6.1 (latest) all carry the same pin. Overriding is safe here for a specific reason, not an optimistic one: the installed SDK imports neither package. grep over site-packages/limacharlie for cryptography and pygments returns nothing, so the pins constrain a dependency the vendor does not use. The packages that genuinely consume cryptography are permissive — PyJWT >=3.4.0 under its crypto extra, passlib unpinned. Verified: cryptography 50.0.0 and pygments 2.20.0 resolve, limacharlie still imports, and a PyJWT RS256 sign/verify round-trip through the new cryptography succeeds. Suite is unchanged at 815 passed — the 2 failures present are pre-existing on main and unrelated (confirmed by running them on a stashed tree). Each override names the advisory it exists for, so it can be removed once the SDK relaxes the pin rather than outliving its reason. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GWp9quiV9aBepvRyjA92Br
|
Claude finished @ubercylon8's task in 2m 26s —— View job Security review — PR #95
Scope: dependency-only change ( Claims verified:
One finding (suggestion, not blocking):
override-dependencies = [
"cryptography>=50.0.0",
"pygments>=2.20.0",
]Because this override exists specifically to force a security-relevant package past a vendor's stale pin, an unbounded Fix this → — tightens the override bound and re-locks. Summary: No security issues in the change itself — it correctly closes both Dependabot alerts, is scoped to exactly the two flagged packages, and includes a documented exit condition. The only suggestion is to bound the override specifiers so the fix doesn't quietly become a standing "always take whatever's newest" policy for a crypto-relevant dependency. |
From the PR's own review: unbounded `>=` on a security-motivated override lets a routine `uv lock --upgrade` float cryptography across a major boundary with no override-text change to review. That is the same "resolved something nobody chose" failure the block exists to prevent, pointed the other way. Now floor-and-cap, matching the repo's dependency policy: >=50.0.0,<51 and >=2.20.0,<3. Patch and minor releases still arrive without an edit, so a 50.0.x security fix needs no manual bump; only a major does. Resolution is unchanged — cryptography 50.0.0, pygments 2.20.0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01GWp9quiV9aBepvRyjA92Br
|
Claude finished @ubercylon8's task in 59s —— View job Security review — PR #95 (updated after latest push)
What changed since my last pass: commit override-dependencies = [
"cryptography>=50.0.0,<51",
"pygments>=2.20.0,<3",
]This closes the gap I flagged — a future Re-verified scope: CLAUDE.md Critical Rules: still not applicable — no tools, servers, CI: Summary: No security issues in the change itself or in this update. The override is scoped to exactly the two advisory-flagged packages, is now bounded below the next major on both floor and ceiling, and includes documented exit conditions. Nothing further to flag. |
|
Claude finished @ubercylon8's task in 59s —— View job Security review — PR #95
Scope: CLAUDE.md Critical Rules: none apply directly — no tools, gated-write logic, secret handling, or findings-schema code is touched. The override itself ( override-dependencies = [
"cryptography>=50.0.0,<51",
"pygments>=2.20.0,<3",
]
Correctness / test coverage: this is a pure dependency-resolution change; there's no new source logic to unit-test. The PR description documents a manual JWT sign/verify smoke test against the new Summary: No security issues. The change correctly closes both open Dependabot alerts, is scoped to exactly the two flagged packages, is bounded to avoid unreviewed future major bumps, and documents its own exit condition. Nothing further to flag. |
What & why
Clears the repository's two open Dependabot alerts:
cryptographyreaches seven servers — defender, entra, intune, limacharlie,purview, and both projectachilles servers — through
pyjwt[crypto]and thelimacharlie SDK.
Why an ordinary bump does not work
uv lock --upgrade-package cryptographyis a no-op, and uv explains why whenpushed:
The limacharlie SDK exact-pins ten of its dependencies:
No released version relaxes this — 5.5.2, 5.5.3, 5.5.4, 5.5.5, 5.6.0 and 5.6.1
(latest) all carry
cryptography==48.0.1. So the repository is downstream of avendor's pinning policy for ten packages, two of which currently carry
advisories.
Why overriding is safe here
Not optimism — a specific check. The installed SDK imports neither package:
It pins what it does not use. The packages that genuinely consume cryptography
are permissive:
PyJWT >=3.4.0under itscryptoextra, andpasslibunpinned. Nothing but a vendor declaration was holding 48.0.1 in place.
Separately, no repository code imports
cryptographyat all, and nothingreferences PKCS#7, EnvelopedData, or S/MIME — so the specific vulnerable API was
not being called from here either. That lowers the urgency; it does not remove
the exposure, since
pyjwt[crypto]links the library in regardless.The override, and its exit condition
[tool.uv] override-dependenciesin the rootpyproject.toml. Each entry namesthe advisory it exists for, so it can be removed when the SDK relaxes its
pin rather than quietly outliving its reason — an override nobody remembers is
how a project ends up resolving something nobody chose.
Worth raising upstream with LimaCharlie: exact-pinning transitives in a library
propagates every one of their advisories to every consumer, and it is why alerts
#1 and #2 (
requests) could only close when the SDK itself moved.Checklist (mirrors the Critical Rules in CLAUDE.md)
model / Returns Finding(s) / Safety logic stays in
core//Small-model-safe — n/a: dependency resolution only, no source touched.
uv run ruff check .anduv run mypy .pass; suite unchanged (see below).Testing
Functional smoke of the upgraded stack, since a cryptography major is the risk here:
Note on the 2 failures — they are pre-existing on
main, not caused by thisPR. I verified by stashing this change, re-syncing, and running them against a
clean tree: same two, same 815 passed.
Neither is dependency-related — one asserts device filtering returns
OLDbutnot
FRESH, the other assertsopencode.jsoncarries nomodel/providerkey.They want fixing, but in their own change rather than folded in here.
🤖 Generated with Claude Code
https://claude.ai/code/session_01GWp9quiV9aBepvRyjA92Br