Incorrect handling of invalid surrogate pair charactersGHSA-wpqr-jcpx-745r
HIGHFix: ultrajson/ultrajson@67ec071GHSA-wpqr-jcpx-745r is a high-severity (CVSS 7.5) CWE-670 vulnerability in ujson. 1 public exploit or proof-of-concept reference is indexed, so weaponization risk is real. A fix is available for ujson — see the affected versions and patch details below.
Exploitation Status
Proof-of-concept exploit code exists
- CISA’s SSVC triage found public proof-of-concept exploit code for this CVE, though no confirmed active exploitation.
- CISA assesses this as automatable — exploitation doesn’t require manual, per-target effort, which raises the odds of mass scanning and opportunistic attacks.
Exploitation and automatability from CISA’s SSVC triage for GHSA-wpqr-jcpx-745r.
EPSS Exploitation Probability
Probability of exploitation in the next 30 days, from FIRST.org EPSS.
How urgent is this, really
Where this sits among everything scored
Real-World Exposure
ujsonReal-time download stats are indexed for npm and PyPI packages. This vulnerability affects PyPI packages — download data is not available via public APIs for these ecosystems.
Description
Impact
What kind of vulnerability is it? Who is impacted?
Anyone parsing JSON from an untrusted source is vulnerable.
JSON strings that contain escaped surrogate characters not part of a proper surrogate pair were decoded incorrectly. Besides corrupting strings, this allowed for potential key confusion and value overwriting in dictionaries.
Examples:
# An unpaired high surrogate character is ignored.
>>> ujson.loads(r'"\uD800"')
''
>>> ujson.loads(r'"\uD800hello"')
'hello'
# An unpaired low surrogate character is preserved.
>>> ujson.loads(r'"\uDC00"')
'\udc00'
# A pair of surrogates with additional non surrogate characters pair up in spite of being invalid.
>>> ujson.loads(r'"\uD800foo bar\uDC00"')
'foo bar𐀀'
Patches
Has the problem been patched? What versions should users upgrade to?
Users should upgrade to UltraJSON 5.4.0.
From version 5.4.0, UltraJSON decodes lone surrogates in the same way as the standard library's json module does, preserving them in the parsed output:
>>> ujson.loads(r'"\uD800"')
'\ud800'
>>> ujson.loads(r'"\uD800hello"')
'\ud800hello'
>>> ujson.loads(r'"\uDC00"')
'\udc00'
>>> ujson.loads(r'"\uD800foo bar\uDC00"')
'\ud800foo bar\udc00'
Workarounds
Is there a way for users to fix or remediate the vulnerability without upgrading?
Short of switching to an entirely different JSON library, there are no safe alternatives to upgrading.
For more information
If you have any questions or comments about this advisory:
- Open an issue in UltraJSON
Affected Packages
| Ecosystem | Package | Vulnerable range | Fix |
|---|---|---|---|
| 🐍PyPI | ujson | all versions | 5.4.0pip install --upgrade 'ujson==5.4.0' |
Affected Products
fedorafedoraprojectultrajsonultrajson_projectResearch use only. For defensive security, authorized penetration testing, and academic research only. Never execute exploit code against systems without explicit written authorization.
Detection & mitigation playbook
Open-source dependencyDetect
Scan your dependency tree (package-lock.json, pnpm-lock.yaml, requirements.txt, go.sum, etc.) for ujson, including transitive dependencies — a direct dependency you never call can still pull in a vulnerable version.
Fix
Update ujson to 5.4.0 or later, then make sure no transitive (indirect) dependency still pins the vulnerable range — O3 confirms GHSA-wpqr-jcpx-745r is resolved across your whole dependency graph.
Workarounds
If you can't upgrade right away: gate or disable the affected feature, validate untrusted input at the boundary, and avoid passing attacker-controlled data into the vulnerable path. O3's runtime protection blocks exploitation in production as an interim safeguard until the upgrade lands.
Fixing This On Your OS
If you run this on a Linux distribution, patch through your package manager against the distro's own security advisory below — it tracks the exact backported fix for your release, which can ship on a different timeline (and sometimes a different severity) than the upstream project.
| Product | Fixed in | Advisory |
|---|---|---|
| Red Hat OpenStack Platform 16.1 | python-ujson-0:2.0.3-3.el8ost | RHSA-2022:8864 |
| Red Hat OpenStack Platform 16.2 | python-ujson-0:2.0.3-3.el8ost | RHSA-2022:8850 |
Frequently Asked Questions
Is GHSA-wpqr-jcpx-745r in your dependencies?
Find it across PyPI, including transitive dependencies.