In preparation for my upcoming talk at BSides SF about finding vulnerabilities, I would like to share today some insights regarding two common types of vulnerabilities which leverage web browser in two unique ways.
The goal of these vulnerabilities is quite different however. One is used to run untrusted code while the other is used to hijack authentication. The combined effect of these issues can be quite powerful.
Cross-site scripting, commonly referred to as XSS, is listed A3 in OWASP Top 10 2013 and was A2 in OWASP Top 10 for 2010 Web Application Security risks. Unlike SQL injection attacks which target data on the server, XSS provides a vector for attacking the users of a vulnerable web site.
At a general level, XSS is when an attacker can cause a web site to render with unintended script content. This script content is considered the payload of an XSS attack and can range from a simple pop-up window all the way to browser exploitation for remote code execution.
XSS occurs when a web application renders user controlled data without escaping special characters such as angle brackets (angle brackets designate hypertext markup unless they are escaped as < and > when sent to the browser).
Cross-site request forgery, commonly known as XSRF or CSRF, weighs in A 8 in the OWASP Top 10 for 2013, a considerable drop from A5 in the 2010 list. Similar to XSS, CSRF (pronounced sea-surf) uses an oversight in the design of a web application to attack users rather than actually attacking the server itself.
Successful exploitation of a CSRF vulnerability causes the web application to process an attacker-specified request within the context of the victim’s authenticated session. For a most basic example, let us consider a web-based payment system which allows users to transfer money between accounts specified as arguments to a PHP script.
Normally transfers happen when the user clicks a series of links instructing the site to transfer money but it is also possible to craft a URL which will perform the transfer. Specifically, browsing to http://vulnerable-site/transfer.php?acct_to=123456&amount=1337 while authenticated to the vulnerable-site will transfer $1337 from the user’s account to account number ‘123456’.
This works because the web browser includes authentication details with each request to http://vulnerable-site regardless of whether the URL was linked from another page or if the location were directly entered into the URL bar.
An attacker can use this behavior to their advantage in many ways but for this simple case, all that is needed is for the attacker to entice a victim to load an HTML document including <img src=http://vulnerable-site/transfer.php?acct_to=123456&amount=1337 height=0 width=0>.
When the browser attempts to load that resource, it passes along authentication (if present) and the web application will process the transfer without recognizing that the request did not originate from itself.
More complicated sites which make use of form data posts can also fall victim to CSRF attacks. For this situation, an attacker can clone a form from the vulnerable site, populate fields with values, and use JavaScript to automatically submit the form.
Often times, CSRF vulnerabilities can be exploited in unison with XSS vulnerabilities thereby elevating the risks associated with a CSRF attack. For example, when initially reviewing phpScheduleIt, I found that it did not implement CSRF protection and consequently an attack could perform a password reset via a crafted site.
Although this in itself can be considered as a moderately severe vulnerability, the problem is compounded by the fact that certain administrator-controlled input were not filtered for script content. In theory an attacker could then dupe an administrator into visiting a page which will forge a request to insert XSS useful for attacking other users.
Such injections could easily disclose any cookies used for authentication assuming they are not marked hostOnly. The BeEF (Browser Exploitation Framework) project does a great job of demonstrating how XSS can be used to glean information and launch attacks against client browsers.
Last year VERT evaluated a packet capture sharing application. Almost immediately I noticed that it is prone to XSS in a variety of places and meanwhile another VERT researcher, Ian, pointed out that the site was also prone to CSRF.
Putting these two aspects together, I was able to create a proof-of-concept exploit demonstrating that CSRF could be used to exploit an XSS vulnerability which is otherwise protected from the perspective of the web-based user interface.
What’s worse is that the XSS is inserted as if it came from the victim leaving the attacker potentially anonymous. This proof-of-concept was developed very quickly by leveraging Google Chrome’s development tools to identify the vulnerable web form and copy it to a fresh HTML document.
After copying the form it is just necessary to seed the form fields with the desired value attributes and add some JavaScript to submit the form. The resulting page can be loaded as an invisible IFRAME so that the user is unaware that they have submitted a request to the site. I will demonstrate this technique for testing CSRF at the upcoming BSides SF conference.
As previously mentioned, XSS vulnerabilities can be eliminated if proper precautions are made when handling user-controlled data. Over the years, several techniques have evolved for protecting against XSS within web application source code. One such defense is to prepare a white-list of allowable characters making sure to disallow markup characters such as the angle brackets (‘<’ and ‘>’).
Alternatively user-submitted data can be escaped so that unsafe characters are replaced with their safe counterparts. For example < instructs the browser to display the ‘<’ without interpreting it as a delimiter. Many programming languages even have built-in mitigations such as XSS filters which when used properly will recognize and remove or alter malicious content.
Protecting against CSRF however can require more fundamental changes to the architecture of a web site. One simple mitigation technique is to enforce an idle timeout so as to limit the window of opportunity for a CSRF. To properly solve CSRF however a secure web site must be able to validate that a request originated from itself rather than having been forged by a separate site.
Although it is possible to use the ‘HTTP Referer’ header to infer the origin of a request, some browsers may withhold the field and some proxy servers will not relay it (it is also possible in some circumstances for an attack page to forge HTTP headers) .
A more thorough solution is to supplement requests with a secure identifier which can be verified by the server but not forged by the attacker. This identifier is commonly referred to as a CSRF token and library implementations are available for a variety of web technologies.
XSS and CSRF are prevalent threats to the security of web 2.0 applications and are all too often misunderstood. What’s worse is when these issues are written off as unimportant because the risk is primarily to the user and not to the site operator.
If you are a web developer, I strongly encourage you to read up on mitigation techniques as well as to check your own applications for vulnerability. With so many tools and libraries available, it is not difficult to protect against these attack categories and it is often times even easier for an attacker to recognize the problems.
Read the Guide
Climbing Vulnerability Management Mountain
How to Build a Strong Vulnerability Management Program