1

The common thing to do in defense against XSS, stored or not, is to HTML-encode the payload. Encoding upon the upload/POST of the data is efficient for processing power and neutralizes it early to be stored in the database but the payload becomes active and dangerous for a long time if the upload defense is somehow bypassed. Encoding upon retrieval or displaying of the payload means the data can be stored as is in the database, saving a few bytes, and while a weak defense on 1 page/endpoint can be bypassed, there's no need to worry about storing and removing raw XSS payloads. So far, I think encoding upon storage sounds better.

Is there a consensus on when the HTML elements should be HTML-encoded?

2
  • 1
    What kind of data you are talking about? Is this about plain text or text with HTML (or other) formatting? And in which contexts the data should be used, i.e. inside plain HTML only or inside HTML tag attributes, inside script tags, for mailings ... Different contexts require different encodings. Commented Apr 10, 2022 at 6:08
  • you don't really even have to encode them if you don't serve the content as text/html content-type. you can inject them as plain text fetched from a web service call and decorate it on the client. Still, it's probably better to accept markdown or wiki or plain than HTML if you need user-formatting.
    – dandavis
    Commented Apr 10, 2022 at 9:06

1 Answer 1

4

Encoding/escaping should happen as late as possible. HTML encoding is typically performed by template engines, and these typically encode all variables unless explicitly told that the data is already safe. This is the safest approach because it requires the least effort on the part of the software developer. Storing already-encoded data is problematic because later use of this data has to trust that it's truly safe, which might require disabling security features like auto-escaping.

It is also impossible to encode data up front so that it can be safely used in all contexts. Including data in a HTML text node has different escaping rules from HTML attributes, which are different from <style> tags which are different from <script> tags which are different from <textarea> tags which are different from JavaScript strings which are different from SQL values which are different from URL parameters which are different from quoted-printable emails.

Thus, to avoid confusion, an application must handle "raw" data as much as possible, without committing to a particular interpretation of the data until it is actually necessary. Encoding should happen at the system boundaries. Incoming data is decoded into whatever format the application wants to use internally (e.g. a UTF-8 string representing plain text). Outgoing data is encoded in whatever way required by that particular context.

Many applications that escape too early forget to unescape when appropriate, leading to artefacts like showing &quot;foo&quot;, &amp;quot;foo&amp;quot;, \"foo\", or even \&quot;foo\&quot; for an input text like "foo". This is the HTML equivalent to the mojibake phenomenon when confusing different text encodings.

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .