{"id":"GHSA-cpww-5vpx-72x7","kind":"vulnerability","aliases":["GHSA-cpww-5vpx-72x7"],"related":[],"title":"Incomplete Fix for CVE-2026-45756: JsonPath Queries Can Still Hold a Process Through search(), match() and Chained Filters","description":"### Description\n\nThe fix for CVE-2026-45756 lowers `pcre.backtrack_limit` to 10000 around each `preg_match()` call of the `match()` and `search()` filter functions. That limit applies to one starting position, not to one call. PCRE resets its counter at every position it tries a match from. So an unanchored pattern that stays just under the limit is paid once per byte of the subject. Each call also starts from a fresh limit, so chaining clauses in one filter multiplies the work.\n\nTwo other paths made the cost of a query grow faster than its size, without any regular expression:\n\n- The filter evaluator scanned the whole expression for logical operators once per node. Its cost grew with the square of the number of chained clauses.\n- Queries starting with `$` inside a filter, like `@.x == $.limit` or `length($.items)`, were evaluated again for every node the filter visits.\n\nAn application that evaluates an attacker-influenced JSONPath expression can therefore still be made to hold a PHP worker. A document of 2 MB and a query of 2.5 KB take 3.5 minutes of CPU.\n\n### Resolution\n\n`JsonCrawler::find()` now bounds the total regex work of one call, and throws an exception when that budget is exhausted. Filter expressions are parsed once per query, and absolute queries inside filters are evaluated once per query.\n\nThe patches for this issue are available [here](https://github.com/symfony/symfony/commit/11650dc31f03badb5d24199a1023539ae6380ff2), [here](https://github.com/symfony/symfony/commit/df0d7dc6b1fd7a671be3a6519a82047bb2ab6b47) and [here](https://github.com/symfony/symfony/commit/45e44c5e228c131185e334c7ba390d51ea4517f8) for branch 7.4 (and forward-ported to 8.1 and 8.2).\n\n### Credits\n\nWe would like to thank Kamil Vavra for reporting the issue and Nicolas Grekas for finding the related ones and providing the fix.","summary":"The JsonPath component in Symfony still lets a crafted query with search(), match() or chained filters burn CPU far beyond its size, after an earlier fix for the same class of flaw. An application that evaluates an attacker-influenced JSONPath expression can have a PHP worker held for minutes, a denial of service.","severity":"medium","cvss":null,"epss":null,"exploited":false,"exploited_at":null,"products":[{"name":"symfony/json-path","note":">=7.3.0, <7.4.23","fixed":["7.4.23"],"affected":">= 7.3.0, < 7.4.23","ecosystem":"composer"},{"name":"symfony/json-path","note":">=8.0.0, <8.1.11","fixed":["8.1.11"],"affected":">= 8.0.0, < 8.1.11","ecosystem":"composer"},{"name":"symfony/symfony","note":">=7.3.0, <7.4.23","fixed":["7.4.23"],"affected":">= 7.3.0, < 7.4.23","ecosystem":"composer"},{"name":"symfony/symfony","note":">=8.0.0, <8.1.11","fixed":["8.1.11"],"affected":">= 8.0.0, < 8.1.11","ecosystem":"composer"}],"ecosystems":["composer"],"tags":["cwe-1333","cwe-400","cwe-407","json-path","package","php","self-hosted","symfony"],"not_affected_if":["auth-required","static-queries","trusted-input"],"how_to_check":"- Run `composer show symfony/json-path` and `composer show symfony/symfony` to read the installed versions.\n- Look for code that passes user-supplied strings to JsonPath or JsonCrawler `find()` with filter expressions.","fix":"- `symfony/json-path` 7.x: `7.4.23`\n- `symfony/json-path` 8.x: `8.1.11`\n- `symfony/symfony` 7.x: `7.4.23`\n- `symfony/symfony` 8.x: `8.1.11`","status":"open","published_at":"2026-11-04T11:43:33+00:00","first_seen_at":"2026-11-09T22:53:32+00:00","triaged_at":"2026-11-09T22:58:42+00:00","updated_at":"2026-11-09T22:58:42+00:00","category":"package","confidence":0.7,"triage":{"at":"2026-11-09T22:58:42Z","model":"claude-haiku-5-5","output":{"fix":"- `symfony/json-path` 7.x: `7.4.23`\n- `symfony/json-path` 8.x: `8.1.11`\n- `symfony/symfony` 7.x: `7.4.23`\n- `symfony/symfony` 8.x: `8.1.11`","reach":"unknown","title":"Symfony JsonPath: crafted queries can hold a PHP worker for minutes","impact":"low","summary":"The JsonPath component in Symfony still lets a crafted query with search(), match() or chained filters burn CPU far beyond its size, after an earlier fix for the same class of flaw. An application that evaluates an attacker-influenced JSONPath expression can have a PHP worker held for minutes, a denial of service.","audience":"developers","category":"package","nicknames":[],"who_cares":["symfony","php","json-path","self-hosted"],"confidence":0.7,"fix_status":"available","needs_auth":"unknown","worst_case":"Attacker holds a PHP worker for minutes, causing denial of service","analyst_note":"","how_to_check":"- Run `composer show symfony/json-path` and `composer show symfony/symfony` to read the installed versions.\n- Look for code that passes user-supplied strings to JsonPath or JsonCrawler `find()` with filter expressions.","plain_action":"","product_name":"","needs_analyst":false,"not_affected_if":["auth-required","static-queries","trusted-input"],"who_is_affected":"Applications that evaluate JSONPath expressions which an attacker can influence, such as a query string or request field passed to JsonPath filters. Applications that only use fixed, developer-written JSONPath queries on trusted data are not exposed. The sources do not say whether default configurations are reachable from the internet.","user_interaction":"no","product_ecosystem":"","needs_special_setup":"yes","severity_if_unknown":"medium"},"cost_usd":0.000852,"input_tokens":5346,"output_tokens":635,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-1333':35B '-2026':5A,108C '-400':37B '-407':39B '-45756':6A,109C '/symfony/symfony/commit/11650dc31f03badb5d24199a1023539ae6380ff2),':333C '/symfony/symfony/commit/45e44c5e228c131185e334c7ba390d51ea4517f8)':342C '/symfony/symfony/commit/df0d7dc6b1fd7a671be3a6519a82047bb2ab6b47)':337C '10000':114C '2':272C '2.5':278C '3.5':281C '5vpx':23A,28A '7.4':345C '72x7':24A,29A '8.1':351C '8.2':353C 'absolut':314C 'also':170C 'appli':129C 'applic':82B,250C 'around':115C 'attack':87B,255C 'attacker-influenc':86B,254C 'avail':329C 'beyond':68B 'bound':289C 'branch':344C 'budget':303C 'burn':65B 'byte':164C 'call':119C,137C,169C,296C 'chain':18A,63B,177C,226C 'class':78B 'claus':178C,227C 'compon':51B 'cost':190C,217C 'counter':141C 'cpu':66B,284C 'cpww':22A,27A 'craft':57B 'credit':354C 'cve':4A,107C 'cwe':34B,36B,38B 'denial':100B 'descript':103C 'document':270C 'earlier':73B 'evalu':84B,205C,241C,252C,319C 'everi':143C,244C 'except':300C 'exhaust':305C 'express':90B,202C,209C,258C,307C 'far':67B 'faster':195C 'filter':19A,64B,125C,181C,204C,233C,247C,306C,317C 'find':287C,370C 'fix':2A,74B,105C,377C 'flaw':80B 'forward':348C 'forward-port':347C 'fresh':174C 'function':126C 'ghsa':21A,26A 'ghsa-cpww-5vpx-72x7':20A,25A 'github.com':332C,336C,341C 'github.com/symfony/symfony/commit/11650dc31f03badb5d24199a1023539ae6380ff2),':331C 'github.com/symfony/symfony/commit/45e44c5e228c131185e334c7ba390d51ea4517f8)':340C 'github.com/symfony/symfony/commit/df0d7dc6b1fd7a671be3a6519a82047bb2ab6b47)':335C 'greka':368C 'grew':218C 'grow':194C 'held':96B 'hold':11A,265C 'host':47B 'incomplet':1A 'influenc':88B,256C 'insid':231C,316C 'issu':327C,365C 'item':239C 'json':41B 'json-path':40B 'jsoncrawl':286C 'jsonpath':7A,50B,89B,257C 'kamil':360C 'kb':279C 'length':238C 'let':55B 'like':234C,357C 'limit':112C,128C,159C,175C,236C 'logic':211C 'lower':110C 'made':188C,263C 'match':16A,61B,118C,122C,148C 'mb':273C 'minut':98B,282C 'multipli':182C 'nicola':367C 'node':215C,245C 'number':224C 'one':131C,136C,180C,295C,373C 'oper':212C 'packag':43B 'paid':161C 'pars':309C 'patch':324C 'path':42B,187C 'pattern':153C 'pcre':138C 'pcre.backtrack':111C 'per':163C,214C,311C,321C 'php':44B,94B,267C 'port':349C 'posit':133C,144C 'preg':117C 'process':13A 'provid':375C 'queri':8A,58B,193C,228C,276C,312C,315C,322C 'regex':292C 'regular':201C 'relat':372C 'report':363C 'reset':139C 'resolut':285C 'scan':206C 'search':15A,60B,124C 'self':46B 'self-host':45B 'servic':102B 'size':70B,198C 'squar':221C 'start':132C,171C,229C 'stay':155C 'still':10A,54B,261C 'subject':167C 'symfoni':48B,53B 'symfony/json-path':30A,31A 'symfony/symfony':32A,33A 'take':280C 'thank':359C 'therefor':260C 'throw':298C 'total':291C 'tri':146C 'two':185C 'unanchor':152C 'vavra':361C 'visit':248C 'whole':208C 'without':199C 'work':184C,293C 'worker':95B,268C 'would':356C 'x':235C","nicknames":[],"mitigations":[],"who_affected":"Applications that evaluate JSONPath expressions which an attacker can influence, such as a query string or request field passed to JsonPath filters. Applications that only use fixed, developer-written JSONPath queries on trusted data are not exposed. The sources do not say whether default configurations are reachable from the internet.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":["symfonyjsonpath","symfonysymfony"],"ptokens":["json","path","symfony"],"labels":["composer","cwe1333","cwe400","cwe407","jsonpath","medium","package","php","selfhosted","symfony"],"campaign_type":null,"search_a":"'-2026':5A '-45756':6A '5vpx':23A,28A '72x7':24A,29A 'chain':18A 'cpww':22A,27A 'cve':4A 'filter':19A 'fix':2A 'ghsa':21A,26A 'ghsa-cpww-5vpx-72x7':20A,25A 'hold':11A 'incomplet':1A 'jsonpath':7A 'match':16A 'process':13A 'queri':8A 'search':15A 'still':10A 'symfony/json-path':30A,31A 'symfony/symfony':32A,33A","search_b":"'-1333':35B '-400':37B '-407':39B 'applic':82B 'attack':87B 'attacker-influenc':86B 'beyond':68B 'burn':65B 'chain':63B 'class':78B 'compon':51B 'cpu':66B 'craft':57B 'cwe':34B,36B,38B 'denial':100B 'earlier':73B 'evalu':84B 'express':90B 'far':67B 'filter':64B 'fix':74B 'flaw':80B 'held':96B 'host':47B 'influenc':88B 'json':41B 'json-path':40B 'jsonpath':50B,89B 'let':55B 'match':61B 'minut':98B 'packag':43B 'path':42B 'php':44B,94B 'queri':58B 'search':60B 'self':46B 'self-host':45B 'servic':102B 'size':70B 'still':54B 'symfoni':48B,53B 'worker':95B","search_c":"'-2026':108C '-45756':109C '/symfony/symfony/commit/11650dc31f03badb5d24199a1023539ae6380ff2),':333C '/symfony/symfony/commit/45e44c5e228c131185e334c7ba390d51ea4517f8)':342C '/symfony/symfony/commit/df0d7dc6b1fd7a671be3a6519a82047bb2ab6b47)':337C '10000':114C '2':272C '2.5':278C '3.5':281C '7.4':345C '8.1':351C '8.2':353C 'absolut':314C 'also':170C 'appli':129C 'applic':250C 'around':115C 'attack':255C 'attacker-influenc':254C 'avail':329C 'bound':289C 'branch':344C 'budget':303C 'byte':164C 'call':119C,137C,169C,296C 'chain':177C,226C 'claus':178C,227C 'cost':190C,217C 'counter':141C 'cpu':284C 'credit':354C 'cve':107C 'descript':103C 'document':270C 'evalu':205C,241C,252C,319C 'everi':143C,244C 'except':300C 'exhaust':305C 'express':202C,209C,258C,307C 'faster':195C 'filter':125C,181C,204C,233C,247C,306C,317C 'find':287C,370C 'fix':105C,377C 'forward':348C 'forward-port':347C 'fresh':174C 'function':126C 'github.com':332C,336C,341C 'github.com/symfony/symfony/commit/11650dc31f03badb5d24199a1023539ae6380ff2),':331C 'github.com/symfony/symfony/commit/45e44c5e228c131185e334c7ba390d51ea4517f8)':340C 'github.com/symfony/symfony/commit/df0d7dc6b1fd7a671be3a6519a82047bb2ab6b47)':335C 'greka':368C 'grew':218C 'grow':194C 'hold':265C 'influenc':256C 'insid':231C,316C 'issu':327C,365C 'item':239C 'jsoncrawl':286C 'jsonpath':257C 'kamil':360C 'kb':279C 'length':238C 'like':234C,357C 'limit':112C,128C,159C,175C,236C 'logic':211C 'lower':110C 'made':188C,263C 'match':118C,122C,148C 'mb':273C 'minut':282C 'multipli':182C 'nicola':367C 'node':215C,245C 'number':224C 'one':131C,136C,180C,295C,373C 'oper':212C 'paid':161C 'pars':309C 'patch':324C 'path':187C 'pattern':153C 'pcre':138C 'pcre.backtrack':111C 'per':163C,214C,311C,321C 'php':267C 'port':349C 'posit':133C,144C 'preg':117C 'provid':375C 'queri':193C,228C,276C,312C,315C,322C 'regex':292C 'regular':201C 'relat':372C 'report':363C 'reset':139C 'resolut':285C 'scan':206C 'search':124C 'size':198C 'squar':221C 'start':132C,171C,229C 'stay':155C 'still':261C 'subject':167C 'take':280C 'thank':359C 'therefor':260C 'throw':298C 'total':291C 'tri':146C 'two':185C 'unanchor':152C 'vavra':361C 'visit':248C 'whole':208C 'without':199C 'work':184C,293C 'worker':268C 'would':356C 'x':235C","cause_entry":null,"cause_path":null,"disclosures_checked_at":null,"first_public_at":"2026-11-04T11:43:33+00:00","kev":null,"cvss_vector":null,"cvss_by":null,"poc_count":0,"sources":[{"source":"ghsa-repo","external_id":"GHSA-cpww-5vpx-72x7","url":"https://github.com/symfony/symfony/security/advisories/GHSA-cpww-5vpx-72x7","severity":"medium","published_at":"2026-11-04T11:43:33+00:00","modified_at":"2026-11-04T11:43:33+00:00","first_seen_at":"2026-11-09T22:53:32+00:00","fetched_at":"2026-11-09T22:53:32+00:00","note":null}],"documents":[{"id":110708,"url":"https://github.com/symfony/symfony/security/advisories/GHSA-cpww-5vpx-72x7","title":"Maintainer's advisory: github.com","kind":"vendor","source":"ghsa-repo","publisher":"vendor","text":null,"published_at":null,"relation":"advisory","confidence":null,"note":"Maintainer's advisory: github.com"}],"disclosures":[],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}