← Back to CVE Explorer

CVE-2026-122053

Full vulnerability record from the local CVENow database.

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. ObjectNormalizer::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. The 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.

Severity
MEDIUM
CVSS score
6.9 (v4.0)
Vulnerability status
Received
Source identifier
596c5446-0ce5-4ba2-aa66-48b3b757a647
Published
2026-11-06 17:17:20.123000
Last modified
2026-11-06 17:17:20.123000
View original CVE JSON
{
  "id": "CVE-2026-122053",
  "sourceIdentifier": "596c5446-0ce5-4ba2-aa66-48b3b757a647",
  "published": "2026-11-06T17:17:20.123",
  "lastModified": "2026-11-06T17:17:20.123",
  "vulnStatus": "Received",
  "cveTags": [],
  "descriptions": [
    {
      "lang": "en",
      "value": "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."
    }
  ],
  "affected": [
    {
      "source": "596c5446-0ce5-4ba2-aa66-48b3b757a647",
      "affectedData": [
        {
          "vendor": "sensiolabs",
          "product": "symfony",
          "defaultStatus": "unaffected",
          "collectionURL": "https://packagist.org/packages/symfony/serializer",
          "packageName": "symfony/serializer",
          "modules": [
            "Symfony\\Component\\Serializer\\Normalizer\\ObjectNormalizer::isAllowedAttribute()"
          ],
          "repo": "https://github.com/symfony/serializer",
          "versions": [
            {
              "version": "5.4.41",
              "lessThan": "5.4.56",
              "versionType": "git",
              "status": "affected"
            },
            {
              "version": "6.4.9",
              "lessThan": "6.4.50",
              "versionType": "git",
              "status": "affected"
            },
            {
              "version": "7.0.9",
              "lessThan": "7.1.0",
              "versionType": "git",
              "status": "affected"
            },
            {
              "version": "7.1.2",
              "lessThan": "7.4.23",
              "versionType": "git",
              "status": "affected"
            },
            {
              "version": "8.0.0",
              "lessThan": "8.1.11",
              "versionType": "git",
              "status": "affected"
            }
          ]
        }
      ]
    }
  ],
  "metrics": {
    "cvssMetricV40": [
      {
        "source": "596c5446-0ce5-4ba2-aa66-48b3b757a647",
        "type": "Secondary",
        "cvssData": {
          "version": "4.0",
          "vectorString": "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",
          "baseScore": 6.9,
          "baseSeverity": "MEDIUM",
          "attackVector": "NETWORK",
          "attackComplexity": "LOW",
          "attackRequirements": "NONE",
          "privilegesRequired": "NONE",
          "userInteraction": "NONE",
          "vulnConfidentialityImpact": "LOW",
          "vulnIntegrityImpact": "LOW",
          "vulnAvailabilityImpact": "NONE",
          "subConfidentialityImpact": "NONE",
          "subIntegrityImpact": "NONE",
          "subAvailabilityImpact": "NONE",
          "exploitMaturity": "NOT_DEFINED",
          "confidentialityRequirement": "NOT_DEFINED",
          "integrityRequirement": "NOT_DEFINED",
          "availabilityRequirement": "NOT_DEFINED",
          "modifiedAttackVector": "NOT_DEFINED",
          "modifiedAttackComplexity": "NOT_DEFINED",
          "modifiedAttackRequirements": "NOT_DEFINED",
          "modifiedPrivilegesRequired": "NOT_DEFINED",
          "modifiedUserInteraction": "NOT_DEFINED",
          "modifiedVulnConfidentialityImpact": "NOT_DEFINED",
          "modifiedVulnIntegrityImpact": "NOT_DEFINED",
          "modifiedVulnAvailabilityImpact": "NOT_DEFINED",
          "modifiedSubConfidentialityImpact": "NOT_DEFINED",
          "modifiedSubIntegrityImpact": "NOT_DEFINED",
          "modifiedSubAvailabilityImpact": "NOT_DEFINED",
          "Safety": "NOT_DEFINED",
          "Automatable": "NOT_DEFINED",
          "Recovery": "NOT_DEFINED",
          "valueDensity": "NOT_DEFINED",
          "vulnerabilityResponseEffort": "NOT_DEFINED",
          "providerUrgency": "NOT_DEFINED"
        }
      }
    ]
  },
  "weaknesses": [
    {
      "source": "596c5446-0ce5-4ba2-aa66-48b3b757a647",
      "type": "Secondary",
      "description": [
        {
          "lang": "en",
          "value": "CWE-915"
        }
      ]
    }
  ],
  "references": [
    {
      "url": "https://github.com/symfony/symfony/commit/9f7390678a255f7962fb1c81c42b26fa907d3437",
      "source": "596c5446-0ce5-4ba2-aa66-48b3b757a647"
    },
    {
      "url": "https://github.com/symfony/symfony/commit/fcaf87a93c7fa5b7fe9e9e8382d4ed0d0c52c67c",
      "source": "596c5446-0ce5-4ba2-aa66-48b3b757a647"
    },
    {
      "url": "https://github.com/symfony/symfony/security/advisories/GHSA-hqp2-7rr8-hf26",
      "source": "596c5446-0ce5-4ba2-aa66-48b3b757a647"
    }
  ]
}