Skip to content
This repository has been archived by the owner on Sep 11, 2024. It is now read-only.

Allow [bf]g colors for <font> style attrib #610

Merged
merged 9 commits into from
Mar 3, 2017

Conversation

lukebarnard1
Copy link
Contributor

@lukebarnard1 lukebarnard1 commented Jan 11, 2017

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.

Fix for element-hq/element-web#2460.

Luke Barnard and others added 3 commits January 11, 2017 16:35
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.
@Half-Shot
Copy link
Contributor

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 p, span and other tags?

@lukebarnard1
Copy link
Contributor Author

@Half-Shot there's no reason really, but I don't see any reason to use p or span. AFAIK p would look slightly different but I'm not sure that's useful.

@Half-Shot
Copy link
Contributor

Half-Shot commented Feb 9, 2017

Fair enough. p is probably a bit useless, but I can see myself using span. font is technically not supported anymore and span is the closest thing to a replacement.

@lukebarnard1
Copy link
Contributor Author

2017-02-09-170946_597x449_scrot

ah.. I see what you mean

@Half-Shot
Copy link
Contributor

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

@lukebarnard1
Copy link
Contributor Author

Using <span> seems sensible!

@lukebarnard1
Copy link
Contributor Author

lukebarnard1 commented Feb 22, 2017

IRL @ara4n and @kegsay have said that we should stick with <font>. And I can't remember why...

@Half-Shot
Copy link
Contributor

I assume there are good reasons, but that kinda sucks 🙁

@ara4n
Copy link
Member

ara4n commented Feb 22, 2017

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?)

@ara4n
Copy link
Member

ara4n commented Feb 22, 2017

@kegsay do you remember?

@kegsay
Copy link
Member

kegsay commented Feb 22, 2017

Previously, clients could send colours in one of two ways, <font> or CSS. CSS would get sanitized out by most clients, so <font> was preferable. If we are now not sanitizing some CSS, then there's no reason to restrict the tag to <font> only.

@Half-Shot
Copy link
Contributor

Previously, clients could send colours in one of two ways, or CSS. CSS would get sanitized out by most clients, so was preferable. If we are now not sanitizing some CSS, then there's no reason to restrict the tag to only.

Mm, I remember that was the reason a long time back. This should hopefully fix all that and I can haz <span>? 😇

@lukebarnard1
Copy link
Contributor Author

@kegsay so I suppose this can be done for all tags then?

@kegsay
Copy link
Member

kegsay commented Feb 27, 2017

Yes.

@lukebarnard1
Copy link
Contributor Author

\o/ /me implements..

src/HtmlUtils.js Outdated

const pairs = attribs.style.split(';');
let sanitisedStyle = "";
for (let i = 0; i < pairs.length; i++) {
Copy link
Member

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.

Copy link
Contributor Author

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?

@lukebarnard1
Copy link
Contributor Author

So IRL, we discussed that we shouldn't be writing our own CSS sanitizer and using a custom data attribute (data-mx[-bg]-color) would be better because then we only have to spec that and not the slimmed-down CSS that we would inevitably have to spec otherwise.

This keeps things simple: remove style and transform the custom data attributes to CSS. Then we only allow hex #RRGGBB style colours.

Luke Barnard added 2 commits March 2, 2017 11:36
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;
Copy link
Member

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 :)

Copy link
Contributor Author

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.

@dbkr dbkr assigned lukebarnard1 and unassigned dbkr Mar 2, 2017
@lukebarnard1 lukebarnard1 assigned dbkr and unassigned lukebarnard1 Mar 2, 2017
@dbkr dbkr assigned lukebarnard1 and unassigned dbkr Mar 2, 2017
@lukebarnard1 lukebarnard1 merged commit 6a007d0 into develop Mar 3, 2017
@@ -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}/;
Copy link
Member

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

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants