') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ', 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); })(); Raise cryptography ceiling to allow the patched 50.x by matthewcummings · Pull Request #399 · finos/symphony-bdk-python · GitHub
Skip to content

Raise cryptography ceiling to allow the patched 50.x - #399

Merged
matthewcummings merged 2 commits into
finos:mainfrom
matthewcummings:raise-cryptography-ceiling
Aug 31, 2026
Merged

Raise cryptography ceiling to allow the patched 50.x#399
matthewcummings merged 2 commits into
finos:mainfrom
matthewcummings:raise-cryptography-ceiling

Conversation

@matthewcummings

@matthewcummingsmatthewcummings commented Aug 30, 2026

Copy link
Copy Markdown
Contributor

Problem

The current constraint, cryptography = ">=48.0.1,<49.0.0", cannot resolve to a version free of known CVEs:

cryptographyStatus
48.0.1CVE-2026-69247, CVE-2026-69249
49.0.0CVE-2026-69247
50.0.xclean

Both CVEs were published 2026-08-03, before 2.11.3 was released, so every version the released constraint permits is affected. Downstream consumers have no workaround: anything satisfying the BDK is vulnerable, and anything patched fails resolution. It surfaces as a hard failure in image compliance scanning.

This is the second time in eight days the ceiling has blocked a security fix. #397 raised it from <47.0.0 to <49.0.0 for CVE-2026-34180, and it is already stale again.

Change

-cryptography = ">=48.0.1,<49.0.0"+cryptography = ">=50.0.0,<51.0.0"

The bound is kept, just moved up to a range that contains a clean version. poetry.lock regenerated with Poetry 2.4.2, resolving cryptography 50.0.1. That is the only package change, none added or removed.

Verification

No new tests. This is a dependency constraint change, so the existing suite is the regression check. Run against the old pin and the new one to confirm the bump is not masking a regression:

cryptographyResult
48.0.1 (previous pin)560 passed, 3 skipped
50.0.0560 passed, 3 skipped
50.0.1 (newly locked)560 passed, 3 skipped

Worth considering separately

Keeping a one-major ceiling means this recurs. cryptography has shipped a major roughly every five to seven weeks this year (47.0.0 in April, 48.0.0 in May, 49.0.0 in June, 50.0.0 in July), so <51.0.0 will likely go stale before October and block the next security fix the same way.

This project's cryptography surface is three imports of long stable APIs, all in symphony/bdk/core/auth/jwt_helper.py:

fromcryptography.hazmat.primitives.serializationimportEncoding, PublicFormatfromcryptography.x509importload_pem_x509_certificate

idna is already declared without an upper bound here, so dropping the cryptography bound would not be a new pattern. Deliberately not doing that in this PR, since the priority is unblocking the CVEs, but it is worth a decision on its own.

Releasing

This PR also bumps version to 2.11.4, so merging it leaves main release-ready and the fix can go out without a second PR.

That is deliberate. #390 merged a constraint fix that then sat unreleased for five days until #397 bumped the version. The CVEs here are live in the released 2.11.3, so that gap matters this time.

Publishing still needs a maintainer to create and publish the GitHub release for v2.11.4, which triggers release.yml and poetry publish.

The current constraint, cryptography>=48.0.1,<49.0.0, cannot resolve to a
version free of known CVEs:
48.0.1 CVE-2026-69247 and CVE-2026-69249
49.0.0 CVE-2026-69247
50.0.x clean
Both CVEs were published 2026-08-03, before 2.11.3 was released, so every
version the released constraint permits is affected. Downstream consumers
cannot work around this: anything satisfying the BDK is vulnerable, and
anything patched fails resolution. It surfaces as a hard failure in image
compliance scanning.
This is the second time in eight days the ceiling has blocked a security
fix. finos#397 raised it from <47.0.0 to <49.0.0 for CVE-2026-34180, and it is
already stale again.
Verified: the full test suite passes on the new lock and identically on
the old pin, so this is not masking a regression.
cryptography 48.0.1 560 passed, 3 skipped
cryptography 50.0.0 560 passed, 3 skipped
cryptography 50.0.1 560 passed, 3 skipped (the locked version)
poetry.lock regenerated with Poetry 2.4.2; cryptography 48.0.1 to 50.0.1
is the only package change, none added or removed.
@matthewcummings
matthewcummingsforce-pushed the raise-cryptography-ceiling branch from e499f1f to feeb4dcCompareAugust 30, 2026 20:19
Included here so merging this PR leaves main release-ready, rather than
needing a second PR before the fix can reach consumers.
The constraint fix in finos#390 sat unreleased for five days because the
version bump was a separate change (finos#397). The CVEs this PR addresses
are live in the released 2.11.3, so the gap matters.
Follows the same convention as finos#397: pyproject.toml only. The lock is
unaffected, project version is not part of its content hash.
@matthewcummings
matthewcummings merged commit 487ac1c into finos:mainAug 31, 2026
21 checks passed
Sign up for freeto 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.

3 participants

@matthewcummings@thibauult@catalinsymphony