2
votes

How would you use SafeHtml in combination with links?

Scenario: Our users can enter unformatted text which may contain links, e.g. I like&love http://www.stackoverflow.com. We want to safely render this text in GWT but make the links clickable, e.g. I like&amp;love <a="http://www.stackoverflow.com">stackoverflow.com</a>. Aside rendering the text in the GWT frontend, we also want to send it via email where the links should be clickable as well.

So far, we considered the following options:

  1. Store the complete text as HTML in the backend and let the frontend assume it's correctly encoded (I like&amp;love <a="http://www.stackoverflow.com">stackoverflow.com</a>) -> Introduces XSS vulnerabilities
  2. Store plain text but the links as HTML (I like&love <a="http://www.stackoverflow.com">stackoverflow.com</a>) in the backend and use HtmlSanitizer in the frontend
  3. Store plain text and special encoding for the links (I like&love [stackoverflow.com|http://www.stackoverflow.com]) in the backend and use a custom SafeHtml generator in the frontend

To us, the third option looks the cleanest but it seems to require the most custom code since we can't leverage GWT's SafeHtml infrastructure.

Could anybody share how to best solve the problem? Is there another option that we didn't consider so far?

1
How about storing HTML and using HtmlSanitizer? - Thomas Broyer
Thomas - May actually be very good idea. We just wondering if storing in HTML may lead in the long run to issues if we need to use the data for something else than outputting as HTML... (which is not completely unlikely). - Ron

1 Answers

2
votes

Why not store the text exactly as it was entered by the user, and perform any special treatment when transforming it for the output (e.g. for sending emails, creating PDFs, ...). This is the most natural approach, and you won't have to undo any special treatment e.g. when you offer the user to edit the string.

As a general rule, I would always perform encoding/escaping/transformation only for the immediate transport/storage/output target. There are very few reasons to deviate from this rule, one of them may be performance, e.g. caching a transformed value in the DB. (In these cases, I think it's best to give the DB field a specific name like 'text_htmltransformed' - this avoids 'overescaping', which can be just as harmful as no escaping.)

Note: Escaping/encoding is no replacement for input validation.