ciprian
ciprian

Reputation: 443

a little question about XSS vulnerabilities

i want to use a css style switcher on a live server. i've been asking on irc and a guy said there is a big XSS hole. i don't know too much about XSS vulnerabilities. I hope someone can help me out to secure it!

i used this tutorial for the css switcher: http://net.tutsplus.com/tutorials/javascript-ajax/jquery-style-switcher/

and the guy said the vulnerability is on the PHP side of the script!

Any tips would be highly appreciated!

Also if someone could re-make the whole script in a more secure way because - please do many ppl from net.tutsplus.com who use it would thank you!

Upvotes: 0

Views: 932

Answers (3)

HoLyVieR
HoLyVieR

Reputation: 11134

The problem I see on this script is that there is a value that comes from the client $_COOKIE['style'] and is directly outputed in the page.

<link id="stylesheet" type="text/css" href="css/<?php echo $style ?>.css" rel="stylesheet" />

The cookie value is possible to highjack by external website in some particular condition. Also that cookie value is also set in the style-switcher.php without any filtering based on a GET parameter.

What I recommand you is to limit the possibility to style you want to be available.

Example :

<?php  
   if(!empty($_COOKIE['style'])) $style = $_COOKIE['style'];  
   else $style = 'day';  

   // List of possible theme //
   $listStyle = array('day', 'night', 'foobar');
   if (!in_array($style, $listStyle)) {
        $style = $listStyle[0];
   }
?> 

Upvotes: 7

bobince
bobince

Reputation: 536369

href="css/<?php echo $style ?>.css"

Every time you output a text string to HTML, you must use htmlspecialchars() on the value, otherwise out-of-band characters like <, & or in this case " will break out of the context (attribute value) and allow an attacker to insert arbitrary HTML into the page, including JavaScript content.

This in an HTML-injection hole, and you should fix it. However it is not yet directly an XSS vulnerability, because the source of $style is $_COOKIE. That cookie must have been set by your scripts, or by the user himself; unlike $_GET and $_POST values, it cannot be set on a user's browser by a third party. It only becomes a vulnerability if you allow a third party to cause the user's cookies to be set to arbitrary values.

However, style-switcher.php does exactly that:

$style = $_GET['style'];  
setcookie("style", $style, time()+604800);

with no checking to see that $style is an approved value, and no checking that the request to switch styles has been made by the user himself and not an arbitrary link on a third-party site: that is, it is vulnerable to XSRF. Say an attacker included a link or img src in a page visited by the user, pointing to:

http://www.example.com/style-switcher.php?style="><script>steal(document.cookie);</script>

that script will now be run each time the user loads a page from your site. (Technically, the ", ; and </> characters in this example need to be URL-encoded with %, but I've left it raw here for readability.)

(Also, you should really be using a POST form for this, since it has a side-effect action.)

What's worse, the same script contains a direct echoed injection which most definitely is XSS-vulnerable:

if(isset($_GET['js'])) {  
    echo $style;  
}

This hole allows arbitrary content injection. Although normally you will be expecting this script with js to be called by an XMLHttpRequest (via jQuery get()), there is nothing stopping an attacker calling it by linking a user to a URL like:

http://www.example.com/style-switcher.php?style=<script>steal(document.cookie);</script>&js=on

and in response they'll get their <script> echoed back in a page that, with no Content-Type header explicitly set, will default to text/html, causing JavaScript of the attacker's choosing to be executed in your site's security context.

header("Location: ".$_SERVER['HTTP_REFERER']);

This is not a good idea for other reasons. The Referer header is not guaranteed to make its way to your server. To ensure this works, pass the URL-to-return-to in a parameter to the script.

I probably wouldn't bother with the PHP side to this. I'd just set the relevant cookie from JavaScript and location.reload() or manipulate the stylesheet DOM to update. The PHP script is an attempt to make the switcher work without JavaScript, but unless you can be bothered to implement it properly and securely with XSRF protection, it is a liability.

If you include your alternative style sheets as <link rel="alternate stylesheet"> you'll be giving stylesheet switching support to users without JavaScript anyway.

Upvotes: 6

bcosca
bcosca

Reputation: 17555

Subject your app to a comprehensive security test to see where the holes are. Try Skipfish.

Upvotes: 0

Related Questions