The vulnerability description clearly states that rendering {{ attributes }} (which calls __toString() on a ComponentAttributes object) or using methods that return a ComponentAttributes instance could lead to unescaped output. The core issue was the lack of enforced escaping within the ComponentAttributes class.
The primary fix in symfony/ux-twig-component (commit b5d4e77db69315aeb18d2238e0e7c943d340ce76) targets the ComponentAttributes class.
- The
__construct method was changed to require a Twig\Runtime\EscaperRuntime instance, ensuring that an escaper is always present. Previously, it accepted an optional HtmlAttributeEscaperInterface, and a deprecation was triggered if it was null. This optional nature was a root cause.
- The
__toString method was modified to use this mandatory escaper to escape attribute values before they are included in the output string. The removed line $attributes .= ' '.\sprintf('%s="%s"', $key, $this->escaper?->escapeValue($value) ?? $value); shows that if $this->escaper was null (which was possible before the constructor change), the raw $value would be used.
Therefore, Symfony\UX\TwigComponent\ComponentAttributes::__toString() is the function that directly processed and outputted the potentially malicious unescaped input. The Symfony\UX\TwigComponent\ComponentAttributes::__construct() method is also identified as vulnerable because its previous implementation allowed the object to be instantiated in a state where __toString() would behave insecurely.
Methods like only(), defaults(), and without() were mentioned in the advisory because they return ComponentAttributes instances. If the original instance was created without a proper escaper, these methods would propagate that insecure state by creating new instances that also lacked the escaper. However, the actual unescaped output and processing of malicious input occurred within __toString().