{"id":"GHSA-hq37-853p-g5cf","summary":"Regular Expression Denial of Service in CairoSVG","details":"# Doyensec Vulnerability Advisory \n\n* Regular Expression Denial of Service (REDoS) in cairosvg\n* Affected Product: CairoSVG v2.0.0+\n* Vendor: https://github.com/Kozea\n* Severity: Medium\n* Vulnerability Class: Denial of Service\n* Author(s): Ben Caller ([Doyensec](https://doyensec.com))\n\n## Summary\n\nWhen processing SVG files, the python package CairoSVG uses two regular expressions which are vulnerable to Regular Expression Denial of Service (REDoS).\nIf an attacker provides a malicious SVG, it can make cairosvg get stuck processing the file for a very long time.\n\n## Technical description\n\nThe vulnerable regular expressions are\n\nhttps://github.com/Kozea/CairoSVG/blob/9c4a982b9a021280ad90e89707eacc1d114e4ac4/cairosvg/colors.py#L190-L191\n\nThe section between 'rgb(' and the final ')' contains multiple overlapping groups.\n\nSince all three infinitely repeating groups accept spaces, a long string of spaces causes catastrophic backtracking when it is not followed by a closing parenthesis.\n\nThe complexity is cubic, so doubling the length of the malicious string of spaces makes processing take 8 times as long.\n\n## Reproduction steps\n\nCreate a malicious SVG of the form:\n\n    \u003csvg width=\"1\" height=\"1\"\u003e\u003crect fill=\"rgb(                     ;\"/\u003e\u003c/svg\u003e\n\nwith the following code:\n\n    '\u003csvg width=\"1\" height=\"1\"\u003e\u003crect fill=\"rgb(' + (' ' * 3456) + ';\"/\u003e\u003c/svg\u003e'\n\nNote that there is no closing parenthesis before the semi-colon.\n\nRun cairosvg e.g.:\n\n    cairosvg cairo-redos.svg -o x.png\n\nand notice that it hangs at 100% CPU. Increasing the number of spaces increases the processing time with cubic complexity.\n\n## Remediation\n\nFix the regexes to avoid overlapping parts. Perhaps remove the [ \\n\\r\\t]* groups from the regex, and use .strip() on the returned capture group.\n\n## Disclosure timeline\n\n- 2020-12-30: Vulnerability disclosed via email to CourtBouillon","aliases":["CVE-2021-21236","PYSEC-2021-5"],"modified":"2026-05-07T05:02:19.642555305Z","published":"2021-01-06T16:57:50Z","database_specific":{"github_reviewed_at":"2021-01-06T16:57:38Z","nvd_published_at":"2021-01-06T17:15:00Z","cwe_ids":["CWE-400"],"severity":"HIGH","github_reviewed":true},"references":[{"type":"WEB","url":"https://github.com/Kozea/CairoSVG/security/advisories/GHSA-hq37-853p-g5cf"},{"type":"ADVISORY","url":"https://nvd.nist.gov/vuln/detail/CVE-2021-21236"},{"type":"WEB","url":"https://github.com/Kozea/CairoSVG/commit/cfc9175e590531d90384aa88845052de53d94bf3"},{"type":"PACKAGE","url":"https://github.com/Kozea/CairoSVG"},{"type":"WEB","url":"https://github.com/Kozea/CairoSVG/releases/tag/2.5.1"},{"type":"WEB","url":"https://github.com/pypa/advisory-database/tree/main/vulns/cairosvg/PYSEC-2021-5.yaml"},{"type":"WEB","url":"https://pypi.org/project/CairoSVG"}],"affected":[{"package":{"name":"cairosvg","ecosystem":"PyPI","purl":"pkg:pypi/cairosvg"},"ranges":[{"type":"ECOSYSTEM","events":[{"introduced":"0"},{"fixed":"2.5.1"}]}],"versions":["0.1","0.1.1","0.1.2","0.2","0.3","0.3.1","0.4","0.4.1","0.4.2","0.4.3","0.4.4","0.5","1.0","1.0.1","1.0.10","1.0.11","1.0.12","1.0.13","1.0.14","1.0.15","1.0.16","1.0.17","1.0.18","1.0.19","1.0.2","1.0.20","1.0.21","1.0.22","1.0.3","1.0.4","1.0.5","1.0.6","1.0.7","1.0.8","1.0.9","2.0.0","2.0.0rc1","2.0.0rc2","2.0.0rc3","2.0.0rc4","2.0.0rc5","2.0.0rc6","2.0.1","2.0.2","2.0.3","2.1.0","2.1.1","2.1.2","2.1.3","2.2.0","2.2.1","2.3.0","2.3.1","2.4.0","2.4.1","2.4.2","2.5.0"],"database_specific":{"source":"https://github.com/github/advisory-database/blob/main/advisories/github-reviewed/2021/01/GHSA-hq37-853p-g5cf/GHSA-hq37-853p-g5cf.json"}}],"schema_version":"1.9.0","severity":[{"type":"CVSS_V3","score":"CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H"},{"type":"CVSS_V4","score":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:N/VA:H/SC:N/SI:N/SA:N/E:P"}]}