{"id":"CVE-2026-122053","kind":"vulnerability","aliases":["CVE-2026-122053"],"related":[],"title":"Symfony: Serializer normalizer lets requests write nested object properties","description":"The Symfony Serializer component ObjectNormalizer treats any attribute name containing . (and, from Symfony 6.4, [) as a writable property path, allowing untrusted input to modify properties of nested objects and bypass their #[Ignore] metadata attribute in Symfony versions 5.4.41 prior to 5.4.56, 6.4.9 prior to 6.4.50, 7.0.9 prior to 7.1.0, 7.1.2 prior to 7.4.23, and 8.x prior to 8.1.11.\nObjectNormalizer::isAllowedAttribute() accepts such names, and setAttributeValue() hands the name straight to PropertyAccessor::setValue(), which parses it as a property path and traverses into the nested object. A payload key such as customer.admin writes to $order->customer->admin. The #[Ignore] metadata attribute is only consulted when the nested object is denormalized in its own right, never when it is reached through a path. #[Groups] restrictions are not bypassed: the path is only accepted when no groups are passed in the context, and then groups restrict nothing. When the root class carries neither #[Ignore] nor #[Groups], no allowlist applies and every key of the payload is let through. Because PropertyAccessor also resolves a path segment against public methods, a segment matching a public method name invokes that method with the attacker’s value.Applications that bind untrusted input to objects are affected, including controllers using #[MapRequestPayload] or #[MapQueryString], whose default normalizer is ObjectNormalizer. With OBJECT_TO_POPULATE, as used for partial updates, the traversal reaches an already hydrated entity graph, and the modified field may be persisted.\n\nThe fix accepts a property path only when the class metadata declares an attribute of that exact name. Declared paths keep working unchanged, and a path in the payload with no matching declaration is ignored.","summary":"Symfony's Serializer ObjectNormalizer accepts attribute names containing dots or brackets and treats them as property paths. An attacker can send a payload key such as customer.admin to write into nested objects, bypass their #[Ignore] attributes, or invoke public methods.","severity":"medium","cvss":6.9,"epss":null,"exploited":false,"exploited_at":null,"products":[],"ecosystems":[],"tags":["package","php","symfony","symfony-controller","symfony-serializer"],"not_affected_if":["custom-normalizer","no-untrusted-object-binding"],"how_to_check":"- Check the installed `symfony/serializer` version in `composer.lock` or with `composer show symfony/serializer`.\n- Look for controllers or code that deserialize untrusted input into objects with `ObjectNormalizer`, including `#[MapRequestPayload]` and `#[MapQueryString]`, and for `OBJECT_TO_POPULATE` used on partial updates.","fix":"- Upgrade `symfony/serializer` to `5.4.56` or later on the 5.4 line.\n- Upgrade to `6.4.50` or later on the 6.4 line.\n- Upgrade to `7.1.0` or later on the 7.0 line, or `7.4.23` or later on the 7.1 and 7.4 lines.\n- Upgrade to `8.1.11` or later on the 8.x line.","status":"open","published_at":"2026-11-06T17:17:20+00:00","first_seen_at":"2026-11-06T17:43:12+00:00","triaged_at":"2026-11-06T17:45:18+00:00","updated_at":"2026-11-06T17:45:18+00:00","category":"package","confidence":0.8,"triage":{"at":"2026-11-06T17:45:18Z","model":"claude-haiku-5-5","output":{"fix":"- Upgrade `symfony/serializer` to `5.4.56` or later on the 5.4 line.\n- Upgrade to `6.4.50` or later on the 6.4 line.\n- Upgrade to `7.1.0` or later on the 7.0 line, or `7.4.23` or later on the 7.1 and 7.4 lines.\n- Upgrade to `8.1.11` or later on the 8.x line.","reach":"internet","title":"Symfony: Serializer normalizer lets requests write nested object properties","impact":"medium","summary":"Symfony's Serializer ObjectNormalizer accepts attribute names containing dots or brackets and treats them as property paths. An attacker can send a payload key such as customer.admin to write into nested objects, bypass their #[Ignore] attributes, or invoke public methods.","audience":"developers","category":"package","nicknames":[],"who_cares":["symfony","php","symfony-serializer","symfony-controller"],"confidence":0.8,"fix_status":"available","needs_auth":"unknown","worst_case":"Attacker writes nested object fields and may invoke public methods.","analyst_note":"","how_to_check":"- Check the installed `symfony/serializer` version in `composer.lock` or with `composer show symfony/serializer`.\n- Look for controllers or code that deserialize untrusted input into objects with `ObjectNormalizer`, including `#[MapRequestPayload]` and `#[MapQueryString]`, and for `OBJECT_TO_POPULATE` used on partial updates.","plain_action":"","needs_analyst":false,"not_affected_if":["no-untrusted-object-binding","custom-normalizer"],"who_is_affected":"Applications that bind untrusted request data to objects through the Symfony Serializer are exposed, including controllers using `#[MapRequestPayload]` or `#[MapQueryString]`, since ObjectNormalizer is their default normalizer. The flaw is reached through dotted or bracketed attribute names in the payload, and partial updates with OBJECT_TO_POPULATE can persist the modified field. Applications that do not deserialize untrusted input into objects can skip it.","user_interaction":"no","needs_special_setup":"unknown","severity_if_unknown":"unknown"},"cost_usd":0.001264,"input_tokens":4785,"output_tokens":1572,"severity_before":"medium"},"analyst_status":null,"analyst_note":null,"search":"'-122053':12A,15A '-2026':11A,14A '5.4.41':102C '5.4.56':105C '6.4':78C '6.4.50':109C '6.4.9':106C '7.0.9':110C '7.1.0':113C '7.1.2':114C '7.4.23':117C '8':119C '8.1.11':123C 'accept':29B,126C,196C,301C 'admin':161C 'affect':263C 'allow':84C 'allowlist':220C 'alreadi':288C 'also':233C 'appli':221C 'attack':43B,253C 'attribut':30B,60B,72C,98C,165C,312C 'bind':257C 'bracket':35B 'bypass':57B,94C,191C 'carri':214C 'class':213C,308C 'compon':68C 'consult':168C 'contain':32B,74C 'context':204C 'control':21B,265C 'custom':160C 'customer.admin':51B,156C 'cve':10A,13A 'declar':310C,317C,331C 'default':271C 'denorm':174C 'dot':33B 'entiti':290C 'everi':223C 'exact':315C 'field':295C 'fix':300C 'graph':291C 'group':187C,199C,207C,218C 'hand':131C 'hydrat':289C 'ignor':59B,96C,163C,216C,333C 'includ':264C 'input':86C,259C 'invok':62B,248C 'isallowedattribut':125C 'keep':319C 'key':48B,153C,224C 'let':4A,229C 'mapquerystr':269C 'maprequestpayload':267C 'match':243C,330C 'may':296C 'metadata':97C,164C,309C 'method':64B,240C,246C,250C 'modifi':88C,294C 'name':31B,73C,128C,133C,247C,316C 'neither':215C 'nest':7A,55B,91C,149C,171C 'never':179C 'normal':3A,272C 'noth':209C 'object':8A,56B,92C,150C,172C,261C,276C 'objectnorm':28B,69C,124C,274C 'order':159C 'packag':16B 'pars':139C 'partial':282C 'pass':201C 'path':41B,83C,144C,186C,193C,236C,304C,318C,324C 'payload':47B,152C,227C,327C 'persist':298C 'php':17B 'popul':278C 'prior':103C,107C,111C,115C,121C 'properti':9A,40B,82C,89C,143C,303C 'propertyaccessor':136C,232C 'public':63B,239C,245C 'reach':183C,286C 'request':5A 'resolv':234C 'restrict':188C,208C 'right':178C 'root':212C 'segment':237C,242C 'send':45B 'serial':2A,24B,27B,67C 'setattributevalu':130C 'setvalu':137C 'straight':134C 'symfoni':1A,18B,20B,23B,25B,66C,77C,100C 'symfony-control':19B 'symfony-seri':22B 'travers':146C,285C 'treat':37B,70C 'unchang':321C 'untrust':85C,258C 'updat':283C 'use':266C,280C 'value.applications':255C 'version':101C 'whose':270C 'work':320C 'writabl':81C 'write':6A,53B,157C 'x':120C","nicknames":[],"mitigations":[],"who_affected":"Applications that bind untrusted request data to objects through the Symfony Serializer are exposed, including controllers using `#[MapRequestPayload]` or `#[MapQueryString]`, since ObjectNormalizer is their default normalizer. The flaw is reached through dotted or bracketed attribute names in the payload, and partial updates with OBJECT_TO_POPULATE can persist the modified field. Applications that do not deserialize untrusted input into objects can skip it.","tier":"C","verified":{},"analyst_revisit_at":null,"fix_status":"available","audience":"developers","plain_action":null,"pkeys":[],"ptokens":[],"labels":["medium","package","php","symfony","symfonycontroller","symfonyserializer"],"campaign_type":null,"search_a":"'-122053':12A,15A '-2026':11A,14A 'cve':10A,13A 'let':4A 'nest':7A 'normal':3A 'object':8A 'properti':9A 'request':5A 'serial':2A 'symfoni':1A 'write':6A","search_b":"'accept':29B 'attack':43B 'attribut':30B,60B 'bracket':35B 'bypass':57B 'contain':32B 'control':21B 'customer.admin':51B 'dot':33B 'ignor':59B 'invok':62B 'key':48B 'method':64B 'name':31B 'nest':55B 'object':56B 'objectnorm':28B 'packag':16B 'path':41B 'payload':47B 'php':17B 'properti':40B 'public':63B 'send':45B 'serial':24B,27B 'symfoni':18B,20B,23B,25B 'symfony-control':19B 'symfony-seri':22B 'treat':37B 'write':53B","search_c":"'5.4.41':102C '5.4.56':105C '6.4':78C '6.4.50':109C '6.4.9':106C '7.0.9':110C '7.1.0':113C '7.1.2':114C '7.4.23':117C '8':119C '8.1.11':123C 'accept':126C,196C,301C 'admin':161C 'affect':263C 'allow':84C 'allowlist':220C 'alreadi':288C 'also':233C 'appli':221C 'attack':253C 'attribut':72C,98C,165C,312C 'bind':257C 'bypass':94C,191C 'carri':214C 'class':213C,308C 'compon':68C 'consult':168C 'contain':74C 'context':204C 'control':265C 'custom':160C 'customer.admin':156C 'declar':310C,317C,331C 'default':271C 'denorm':174C 'entiti':290C 'everi':223C 'exact':315C 'field':295C 'fix':300C 'graph':291C 'group':187C,199C,207C,218C 'hand':131C 'hydrat':289C 'ignor':96C,163C,216C,333C 'includ':264C 'input':86C,259C 'invok':248C 'isallowedattribut':125C 'keep':319C 'key':153C,224C 'let':229C 'mapquerystr':269C 'maprequestpayload':267C 'match':243C,330C 'may':296C 'metadata':97C,164C,309C 'method':240C,246C,250C 'modifi':88C,294C 'name':73C,128C,133C,247C,316C 'neither':215C 'nest':91C,149C,171C 'never':179C 'normal':272C 'noth':209C 'object':92C,150C,172C,261C,276C 'objectnorm':69C,124C,274C 'order':159C 'pars':139C 'partial':282C 'pass':201C 'path':83C,144C,186C,193C,236C,304C,318C,324C 'payload':152C,227C,327C 'persist':298C 'popul':278C 'prior':103C,107C,111C,115C,121C 'properti':82C,89C,143C,303C 'propertyaccessor':136C,232C 'public':239C,245C 'reach':183C,286C 'resolv':234C 'restrict':188C,208C 'right':178C 'root':212C 'segment':237C,242C 'serial':67C 'setattributevalu':130C 'setvalu':137C 'straight':134C 'symfoni':66C,77C,100C 'travers':146C,285C 'treat':70C 'unchang':321C 'untrust':85C,258C 'updat':283C 'use':266C,280C 'value.applications':255C 'version':101C 'whose':270C 'work':320C 'writabl':81C 'write':157C 'x':120C","first_public_at":"2026-11-04T11:43:50+00:00","kev":null,"cvss_vector":"CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:L/VI:L/VA:N/SC:N/SI:N/SA:N/E:X/CR:X/IR:X/AR:X/MAV:X/MAC:X/MAT:X/MPR:X/MUI:X/MVC:X/MVI:X/MVA:X/MSC:X/MSI:X/MSA:X/S:X/AU:X/R:X/V:X/RE:X/U:X","cvss_by":"596c5446-0ce5-4ba2-aa66-48b3b757a647","poc_count":0,"sources":[{"source":"nvd","external_id":"CVE-2026-122053","url":"https://nvd.nist.gov/vuln/detail/CVE-2026-122053","severity":null,"published_at":"2026-11-06T17:17:20+00:00","modified_at":"2026-11-06T17:17:20+00:00","first_seen_at":"2026-11-06T17:43:12+00:00","fetched_at":"2026-11-06T17:43:12+00:00","note":null}],"documents":[{"id":88376,"url":"https://github.com/symfony/symfony/commit/9f7390678a255f7962fb1c81c42b26fa907d3437","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":88377,"url":"https://github.com/symfony/symfony/commit/fcaf87a93c7fa5b7fe9e9e8382d4ed0d0c52c67c","title":"Patch: github.com","kind":"other","source":"nvd","publisher":"vendor","text":null,"published_at":null,"relation":"fix","confidence":null,"note":"Patch: github.com"},{"id":88378,"url":"https://github.com/symfony/symfony/security/advisories/GHSA-hqp2-7rr8-hf26","title":"Vendor advisory: github.com","kind":"vendor","source":"nvd","publisher":"vendor","text":null,"published_at":"2026-11-04T11:43:50+00:00","relation":"advisory","confidence":null,"note":"Vendor advisory: github.com"}],"exploit_sources":[],"notice":"Free to read, with fair use of about 60 pages a minute. For higher limits or API access: sales@infrastack.ai"}