XSS is mainly associated with HTML escaping (*). Every time you take a line of plain text and put it in an HTML page, regardless of whether the text is from a database, directly from user input, from a file, or from another place entirely, you need to avoid it.
The minimum HTML escape is to convert all & characters to & and all the characters < in < . When you put something in the attribute value, you will also need to escape the quotation mark, which is used to delimit the attribute, usually " before " There is no harm in always avoiding both quotation marks ( " and the single quote apostrophe ' ), and some people also go from > to > although this is only necessary for one case in XHTML. p>
Any good web-based language should provide a feature that does this for you. For example, in PHP, this is htmlspecialchars() :
<p> Hello, <?php htmlspecialchars($name); ?>! </p>
and in Smarty, the escape modifier:
<p> Hello, {$name|escape:'html'}! </p>
in fact, since HTML escaping is what you want 95% of the time (relatively rare to allow HTML markup to be enabled), this should have been the default. Newer template languages have learned that refusing HTML crawl is a huge bug that causes endless XSS holes, so HTML will come out by default.
You can make Smarty behave like this by changing the default modifiers to html . (Do not use htmlall as they offer this if you really don't know what you are doing, or are likely to mess up all your non-ASCII characters.)
No matter what you do, do not fall into the common PHP error for HTML escaping or "disinfection" for HTML input, before it is processed or put into the database. This is the wrong place to encode the output stage and will give you all kinds of problems. If you want to check your input to make sure that it is the expected specific application, then it’s fine, but clipping or escaping “special” characters at this stage is inappropriate.
*: Other aspects of XSS are present when (a) you really want to allow users to send HTML files, in which case you must destroy them to acceptable elements and attributes, which is a complex process usually performed by a library such as HTML Purifier, and even then there were holes. Alternative, simpler layout schemes may help. And (b) when you allow users to upload files, which is very difficult to make secure.