A cross-site scripting (XSS) hole is when an attacker can inject scripts into a page sent by your server in a way that gets them executed in the victim's browser.
For example, if http://www.yoursite.com/search?q=<script>alert(5)</script> returns "<p>There were no hits for <script>alert(5)</script>.</p>", your site is vulnerable to a simple XSS hole. If a malicious site links to such a URL, it can take control over the user's account on the site in several ways:
Internet Explorer supports a non-standard extension to HTTP cookies called HttpOnly. HttpOnly guards against the first version of XSS attacks, but only the first version, so you should not rely on HttpOnly to protect your site and visitors. Mozilla does not support HttpOnly (bug 178993).
Even on sites where users do not have accounts, XSS holes can be a problem. For example, intranet sites are automatically limited to users within the intranet, but XSS holes can allow outsiders to access them through the web browsers of employees.
& < > " 'as
& < > " '
\ / ' "as
For sites where the input is meant to be HTML (e.g. forum posts), escaping doesn't work. The best approach is to parse the input HTML on the server, keeping only tags, attributes, and attribute values you want to allow, then output the result as "well-formed" HTML. The naive approach of "stripping tags" with regular expressions often misses things. For example, the regular expression <.*?> matches nothing in "<script src='http://evil.com/evil.js' </script", leaving your Internet Explorer and Firefox visitors vulnerable (see bug 226495 and for details about "half-tag" parsing). Another example.
Things you should ensure are not allowed in forum posts to protect the accounts of visitors who use Firefox and IE:
If you must allow unsanitized user-posted HTML (web host, attachments in a bug-tracking system), ensure that those pages are not on the same hostname as where other users log in. For example, Hotmail gets this right.
CSRF vulnerabilities are typically in sites that use login cookies, but they can also exist in sites that allow changes based on IP addresses (such as intranet sites).
Do not rely on the Referer header to protect your visitors from CSRF. (Browser bugs and features allow web sites to create referrerless links, so you would have to reject referrerless form submissions. Some users choose to turn off referers, so you can't protect these users without preventing them from accessing your site at all. Some users even spoof their referer so it always appears to come from the site they are requesting a page from, making them impossible to protect in this way. Users that spoof referrers usually do so in order to access porn sites that restrict access to content solely based on referers.)
Since so few sites protect their visitors against CSRF attacks, we have discussed possible client-side fixes for CSRF. We didn't come up with anything good. For reference, see bug 38933, bug 40132, bug 246476, and bug 246519. At most, browsers might be able to prevent CSRFs from web sites to intranet sites, but not between web sites.
Don't load an untrusted site in a frame. The site will be able to load data into other frames, leading to a spoofing attack. If you visitors use Internet Explorer, don't use frames at all, because other sites can replace your site's frames. See bug 246448 for more infromation.
Don't put passwords (or any data that should remain private) in a URL if the page at that URL contains external links. When users click those links, the entire URL is sent as a referer. https sites are not safe, because links to other https sites include the full referer.
Firefox and Internet Explorer follow the DNS protocol, which allows bogus.attacker.com to resolve to an attacker's IP one minute and your server's IP the next. The "Princeton attack" takes advantage of this and has the same security impact as XSS. Intranet servers should check the Host header and return "400 Bad Request" if an unrecognized hostname is given. (The HTTP protocol requires HTTP servers to do this, but many do not.) For an extra layer of security, intranet firewalls should prevent DNS requests on external hostnames from resolving to internal IP addresses. Similarly, browsers, operating systems, and ISPs should all prevent external hostnames from resolving to 127.0.0.1. (See bug 162871, bug 174590, bug 205726, and 223861.)
If you're http://www.amazon.co.uk/, you should ignore cookies that are set for all of co.uk. We're working on disallowing sites from setting cookies on such domains (bug 252342).
If your page is designed to be displayed as an iframe on other sites, you may want specify a background color. If your page is displayed in an <iframe> and does not specify a background color, the background will be transparent, not white (bug 154957).
Even if you protect against traditional CSRF attacks, malicious sites may cause users to make changes on your site by making them click parts of your site unknowingly. Examples of attacks include sub-reaction-time page changes, pages that frame your site but cover all but an 8px-by-8px portion of the frame, and pages that frame your site and make the frame 100% transparent. Removing "One-click purchase" buttons is a partial solution, but I don't know if web sites can really solve this problem.
Web Services are subject to the web services security model. To enable this security model, create a file called /web-scripts-access.xml. If your site doesn't use web services, you shouldn't have to worry about this new security model.
After users log out, encourage them to close the browser window.
To prevent the back button from reaching private pages after the use has logged out of your site (but not closed the window), use cache-control. This will piss off your users, because it prevents the browser from going Back quickly and makes some browsers forget form information upon going Back.
To prevent the browser's "Save password?" dialog from appearing on misconfigured public computers, use the non-standard attribute autocomplete="off" on the form or password field. This will piss off home users, because they want their browsers to remember passwords for them. (They can use a bookmarklet to get around autocomplete=off, but most don't know that.)
Some security holes in web sites don't involve web browsers at all. Examples include directory traversal, buffer overflows, SQL injection, and forgetting to apply form access controls to both the page with the form and the cgi that handles the form. The Web Application Security Consortium's Threat Classification enumerates common server-side holes.
Don't let bug reports, especially reports of security holes, get lost in your customer service department before they reach your developers.