Problem
The names of attributes (and hence, the allowed keys for Drupal\Core\Template\Attribute) have a specific constraint outlined by the W3C. Enforce it.
Solution.
The solution relies on the answer to a question - is it the responsibility of Attribute to validate attribute names? Currently the code uses Html::escape on the name attribute, and while this does prevent XSS attacks it also results in invalid attribute names which will cause rendering issues in some browsers and problems for Javascript.
If it is the Attribute class's responsibility to prevent this sort of attack then an outright test is required, with an exception object thrown on failure. If it is not Attribute's responsibility then we should still at least use a runtime assertion to assert() it is true and, further, track down the class in the code that is going to bear this responsibility. This is the sort of validation I'm not sure should be left for the Contrib modules to do, but then again how many of them deal in the creation of new attributes for output?
Disruptive Changes
Regardless of the solution, one test in Drupal\Core\Common\AttributesTest.php breaks because it is testing Html::escaping of attribute names which create escaped output that is an invalid attribute name. This test will need to be amended.
Contrib code should be safe because code creating invalid attributes will not be in a completely functional state anyway.
Comments
Comment #2
joelpittetI'd prefer the allow attributes to work with XML and not just be scoped for HTML, we did this in D7 and below with locking down to HTML and and D8 we can now generate much easier content that is not HTML, I'd like to keep this idea in mind.
Comment #3
Aki Tendo commentedThe only difference between the two I'm aware of is XML allows a colon in attribute names to namespace them. The regex I planned on using permits this.
And I agree, we need to support XML.
Comment #16
smustgrave commentedThank you for creating this issue to improve Drupal.
We are working to decide if this task is still relevant to a currently supported version of Drupal. There hasn't been any discussion here for over 8 years which suggests that this has either been implemented or is no longer relevant. Your thoughts on this will allow a decision to be made.
Since we need more information to move forward with this issue, the status is now Postponed (maintainer needs more info). If we don't receive additional information to help with the issue, it may be closed after three months.
Thanks!