Tuesday, June 28, 2016

Auditing CSP headers with Burp and ZAP

This post was originally posted on GoSecure's blog
Content Security Policy (CSP)  is a HTTP header that instruct the browser to limit resource loading of media, styles and scripts.
As you may know, CSP is not adopted yet by industry. Multiple surveys have already been made about the adoption of the security header [1] [2] [3]. Even so, it does not mean that we cannot prepare ourselves for the technology. For this purpose, we have built a Burp and ZAP extension to automate the most common validations called CSP Auditor.

The extension


The first component is the passive scanning that find various issues around the CSP configuration. The issues are visible from the Target tab when selecting the targeted host.

Description of the weakness

The weakness is highlighted in the Raw Response Tab.


For manual review of the CSP header(s), an additional tab is available to display a readable version of the CSP configuration. It will display inherited properties. Those properties occur for example if script-src is missing but default-src is defined. The weak configurations are also colored according to the impact (orange for low severity and red for medium). This tab is available in most contexts such as History, Repeater and Intruder.

Detail view tab


The extension was submitted to the BApp Store and should be available in the next months. If you want to try it now, you can grab the plugin from the GitHub repository.

The passives rules


Now, what are the actual validations done by the extension? Here is the complete list. It can also be used as a checklist if a manual review is needed.

1. Unsafe inline

script-src: 'unsafe-inline'
In order to contain the JavaScript being executed, CSP allows only the execution of JavaScript within separate files.  With this directive enabled, an attacker will be able to use script html tag (<script>...</script>) or event handlers (onload, onerror, etc.) to load malicious JavaScript code.

2. Unsafe eval

script-src: 'unsafe-eval'
By default, CSP does not allow the execution of eval or setTimeout functions. The 'unsafe-eval' directive disable this protection. An attacker might be able to take advantage of those risky scripts using eval to trigger a XSS. The directive's presence is not a confirmation that eval() or setTimeout() are used. Old JavaScript libraries are often the reason why 'unsafe-eval' is added.

3. Wildcards

script-src: *
By specifying a wildcard, an attacker will be able to load a script from any server. Having this sort of directive eradicate the XSS protection capability from CSP.

4. Risky hosts with known vulnerable JavaScript

script-src: *.googleapis.com
Some libraries - namely AngularJS - have known payloads that allow the execution of script without using typical script html tag or event handler. In the case of Angular, CSP does not limit angular custom template syntax.

5. Allowing hosts that allow users’ content

script-src: *.appspot.com
Content delivery network (CDN) and software as a service (SAAS) are widely used. It is easy to introduce a permissive directive mistakenly. In the example above, the developer could have wanted to allow the hosts : myapplication1.appspot.com, myapplication1-api.appspot.com and myapplication1-files.appspot.com. Unfortunately, the wildcard cannot be used because anybody can register its own appspot subdomain (AppEngine).

6. Deprecated header name

X-Content-Security-Policy: ... / X-Webkit-CSP: ...
Some browsers have supported an experimental implementation of CSP with different header names. Now that the CSP specification 1.0 is out the older header should not be used.


Conclusion


This extension can be added to your web application assessment arsenal. However don't expect to find a majority of sites implementing an efficient protection against XSS. Inline scripts are still widely used.
We cannot expect applications to be rewritten completely but, we can expect that the web frameworks will eventually adopt the standard. CSP Level 3 and its "nonce-source" are likely to make the adoption easier.

References


Content Security Policy Reference : A handy reference to quickly getting started
CSP 2015 by filedescriptor: Article describing the remaining attack vectors once CSP is configured properly.
XSS without HTML: Client-Side Template Injection with AngularJS by Gareth Heyes: One of the most common CSP bypass
CSP Auditor on GitHub : Get the source code of CSP Auditor
CSP Bypass (Burp plugin) by Joe Moloch : Burp extension similar to CSP Auditor written in Python.
Content Security Policy : Level 1
Content Security Policy : Level 2
Content Security Policy : Level 3

