Skip to content

[Form] Over-sanitization of form's id attributes #53976

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
ThomasLandauer opened this issue Feb 16, 2024 · 10 comments · May be fixed by #53981
Open

[Form] Over-sanitization of form's id attributes #53976

ThomasLandauer opened this issue Feb 16, 2024 · 10 comments · May be fixed by #53981

Comments

@ThomasLandauer
Copy link
Contributor

Symfony version(s) affected

7.0.3

Description

For HTML4 compliance, numbers are stripped from a form's block prefix when creating the id attribute of the HTML elements.
However, in HTML5 those restrictions don't apply anymore, see https://html.spec.whatwg.org/multipage/dom.html#the-id-attribute

When specified on HTML elements, the id attribute value must be unique amongst all the IDs in the element's tree and must contain at least one character. The value must not contain any ASCII whitespace.

There are no other restrictions on what form an ID can take; in particular, IDs can consist of just digits, start with a digit, start with an underscore, consist of just punctuation, etc.

So I suggest to adjust the sanitizing, or (probably easier) drop it completely and leave it in the responsibility of the user to set a valid block prefix.

How to reproduce

Setup a form with:

public function getBlockPrefix(): string
{
    return '1-foo';
}

The resulting field looks like this:

<input type="email" id="-foo_email" name="1-foo[email]">

(Side note: Starting an id with - was also not valid in HTML4)

Possible Solution

The sanitizing is happening in BaseType::buildView()

Additional Context

No response

@xabbuh
Copy link
Member

xabbuh commented Aug 5, 2024

I am 👎 on doing this change. If we stopped sanitising ids, the rendered HTML would change with the next update potentially breaking applications as CSS selector may not be applied anymore. I don't think that's worth the hassle.

@ThomasLandauer
Copy link
Contributor Author

I see your point about the hassle. But keeping it like it is (i.e. over-patronizing) forever, isn't good either...

About breaking existing implementations, let's look at the full scenario: When you try to use something like 1-foo as id, and then notice that it's being sanitized to -foo: Would you then happily write a CSS selector of #-foo?? I bet everybody would go back and change the id!
So I doubt that changing it would really affect somebody in userland.

@xabbuh
Copy link
Member

xabbuh commented Aug 5, 2024

But keeping it like it is (i.e. over-patronizing) forever, isn't good either...

Why? What is the disadvantage of not being able to use everything as an id?

When you try to use something like 1-foo as id, and then notice that it's being sanitized to -foo: Would you then happily write a CSS selector of #-foo?? I bet everybody would go back and change the id!

I have seen enough teams where the people doing writing the CSS are not the same people that write the form types and that don't even know where the id is coming from. In those cases they will simply copy the id that they see in the HTML and reuse that in their CSS selectors.

@ThomasLandauer
Copy link
Contributor Author

Disadvantage: Well, just like any restriction... If using uppercase letters in variable names would be forbidden, you could surely cope with it too. But it would be annoying.
I had a real use case where an id like 1-foo would have been handy for JavaScript (split at -) - that's how I discovered this issue in the first place.

Teams: Gosh, indeed. But what I meant is: Nobody uses such a weird string as id just for fun. They certainly have some further processing in mind (like my JavaScript), and if they see that it doesn't work out, they'll probably change it back.

But I agree that some users will be affected (in my estimate only a handful), so it would be a BC break. But adding it to v8.0 seems fine to me.

@xabbuh
Copy link
Member

xabbuh commented Aug 5, 2024

But adding it to v8.0 seems fine to me.

This would still require a deprecation in 7.x.

@ThomasLandauer
Copy link
Contributor Author

What would you wanna write?:

Relying on the over-sanitation of weird strings is deprecated...

lol

Seriously, this only affects the generated HTML output of forms, right? How were changes like this handled in the past? Since this is not something the user is actively doing, I don't think it can be deprecated.

@derrabus
Copy link
Member

derrabus commented Aug 5, 2024

What would you wanna write?:

Relying on the over-sanitation of weird strings is deprecated...

lol

@xabbuh raised the valid concern of backwards compatibility. What you are proposing is a change of behavior and there might be projects our there that rely on that very behavior. I think, his remark deserves a respectful answer.

Since this is not something the user is actively doing, I don't think it can be deprecated.

You can make the behavior configurable and trigger a deprecation if the app did not opt-in to the new behavior and the new behavior would produce a different result than the old one.

@ThomasLandauer
Copy link
Contributor Author

lol = laughing out loud = joke
The respectful answer was immediately below.

My question was: I'm sure the HTML rendering of forms (or of anything else) has been changed in the past. How were these changes handled? I bet you didn't create a new configuration option for each minor change ;-)

@xabbuh
Copy link
Member

xabbuh commented Aug 5, 2024

I don't remember that we did a change with a similar potential impact in the past.

@derrabus
Copy link
Member

derrabus commented Aug 5, 2024

I bet you didn't create a new configuration option for each minor change

How's this a "minor change" again? You already admitted that it would be a BC break and suggested to ship it with the next major release.

If you want to change behavior in an incompatible manner, create a way to opt-in to the new behavior and make it the default in the next major. This is the way.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants