112 lines
2.2 KiB
Plaintext
112 lines
2.2 KiB
Plaintext
![]() |
==== Encode data according to the HTML context
|
||
|
|
||
|
The best approach to protect against XSS is to systematically encode data that are written to HTML documents.
|
||
|
The goal is to leave the data intact from the end user's point of view but makes it uninterpretable by web browsers.
|
||
|
|
||
|
XSS exploitation techniques vary depending on the HTML context where malicious inputs are injected. For each HTML context, there is a specific encoding to prevent JavaScript code from being interpreted.
|
||
|
The following table summarizes the encoding to apply for each HTML context.
|
||
|
|
||
|
[cols="a,a,a,a"]
|
||
|
|===
|
||
|
| Context
|
||
|
| Code example
|
||
|
| Exploit example
|
||
|
| Encoding
|
||
|
|
||
|
|
||
|
| Inbetween tags
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<div>{ data }</div>
|
||
|
----
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<div><script>alert(1)</script></div>
|
||
|
----
|
||
|
|
|
||
|
HTML entity encoding: replace the following characters by HTML-safe sequences.
|
||
|
|
||
|
* & -> \&
|
||
|
* < -> \<
|
||
|
* > -> \>
|
||
|
* " -> \"
|
||
|
* ' -> \'
|
||
|
| In an attribute surrounded with single or double quotes
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<div tag="{ data }">...</div>
|
||
|
----
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<div tag="" onmouseover="alert(1)">...</div>
|
||
|
----
|
||
|
|
|
||
|
HTML entity encoding: replace the following characters with HTML-safe sequences.
|
||
|
|
||
|
* & -> \&
|
||
|
* < -> \<
|
||
|
* > -> \>
|
||
|
* " -> \"
|
||
|
* ' -> \'
|
||
|
| In an unquoted attribute
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<div tag={ data }>...</div>
|
||
|
----
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<div tag=foo onmouseover=alert(1)>...</div>
|
||
|
----
|
||
|
| *Dangerous context*: no output encoding will prevent XSS fully.
|
||
|
|
||
|
|
||
|
| In a URL attribute
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<a href="{ data }">...</a>
|
||
|
----
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<a href="javascript:alert(1)">...</a>
|
||
|
----
|
||
|
| Validate the URL by parsing the data. Make sure relative URLs start with a `++/++` and that absolute URLs use `++https++` as a scheme.
|
||
|
|
||
|
| In a script block
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<script>{ data }</script>
|
||
|
----
|
||
|
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<script>alert(1)</script>
|
||
|
----
|
||
|
| *Dangerous context*: no output encoding will prevent XSS fully.
|
||
|
To pass values to a JavaScript context, the recommended way is to use a data attribute:
|
||
|
|
||
|
[source,html]
|
||
|
----
|
||
|
<!doctype html>
|
||
|
<script data="{ data }">...</script>.
|
||
|
----
|
||
|
|===
|