When the user clicks on the link, an HTTP request is sent by the user’s browser to the trusted.com web server, requesting the page
The trusted.com web server receives the request and checks if it has the resource which is being requested. When the trusted.com host does not find the requested page, it will return an error message. The web server may also decide to include the requested file name in the return message to specify which file was not found. If this is the case, the file name (which is actually a script) will be sent from the trusted.com webserver to the user’s browser and will be executed in the context of the trusted.com origin. When the script is executed, the cookie set by trusted.com will be sent to the malicious website as a parameter to the invocation of the steal-cookie.php server-side script. The cookie will be saved and can later be used by the owner of the evil.com site to impersonate the unsuspecting user with respect to trusted.com.
The example above shows that it is possible to compromise the security of a user’s environment even though neither the sand-boxing nor the same-origin policy was violated. Unfortunately, vulnerabilities that can be exploited by XSS attacks are common. For example, by analyzing the Common Vulnerabilities and Exposures entries (including candidate entries) from 2001 to 2009, we identified 4541 cross-site scripting vulnerabilities. Note that this is only a partial account of the actual number of XSS vulnerabilities since there are a number of ad hoc web-based applications that have been developed internally by companies to provide customized services. Many of the security flaws in these applications have not yet been discovered or made public.
TYPES OF XSS ATTACKS
THE NOXES TOOL
Noxes is a Microsoft-Windows-based personal web firewall application that runs as a background service on the desktop of a user. The development of Noxes was inspired by Windows personal firewalls that are widely used on PCs and notebooks today. Popular examples of such firewalls are Tiny, ZoneAlarm, Kerio, and Norton Personal Firewall. Personal firewalls provide the user with fine-grained control over the incoming connections that the local machine is receiving and the outgoing connections that running applications are making. The idea is to block and detect malware such as worms and spyware, and to protect users against remotely exploitable vulnerabilities. Personal firewalls are known to be quite effective in mitigating certain types of security threats such as exploit-based worm outbreaks.
Typically, a personal firewall prompts the user for action if a connection request is detected that does not match the firewall rules. The user can then decide to block the connection, allow it, or create a permanent rule that specifies what should be done if such a request is detected again in the future. Although personal firewalls play an essential role in protecting users from a wide range of threats, they are ineffective against web-based client-side attacks, such as XSS attacks. This is because, in a typical configuration, the personal firewall will allow the browser of the user to make outgoing connections to any IP address with the destination port of 80 (i.e., HTTP) or 443 (i.e., HTTPS). Therefore, an XSS attack that redirects a login form from a trusted web page to the attacker’s server will not be blocked. Noxes provides an additional layer of protection that existing personal firewalls do not support. The main idea is to allow the user to exert control over the connections that the browser is making, just as personal firewalls allow a user to control the Internet connections received by or originating from processes running on the local machine. Noxes operates as a web proxy that fetches HTTP requests on behalf of the user’s browser. Hence, all web connections of the browser pass through Noxes and can either be blocked or allowed based on the current security policy.
Analogous to personal firewalls, Noxes allows the user to create filter rules (i.e., firewall rules) for web requests. There are three ways of creating rules:
Manual creation. The user can open the rule database manually and enter a set of rules. When entering a rule, the user has the possibility of using wild cards and can choose to permit or deny requests matching the rule. For example, a permit rule like www.yahoo.com* allows all web requests sent to the domain www.yahoo.com, while a deny rule such as www.tuwien.ac.at/images* blocks all requests to the ‘‘images’’ directory of the domain www.tuwien.ac.at.
Firewall prompts. The user can interactively create a rule whenever a connection request is made that does not match any existing rule, in a way similar to what is provided by most personal firewalls. For example, if no rule exists for the request www.news.yahoo.com/index.html, the user is shown a dialog box to permit or deny the request. The user can also use a pop-up list for creating a rule from a list of possible general rules such as www.news.yahoo.com/*, *.news.yahoo.com/* or *.yahoo.com/*. In addition, the user can specify if the rule being created should be permanent or should just be active for the current browsing session only. Temporary rules are useful for websites that the user does not expect to visit often. Hence, having temporary rules helps prevent the rule-base from growing too large, and at the same time reduces the number of prompts that the user will receive because of web requests to unknown websites.
Snapshot mode. The user can use the special snapshot mode integrated into Noxes to create a ‘‘browsing profile’’ and automatically generate a set of permit rules. The user first starts by activating the snapshot mode and then starts surfing. When the snapshot mode is activated, Noxes tracks and collects the domains that have been visited by the browser. The user can then automatically generate permanent filter rules based on the list of domains collected during a specific session. Note that after new rules have been created, the user can modify or delete the rules as she sees fit.
DETECTING XSS ATTACKS
Unfortunately, a web firewall as described previously is not particularly usable in practice because it raises an unacceptably large number of alerts and requires excessive user interaction. Consider the example of a user that queries a search engine to find some information about a keyword and has received a list of relevant links. Each time the user selects one of the links, she is directed to a new, possibly unknown website and she is prompted for action. Clearly, it is cumbersome and time-consuming for the user to create many new rules each time she searches for something. Unlike a personal firewall, which will have a set of filter rules that do not change over a long period of time, a personal web firewall has to deal with filter rule sets that are flexible; a result of the highly dynamic nature of the web.
In a traditional firewall, a connection is opened to an unknown port by a previously unknown application is clearly a suspicious action. On the web, however, pages are linked to each other and it is perfectly normal for a web page to have links to web pages in domains that are unknown to the user. Hence, a personal web firewall that should be useful in practice must support some optimization to reduce the need to create rules. At the same time, the firewall has to ensure that security is not undermined. An important observation is that all links that are statically embedded in a web page can be considered safe with respect to XSS attacks. That is, the attacker cannot directly use static links to encode sensitive user data. The reason is that all static links are composed by the server before any malicious code at the client can be executed. An XSS attack, on the other side, can only succeed after the page has been completely retrieved by the browser and the script interpreter is invoked to execute malicious code on that page. In addition, all local links can implicitly be considered safe as well. An adversary, after all, cannot use a local link to transfer sensitive information to another domain; external links have to be used to leak information to other domains.
Based on these observations, we extended our system with the capability to analyze all web pages for embedded links. That is, every time Noxes fetches a web page on behalf of the user, it analyzes the page and extracts all external links embedded in that page. Then, temporary rules are inserted into the firewall that allows the user to follow each of these external links once without being prompted. Because each statically embedded link can be followed without receiving a connection alert, the impact of Noxes on the user is significantly reduced. Links that are extracted from the web page include HTML elements with the href and src attributes and the URL identifier in Cascading Style Sheet (CSS) files. The filter rules are stored with a timestamp and if the rule is not used for a certain period of time, it is deleted from the list by a garbage collector.
When Noxes receives a request to fetch a page, it goes through several steps to decide if the request should be allowed. It first uses a simple technique to determine if a request for a resource is a local link. This is achieved by checking the Referer HTTP header and comparing the domain in the header to the domain of the requested web page. Domain information is determined by splitting and parsing URLs (the ‘‘.’’ character in the domain name is used for splitting). For example, the hosts client1.tucows.com and www.tucows.com will both be identified by Noxes as being in the domain tucows.com. If the domains are found to be identical, the request is allowed. If a request being fetched is not in the local domain, Noxes then checks to see if there is a temporary filter rule for the request. If there is a temporary rule, the request is allowed. If not, Noxes checks its list of permanent rules to find a matching rule. If no rules are found matching the request, the user is prompted for action and can decide manually if the request should be allowed or blocked.
RELIABILITY OF THE REFERER HEADER
Apart from the question of whether an attacker is able to modify the Referer header (which is not possible), another issue is under which conditions the Referer header is present in a request. According to the HTTP specification, this header is optional. However, all popular browsers such as Internet Explorer, Opera, and Mozilla make use of it. Note that the Referer header is regularly missing in a request in two cases:
- When a user manually types the target URL into the browser’s location bar
- When she clicks on a link inside an email
Some users have privacy concerns with regard to the Referer header since they do not wish to provide information to the target server about how they have reached this page. Such users tend to disable the transmission of the Referer header, a feature that is easily accessible in modern browsers. The solution to this problem is straightforward: Noxes could first re-enable the transmission of the Referer header in the browser and, as a result, would possess the information that is necessary for shielding the user against XSS attacks. To protect the user’s privacy, Noxes could then remove the Referer header from the request that is forwarded to the destination server. This way, both privacy and security requirements can be satisfied.
HANDLING POST REQUESTS
The explanations so far only applied to GET requests, in which the data to be transmitted is encoded as part of the URL. POST requests, which are typically generated by users who fill out and submit HTML forms, are treated by Noxes in a different way under certain conditions. For local requests, there is no difference in the handling of GET and POST requests: In accordance with the previous discussion of local links, Noxes allows all local POST requests to pass. However, if Noxes detects that a POST request is non-local (i.e., a cross-domain posting), it always prompts the user to verify whether this request was really intended.
One possibility for handling this issue would be to extend Noxes with a tool integrated into the browser that can detect whether a POST request contains dynamic data. Such an extension would only allow static information and input that was really typed in by the user to appear in a POST request. However, this solution comes with two drawbacks. First, some websites might be enhancing legitimate forms with dynamic features to improve user experience (e.g., Google Suggest), resulting in false alarms. Second, even in the absence of dynamic content, the user is still advised to check whether the target of the submitted form really corresponds to what she expected. For instance, an attacker could also statically mimic a login form that eventually sends the user’s password to evil.com (a case of phishing by exploiting an XSS vulnerability).
To summarize, the conservative treatment of cross-domain postings is justified by the following two arguments:
- Cross-domain postings occur very rarely in practice and are suspicious whenever they do occur.
- Automatically distinguishing between legitimate and illegitimate POST requests is, so far, an unsolved problem.
MITIGATING ADVANCED XSS ATTACKS
BINARY ENCODING ATTACKS
Links that are statically embedded in an HTML page were considered safe. Unfortunately, this approach suffers from a security vulnerability. To see this, consider an attacker that embeds a large number of specially crafted, static links into the web page of the trusted site (in addition to the malicious script). Then, when the script is executed in the client’s browser, these links can be used to encode sensitive information. For example, the script could execute a simple loop to send cookie or session ID information bit-by-bit to a server under the attacker’s control, using one previously embedded static link for each bit. Suppose that the cookie consists of 100 bits. The attacker first inserts 100 unique pairs of static image references to her own domain (lines 3–9). The image references need to be unique because Noxes creates a temporary rule for each URL and promptly deletes it once it has been used. In the next step of the attack, the attacker goes through the cookie value bit-by-bit and uses the static references she has previously embedded to ‘‘encode’’ the sensitive information (lines 11–23). Because the attacker only uses static references in the page, the corresponding requests would be allowed by Noxes’ temporary rule set. As a consequence, the attacker can reconstruct the cookie value one bit at a time by checking and analyzing the logs of the web server at evil.com.
To address this type of XSS attack, an earlier version of Noxes takes the following measures: it only allows a maximum of k links to the same external domain, where k is a customizable threshold. If there are more than k links to an external domain on a page, none of them will be allowed by Noxes without user permission. Hence, each successful attack in which two links are used to encode a single bit value (one link to represent that this bit is 0, one link to represent that this bit is 1) will be able to leak only k/2 bits of sensitive information. For example, when k is 4, the attacker would have to make the victim visit at least 50 vulnerable pages to successfully steal a cookie that consists of 100 bits (leaking 4=2 ¼ 2 bits per page visit). Clearly, such an attack is very difficult to perform. Note that an alternative for the attacker would be to send a request for a bit only when its value is 1. If the bit is 0, the absence of a request can be used to infer the correct value. This way, he could reduce the number of vulnerable pages that the victim would have to visit from 50 to 25, which would still be a very difficult challenge for the attacker.
ATTACKS BASED ON N-ARY ALPHABETS
In binary encoding attacks, every link provided by the attacker is used to represent one bit. However, there is an even more advanced type of encoding-based attack in which the amount of information that is transmitted by a single link can be larger than just one bit. Intuitively, this can be demonstrated by the following extreme example: an attacker could inject a huge number of different static links into the vulnerable page, such that each link corresponds to a complete cookie value. This way, it would be sufficient for the attacker to issue just a single request in order to steal the complete cookie. Hence, one link would encode far more than just one bit of information. Of course, the enormous number of links that need to be injected for that purpose makes this particular attack infeasible.
Consider a smaller example
An attacker manages to inject eight static links (denoted as a through h) pointing to her own domain. If the attacker issues just one request to one of these targets, she can use the following mapping between the selected link and the transferred bits: a1000, b1001, c1010, and h1111. Hence, one link is capable of encoding three bits instead of one. Analogously, if the attacker chooses to issue two requests (such as ac or hb), a combination of two links is able to encode 56 distinct values (since there are 56 possibilities for choosing two elements from an eight-element set). This corresponds to an information amount of 5.8 (ld(56)) bits that can be transmitted with two requests. Note that since Noxes deletes a temporary rule for a static link after it has been used, the attacker cannot issue requests such as aa or cc. Moreover, the order of the requests is relevant (that is, ab encodes a different value than ba). In this sense, the links injected by the attacker represent the symbols of an alphabet for transmitting information, where each symbol can be used only once. This implies that an upper bound for the amount of information that can be transmitted via rd requests given an alphabet of nd static links to the attacker’s domain d is equal to:
The corresponding number of bits that can be leaked is computed as ld(Id). Note that Equation 1 represents the combinatorial formula that calculates the number of permutations (Id, in this case) of objects without repetition. Note that, in theory, it might be possible for the attacker to further increase the amount of information that is encoded by one link. The attacker could, for example, attempt to use timing information to encode bit values, issuing a request exactly at 12:22 to express a value of 01101010. In this case, the main difficulty for the attacker is that the clocks between the computers have to be synchronized. Hence, such an attack is extremely difficult to launch. These covert channel attacks are beyond the scope of our work, especially considering that most XSS attacks are launched against a large number of random users. However, our proposed technique makes such attacks more difficult, and, thus, it raises the bar for the attacker in any case.
DYNAMICALLY ENHANCED PROTECTION MECHANISM
With the explanations given in the previous section, we are now able to construct an enhanced protection mechanism based on the following observation: Even if a page contains more than k links to some external domain, it might still be safe for the user to click a small number of these links without leaking too much information. For instance, if there are eight external links, the user would only leak 3 bits when issuing the first request to this domain. Hence, it is overly conservative to prompt the user already for this first request (as the amount of information that can leak is limited). The question is, however, how many requests shall Noxes allow before issuing a warning? To answer this question, we can simply use Equation 1 from the previous section. With a given number of static links to an attacker’s domain and a (customizable) amount of information that we accept to be leaked, we can compute the number of requests that Noxes should allow to this domain. For example, assume that Noxes detects eight static links to the same external domain, and we do not wish that more than eleven bits of the user’s cookie leak to this domain. This enhanced approach has a clear advantage compared to the previous k-threshold technique.
For instance, if a page contains eight static links to an external domain, the previous technique (with a threshold value of k ¼ 4) would not allow the user to click any of these links without being prompted. Now, as mentioned, we can compute that it is safe for the user to click four of these links without risking that a significant fraction of her cookie is leaked. Thus, we are able to further increase the usability of Noxes by reducing the number of prompts that the user is confronted with. This enhancement is achieved by supplementing the previous static analysis of links contained in server replies with two mechanisms: The dynamic computation of the maximum number of permitted requests, and the observation of the requests actually performed.
Apart from an improvement in user experience, the mitigation technique presented in the previous section is also able to thwart multi-domain attacks. In the examples given so far, we have implicitly assumed that the attacker possesses only one domain that she can use as a destination for stealing information. However, an attacker could as well obtain multiple different domains. This way, she could keep her statically embedded links under the radar of our initial k-threshold approach. Since none of these domains is pointed to by more than four links, this attack would not be detected by the k-threshold approach.
A REAL-WORLD XSS PREVENTION EXAMPLE
Here, demonstrates the effectiveness of Noxes on a real-world vulnerability reported at the security mailing list Bugtraq. The vulnerability affects several versions of PHP-Nuke, a popular open-source web portal system. For the following test, we analyzed the vulnerable version 7.2 of PHP-Nuke and modified the harmless original proof-of-concept exploit to make it steal the victim’s cookie.
In a test environment, the server hosting PHP-Nuke was reachable at the IP address 184.108.40.206. The following exploit URL was used to launch a reflected XSS attack:
Hence, the victim is immediately redirected to evil.com’s page and her cookie is attached to the request as a parameter. Noxes prevents this redirection since the malicious target URL is not static, but has been constructed dynamically in order to pass along the cookie. Apart from this example, in our tests, Noxes also successfully prevented the exploitation of the following vulnerabilities listed at Bugtraq: 10524 (PHP-Nuke 7.2), 13507 (MyBloggie 2.1.1), and 395988 (MyBloggie 2.1.1).
Because we started the sniffer on the department Internet gateway and firewall server, we could be sure that we would see all web traffic generated by users of the department network. The captured web traffic in the dump files was around 30GB in size. We implemented an analysis tool in Java using the jpcap library and extracted information about 84,608 visited web pages from the dump files. By analyzing the traffic, we were able to determine how many static links each visited web page contained, how many of these links were pointing to external domains, how many external links were actually requested by the browser, and what the k-value was for each page. We used a Java utility called HTML parser to extract the static hyperlinks in the page by looking at HTML elements such as link, script, and img with attributes such as href and src. The fact that we captured 30GB of data, but extracted only 84,608 web pages, may surprise the reader. However, after analyzing the data, we observed that a significant amount of the web traffic volume was due to the download of automatic updates (both for Windows and Linux machines). Furthermore, several users were downloading large files from the Internet, such as movies and shareware applications.
The web pages contained a total of 6,460,952 links of which 724,438 pointed to external domains (about 11%). Of these external links, 173,917 (about 24%) were actually requested by the browser, either because the user clicked on a link or because the page contained elements that were automatically loaded. We then applied Equation 2 to our data set and calculated the information leakage for the visited web pages. More precisely, the graph depicts the number of web pages for which at most a certain amount of bits were leaked (for different values of information leakage). One can observe that about 55,000 of the visited pages would not have leaked any information and thus, all their links could be freely visited. If, for example, we would allow 20 bits of sensitive information to be leaked to the attacker, no firewall prompts would be generated for 79,379 of the visited pages (which is about 94%). We believe that leaking 20–30 bits is acceptable for a majority of websites. Gmail, for example, uses cookie values that are more than 200 bits in size, and Yahoo mail uses values that are more than 150 bits in size.
Furthermore, programming environments such as Java servlets and PHP typically generate session IDs that are two hundred bits in size. Also, Noxes would have required manual interaction in about 6% of the cases when external links or references were requested. We believe that this makes the tool usable in practice. When we analyzed the k-values of the extracted pages, we observed that with a default k-value of 4, no prompts would be generated for 92% of the visited pages. Given the results outlined above, we can conclude that our enhanced XSS mitigation technique performs as well as the k-value approach, while at the same time, providing a solution against security threats such as multi-domain attacks. Clearly, the idea of using application-level firewalls to mitigate security threats is not new. Several solutions have been proposed to protect web applications by inspecting HTTP requests in an attempt to prevent application-level attacks.
The main critique of such policy-based approaches is that the creation and management of security policies is a tedious and error-prone task. Similarly, there exists a commercial product called AppShield, which is a web application firewall proxy that apparently does not need security policies. AppShield claims that it can automatically mitigate web threats such as XSS attacks by learning from the traffic to a specific web application. Because the product is closed-source, it is impossible to verify this claim. Furthermore, AppShield is a plug-and-play application that can only do simple checks and thus, can only provide limited protection because of the lack of any security policies. The main difference in our approach with respect to existing solutions is that Noxes is a client-side solution. Furthermore, these solutions require the willingness of the service providers to invest in the security of their web applications and services. In cases where service providers are either unwilling or unable to fix their XSS vulnerabilities, users are left defenseless (e.g., e-Bay was reported to have several XSS vulnerabilities that were not fixed for several months although they were widely known by the public).
The main contribution of Noxes is that it provides protection against XSS attacks without relying on web application providers. To the best of our knowledge, Noxes is the first practical client-side solution for mitigating XSS attacks. It is worth noting that, besides proxy-based solutions, several software engineering techniques have also been presented for locating and fixing XSS vulnerabilities. Although the proposed solutions are important contributions to web security, they can only have an impact if web developers use such tools to analyze and fix their applications. The ever-increasing number of reported XSS vulnerabilities, however, suggests that developers are still largely unaware of the XSS problem.