138 lines
2.3 KiB
Plaintext
138 lines
2.3 KiB
Plaintext
==== Encode data according to the HTML context
|
|
|
|
The best approach to protect against XSS is to systematically encode data that is written to HTML documents.
|
|
The goal is to leave the data intact from the end user's point of view but make it uninterpretable by web browsers.
|
|
|
|
XSS exploitation techniques vary depending on the HTML context where malicious input is 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.
|
|
|
|
[options="header",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*: HTML output encoding will not 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*: HTML output encoding will not 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>
|
|
----
|
|
|===
|