Tuesday, March 22, 2016

XSS for ASP.net developers

This post was originally posted on GoSecure's blog
As a follow-up to the conference given at Confoo few weeks ago, we are doing a focus article on the same topic. The presentation was giving an overview of the modern XSS attack vectors and filter bypass. In this blog post, we will take a closer look at XSS in the context of .NET applications.
This article is intended to be a simple checklist for ASP.net MVC developers or security auditors. Defensive measures can be put in place at various layers including the template files (Razor or ASPx Forms), the Request Validation feature and the client-side (browser) filters.


Template


Lets remind ourselves that the root cause of Cross-Site Scripting is missing  encoding of user inputs. Having the right encoding at the source is obviously the true antidote to this class of vulnerabilities. Luckily, the template engine available in .NET is doing some encoding by default.
Here is a list of vulnerable templates using the Razor template engine. The examples assumes that the values displayed are controlled by the user.
  • Unsafe HTML
Hello @Html.Raw(ViewBag.Name)
If direct binding was used (@ViewBag.Name), it would be encoded properly the value for the HTML context. In the HTML context, special characters are replaced by XML entities such as &lt; , &gt; and &quot;.
  • Unsafe Html.Raw in attributes
<a href="/ViewDetails?name=@Html.Raw(ViewBag.Name)">View Details</a>
In this unsafe example, the developer might have disabled the encoding because he realizes that the default encoding to HTML entities is not appropriate for URLs. Special characters are replaced by entities (ie " becomes &quote;). A context specific function should have been used. Server.UrlEncode() can be used to encode safely a value in an URL.
  • Unsafe action link
@Html.ActionLink("Open page", null, null, null, new { href = @ViewBag.Url })
With the first ActionLink, an attacker could use the URL "javascript:[...]" to trigger malicious JavaScript. A validation of the URL is needed in the controller.
@Html.ActionLink("Back to previous page", null, null, null, new { href = Request.UrlReferrer })
The second ActionLink example could lead to an Open Redirect. It does not lead to arbitrary JavaScript execution but it could be used as an effective means for stealing credentials or phishing attacks.
  • Unsafe "unquoted" attribute
Attributes in Razor template can become vulnerable to XSS in two scenarios: when Html.Raw is used (see Unsafe Html.Raw in attributes) or when an attribute is not placed in quotes. Razor does not enforce the use of single or double quotes.
<img src=logo.png alt=@(ViewBag.ImageId)>
Here a malicious user controlling the ImageId variable could add a JavaScript event such as onload or onerror. The following snippet illustrate a basic injection.
<img src=logo.png alt=''onload='alert(1)'>
  • Another example with unquote attribute that could lead to DOM clobbering
<form class=@(ViewBag.FormClass) action="SubmitMe">
</form>
In this particular case, a form with the injected properties "name" and "id" can lead to shadow JavaScript global variables that are injected later in the DOM. It is a very capricious attack vector that works for very specific property names. If you want to know more about it, you can read Gareth Heyes article on DOM clobbering.
  • Script context
<script>
api.SearchUser('@(ViewBag.FirstName)','@(ViewBag.FirstName)');
</script>
Finally, the script context is slightly more at risk because the value are escaped to HTML entities by default. In the example above, it is possible to inject JavaScript because HTML special characters are escaped but not blackslash ().
<script>
api.SearchUser('Dummy',');prompt(1234)//');
</script>
In the previous example, the blackslash escape the terminating single quote. This cause the string to actually close on the following single quote. The second parameter can then be use by the attacker introduce malicious Javascript.
To summarize the correct guidelines, we have create a cheat sheet that include code examples  for the different contexts. It is intend to be a quick reminder for developers or security auditors doing code review. Feel free to share this cheat sheet to developers of your organisation.

Security Cheat Sheet @ GitHub

Request Validation


RequestValidation error message (input blocked)
Request Validation is a built-in filter to ASP.net. It is an additional layer of protection that is intended to block malicious requests. It will stop suspicious request if the parameters contains any HTML tag.
The Request Validation module is a feature that is integrated to ASP.net framework. It is decoupled from the View ASP forms or Razor Templates. It can be view as a Web Application Firewall for XSS specifically.

Bypasses

Any transformation between the moment the request is received and the construction of the final HTML view can lead to filter bypass. If an HTTP parameter is URL decoded two times, it is enough to bypass the filter.
One of the common transformation is SQL server character conversion to ASCII. It can occurs if the column data type is not unicode (VARCHAR vs NVARCHAR). SQL Server will convert the Unicode character FF1C to 003C. This is sufficient to bypass RequestValidation to create a Stored XSS.

Character Character After storage
U+FF1C (%EF%BC%9C) U+003C (%3C)
U+FF1E (%EF%BC%9E) U+003E (%3E)

A malicious payload using this bypass would look like this:
Name=XSS_HERE_%EF%BC%9Cimg%20src%3Dxxx%20onerror%3Dalert(1)%EF%BC%9E
Once the value would be output, it will be display as < (u+003C) and > (u+003E).
XSS_HERE_<img src=xxx onerror=alert(1)>
Nonetheless, it is still recommended to keep RequestValidation as a extra safe guard. As the official documentation stated, it is not a replacement to validation and proper encoding.

Client-side filters

Modern browsers also provide an additional layer of protection. Chrome, Internet Explorer and Edge have a filter mechanism that can detect some reflected XSS. The browsers will find some patterns were HTML tags are passed in the URL or POST parameters and are reflected in the page.

Browser XSS Filter
Mozilla Firefox None
Google Chrome Yes
Internet Explorer / Edge Yes

The filter can also be forced with the header X-XSS-Protection: 1. This has limited benefits because the filter is already enabled by default in Chrome, Internet Explorer and Edge. However, for some hosts (like localhost), IE/Edge will disable its filter by default.

Additional configurations

  • X-XSS-Protection: 1; mode=block : It is possible to block the loading of the page if a malicious pattern is detected. It is intended to avoid unwanted scripts being disabled.
  • X-XSS-Protection: 1; report=http://myhost.com/report : With this directive the browser will report blocked parameters to the URL specified in the header.
Even though  the filters have been proved to be effective, there is no commitment from the Chrome and Edge teams to provide a complete coverage.

Bypasses


Browser filters do not cover stored XSS and some DOM XSS. They also have some known bypasses. Usually, a transformation will lead to filter bypass. In the following example, the value is properly HTML encoded. However, JavaScript will read the attribute and print it. It will trigger an XSS because once the attribute is read the entities are decoded.
http://website.com/example?userId=%3Cimg%20src=xx%20onerror=alert(1)%3E
<form action="">
<input type="hidden" id="userId" name="userId" value="&lt;img src=xx onerror=alert(1)&gt;" >
</form>

<div id="preview"></div>

<script>
document.getElementById("preview").innerHTML = "Hello "+document.getElementById("userId").value;
</script>


Conclusion


This article should cover the key elements when it comes to safe HTML encoding and XSS prevention. You should now be aware of some of the limitations of each components. It should also stand out that security is not a silver bullet. Relying on a single protection will increase the probability of malicious payload passing through.
As mention previously, feel free to share this cheat sheet to developers of your organisation. The cheat sheet will evolve in the next month to include additional languages and frameworks. The project is open for contribution and reuse.

References

Wednesday, January 6, 2016

Deserialization Vulnerability : Automating the hunt


At the end of 2015, many Java applications were found vulnerable to a common deserialization bug. It all starts with a presentation at AppSecCali that demonstrate the danger of deserializing user input and having Apache Commons Collections in the classpath [1]. Stephen Breen from Foxglove later publish vulnerabilities with working exploits for WebLogic, WebSphere, JBoss and Jenkins.

This is obviously not the end of the story. While some big names where fixed, other applications open source and proprietary are likely to be vulnerable to the same bug pattern. In fact quickly after Foxglove publication, an advisory was release for ActiveMQ.

Stephen has already described in great detail the detection and exploitation in the context of penetration test. I wanted to provide a small method for scanning proprietary applications looking only at the jar files.

Object deserialisation (*)

Scanning a specific library


For the demonstration of this article, I will use the command line interface of FindBugs with the plugin Find Security Bugs version 1.4.5 (download link).
In its simplest form, we can pass the path of the JAR file to scan. Here -high is added to hide medium vulnerability.
> ./findsecbugs.sh -high libs/esapi-2.1.0.jar

H S SECOBDES: Object deserialization is used in org.owasp.esapi.codecs.Base64.decodeToObject(String)  At Base64.java:[line 1106]
H S SECPTI: File(...) reads a file whose location might be specified by user input  At DefaultEncryptedProperties.java:[line 174]
H S SECPTO: FileOutputStream(...) writes to a file whose location might be specified by user input  At Base64.java:[line 1359]
H S SECPTO: FileOutputStream(...) writes to a file whose location might be specified by user input  At Base64.java:[line 1322]
H S SECPTI: File(...) reads a file whose location might be specified by user input  At EncryptedPropertiesUtils.java:[line 188]
H S SECPTI: FileInputStream(...) reads a file whose location might be specified by user input  At Base64.java:[line 1318]
H S SECPTI: File(...) reads a file whose location might be specified by user input  At EncryptedPropertiesUtils.java:[line 140]
H S SECPTI: FileInputStream(...) reads a file whose location might be specified by user input  At Base64.java:[line 1355]

To analyze a specific bug, you can open the jar directly in JD.
Jumping to the potential bug (Base64 line 1106)

Search feature in JD to find class by name or regex pattern

Scanning a complete application


The command line interface of FindBugs has plenty of options. If we want to scan a complete application, we will need to give the complete list of jars to FindBugs.

On Linux:
> find /some/application/ -name *.jar

On Windows:
dir "C:/Some/Application/" /s /b  | findstr \.jar$ > libs.txt

Once the jars list is place in a text file, we can start a global scan. In the following example,


  • -xargs : is used to pipe the list of jars
  • -progress : is added to have some feedback since analyzing large code base can take a couple of minutes.
  • -html : I recommend using the HTML report to have a more detailed and readable report

  • > cat libs.txt | findsecbugs.sh -xargs -progress -html -output report.htm
    
    Scanning archives (156 / 156)
    2 analysis passes to perform
    Pass 1: Analyzing classes (16922 / 48118) - 35% complete
    

    The same operation can be done in Windows with the following command.
    > type libs.txt | findsecbugs.bat -xargs -progress -html -output report.htm
    

    Conclusion


    That's it! You should be able to find deserialisation vulnerability along with other bug patterns supported by Find Security Bugs plugin.

    To determine if an application is vulnerable or not will obviously require a specific analysis. The only general guideline is to identify ObjectInputStream instance where the content is read from user input.

    References


  • What Do WebLogic, WebSphere, JBoss, Jenkins, OpenNMS, and Your Application Have in Common? This Vulnerability: Detailed explantation for many application can be exploited by Apache Commons Collections "serialization gadget" written by Stephen Breen
  • AppSecCali 2015 - Marshalling Pickles: Presentation that cover the Apache Commons Collections "serialization gadget" by Christopher Frohoff and Gabriel Lawrence
  • SRCLR: Commons Collections Deserialization Vulnerability Research Findings : Research maded by SRCLR that focus on finding additional vulnerables libraries
  • SRCLR: Let’s Calm Down About Apache Commons Collections: Follow up to the article from Foxglove Security
  • ActiveMQ CVE-2015-5254: Official advisory from ActiveMQ
  • Find Security Bugs : Official web for the Find Security Bugs plugin
  • Find Security Bugs release 1.4.5 : Version use in the previous demonstrations