= Synopsis = Repeatedly, I see the same stupid login/authentication cross-site scripting mistake, over and over again, so I thought I'd tell everybody about it to try and remind people what not to do. = Background = == PMOS a POS == Check out the pmos help desk, here: [code] http://www.h2desk.com/pmos/demo/login.php [/code] Looks normal. Only a couple fields to enter data into, right? Not quite, there's a variable that we don't see right away. Click on a link in the header that looks like it might require authentication, say, tbe "Browse" link, like this: [code] http://www.h2desk.com/pmos/demo/browse.php [/code] The php is so smart it knows you haven't logged in yet. So what does it do? It gets smart -- it says, hey, I need you to login. So I'm going to send you to the login page. BUT, as an added convenience, I'm going to tell the login page to send you back at the end like this: [code] http://www.h2desk.com/pmos/demo/login.php?redirect=browse.php [/code] Isn't that nifty. Yes and no. Yes, it's nifty in that it's a cool design improvement, but no it's not in that it's another form of input into the system, one that isn't so carefully guarded because it'll never hit the SQL system. == An unsanitary problem == Let's download their source code and take a look at how they implemented it. I just went to: http://www.h2desk.com/pmos/ and clicked http://www.h2desk.com/pmos/pmos214.zip and opened up login.php. (Ignore their statement, "Also, please read the GPL license thoroughly. By no means can you use this code (or any of it) in your own product and sell it as your own -- that is completely illegal and will be prosecuted." -- This is false. The GPL lets you charge whatever you want for a product so long as you give them credit in the source files/changelog.) [code]
">
[/code] Ouch! No sanitation, whatsoever. They let you do pretty much whatever you want before you login (this is not so dangerous). But first, let's note the first problem in this code: [code] http://www.h2desk.com/pmos/demo/login.php?redirect=%22%3E%3Cscript%3Ealert(location.href)%3C/script%3E%3Ca [/code] (Note that the email input field is also XSSable (but via the POST method). It just puts that directly into the hidden field for the redirect, without sanitation -- classic XSS, but not so big a deal -- if you're on the login page your cookies probably aren't there to steal yet, if you have well-implemented session-only cookies -- which they don't (they just let them live for a whole month): [code] setcookie( "iv_helpdesk_login", $_POST[email], time( ) + 2592000 );. [/code] = Exploit = == Delivering the payload == If you need to inject code where quotes aren't allowed (magic quotes are enabled, for example!), you can, for example, use the document.referer property and setup your own site to download two different sets of data, one intended for the client, another for the server, so that when the server sees it they get needed payload. Here's a way that just decodes part of the url for the payload to avoid magic quotes altogether: [code] http://www.h2desk.com/pmos/demo/login.php?redirect=%22%3E%3Cscript%3Ealert(decodeURI(location.href.substr(132)))%3C/script%3E%3Ca&s=This%20is%20the%20payload [/code] (Tricks like this are why javascript should die.) == It gets worse from here == [code] if( trim( $_POST[redirect] ) != "" ) $redirect = $_POST[redirect]; else $redirect = $HD_URL_BROWSE; $EXTRA_HEADER = ""; $msg = "
Login successful. Redirecting you now. Click here if you aren't automatically forwarded...
"; $do_redirect = 1; [/code] Yep, they let you inject code _after_ login has succeeded, so if you want to make sure you get their auth data, just... let them login first before activating your payload (which you could carry over via document.referrer instead of document.location if it's not an encrypted link)! Note that, magic quotes _must_ be enabled for pmon to work. == Magic quotes and SQL == Futhermore, it's littered with magic-quotes-expecting SQL commands like: [code] $res = mysql_query( "SELECT * FROM {$pre}user WHERE ( email = '$_POST[email]' && password = '$_POST[password]' )" ); [/code] OUCH! = Conclusion = Yeah, stay away from the h2desk pmon code (no idea about their commercial offering though), as it's not a good example of quality, secure code.