-
Notifications
You must be signed in to change notification settings - Fork 33
Description
@craigfrancis wrote in #18.
I'd prefer the per-element custom config, rather than separate lists for tags and attributes.
But could it go a little further, so the attributes can specify the allowed content?
Short example:
{ 'div': { 'class': 'css-classes' }, 'a': { 'href': ['url', 'mailto'] // Not inline javascript }, '*': { 'title': 'string' } }Why add this extra complexity?
Some attributes can take safe and unsafe values, e.g. the a[href] accepting "javascript:"
You could give hashes for acceptable inline JS/CSS - personally I wouldn't allow 'unsafe-inline' code, but I have to accept that many websites do.
If unsafe attributes get added to the spec in the future, it would be nice for the developer to have clearly stated if they intended it to be a custom attribute (not realising that
data-*attributes exist), or if they intended to use the newly introduced attribute. For example, they might have<input ontap="myclick" />for their JS to read and work with, and a theoretical future browser could see that as some JS to run.This wouldn't be used by most systems, but for a theoretical complicated example:
{ 'a': { 'href': [ 'url', 'mailto', 'sha256-SOMTvqVfOViiCfDUw29p76/OVddUs0V7HyE0bATK3K8=' // For: javascript:alert() ], 'onclick': [ 'sha256-ZlNiuEKoYsR3vT5/phF5QQzmxOHlto0Qb7NgKx0WwV8=' // For: window.open(this.href); return false; ], }, 'input': { 'ontap': 'string', // Arbitrary string, if this becomes an unsafe attribute, the value is dropped. 'onfocus': 'unsafe-inline', // Arbitrary JS, danger, danger, avoid. 'onclick': [ 'sha256-biFQTroSCI3Z5BmsMGyEE2jFZdwjjG1Oe7JLytgH6jM=', // For: this.select() 'sha256-hphOYdb9WX9dW4pYcQdXa8E450mGtzl7k4kSIg1GOIo=' // For: this.value='' ], 'style': 'unsafe-inline', // Might need some more thoughts on this one. 'size': 'number' } }Where 'string' and 'unsafe-js' are effectively the same, but 'unsafe-js' will always be let though (the developer has explicitly stated they are happy with this risk, and it's easy for auditors to find); whereas 'string', will only be let though if the browser knows the attribute can accept this as a safe value (on the basis that the attribute may change in the future, or be added to the spec).