-
-
Notifications
You must be signed in to change notification settings - Fork 833
Allow [bf]g colors for <font> style attrib #610
Conversation
Instead of dropping the style attribute on `<font>` tags entirely, sanitise aggressively and only keep `background-color` and `color` keys, and also sanitise the values to prevent `url(XXXXXX)` and `expression(XXXXXX)` type XSS attacks.
Is there a reason why it's limited to font? Historically it was just because that was the only way of making colours, but I don't see why we can't do this for |
@Half-Shot there's no reason really, but I don't see any reason to use |
Fair enough. |
Mm. What I was saying is that font was only used because it was a convenient way of avoiding CSS while doing styling. I don't think it should be used now we can avoid it :P |
Using |
I assume there are good reasons, but that kinda sucks 🙁 |
i can't remember why either tbh. perhaps we just shift to span for both (or is that going to run up against HTML sanitizer problems?) |
@kegsay do you remember? |
Previously, clients could send colours in one of two ways, |
Mm, I remember that was the reason a long time back. This should hopefully fix all that and I can haz |
@kegsay so I suppose this can be done for all tags then? |
Yes. |
\o/ /me implements.. |
src/HtmlUtils.js
Outdated
|
||
const pairs = attribs.style.split(';'); | ||
let sanitisedStyle = ""; | ||
for (let i = 0; i < pairs.length; i++) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hand-sanitizing CSS like this scares me quite a lot. In this instance it feels quite fragile, and will fail if there's any white-space in the expression? which feels wrong, given whitespace is valid in CSS so we're defining our own custom derivative of CSS here which is generally bad karma.
However, in the longer term, we probably do want users to be able to enter CSS into their HTML messages in order to get pixel-perfect layout (and hopefully sandboxing tech will have caught up by then to ensure we can render the contents in some kind of sandbox to protect the rest of the app from it). So i guess it's not that bad here... as long as the sanitizer is neither to lax nor too strict.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hand-sanitizing CSS like this scares me quite a lot
Should we look into a library that does this instead?
will fail if there's any white-space in the expression
defining our own custom derivative of CSS
Agreed that we shouldn't reinvent the wheel here, but the rationale was to be super strict such as not to allow any possibility of url(...)
or expression(...)
. This will inevitably end up being are own version of CSS but are we not already doing that with HTML?
So IRL, we discussed that we shouldn't be writing our own CSS sanitizer and using a custom data attribute ( This keeps things simple: remove |
This has the benefit of not needing a spec for custom CSS. Instead we rigourously sanitise the values for custom data attributes that are transformed to CSS equivalents. `data-mx-color` translates to CSS `color` for example.
src/HtmlUtils.js
Outdated
@@ -136,6 +138,37 @@ var sanitizeHtmlParams = { | |||
attribs.rel = 'noopener'; // https://mathiasbynens.github.io/rel-noopener/ | |||
return { tagName: tagName, attribs : attribs }; | |||
}, | |||
'*': function(tagName, attribs) { | |||
// Delete any style previously assigned | |||
delete attribs.style; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Doesn't this make allowing style above pointless? If not, probably needs a comment as to why not :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Transforming is done before attributes are stripped (sensibly). I shall comment.
@@ -28,6 +28,7 @@ emojione.imagePathSVG = 'emojione/svg/'; | |||
emojione.imageType = 'svg'; | |||
|
|||
const EMOJI_REGEX = new RegExp(emojione.unicodeRegexp+"+", "gi"); | |||
const COLOR_REGEX = /#[0-9a-fA-F]{6}/; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Woah there! Careful!
> r = /#[0-9a-fA-F]{6}/
/#[0-9a-fA-F]{6}/
> r.test("url(https://evil.com)/*#ffffff*/")
true
You need to use start and end symbols!
> r = /^#[0-9a-fA-F]{6}$/
/^#[0-9a-fA-F]{6}$/
> r.test("url(https://evil.com);/*#ffffff*/")
false
> r.test("#ffffff")
true
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Instead of dropping the style attribute on
<font>
tags entirely, sanitise aggressively and only keepbackground-color
andcolor
keys, and also sanitise the values to preventurl(XXXXXX)
andexpression(XXXXXX)
type XSS attacks.Fix for element-hq/element-web#2460.