Automated Security Test Cases

A paradigm shift in security testing

Let me propose a radical new idea: Implement security test cases to test security controls in your application similar to how you test functional requirements. Yeah, I know there is nothing radical about it and this is not a new concept. But, lot of organizations have accepted Test Driven Development (TDD) practice and are extremely good at automating testing of functional requirements, but when it comes to security testing, it is still being offloaded as a point in time assessment to the security teams. Lets try to make automated security testing as common as implementing test cases for functional testing! Are you with me on this?

Benefits of implementing security test cases

  1. Build secure coding practice in the Development teams and makes them aware of security vulnerabilities and their remediation.
  2. Over a period of time, you build a strong suite of security test cases that get executed continuously in a pipeline providing continuous security assurance as opposed to point in time assessments.
  3. Security tools can’t detect logic and functional security vulnerabilities such as what roles are required to execute a capability, if there are authorizations based on dollar amounts, user registration flows etc.
  4. Most importantly this is “free” as in there is no licensing costs for expensive application security testing tools out on the market that at the most provide partial coverage and effectiveness compared to manual security assessments. I put “free” in quotes because you still need to expend time to implement security test cases.

What are common security test cases to implement?

Please see below for some examples of automated security test cases to implement across various categories.

Authentication test cases

  1. Verify that you are not able to login with invalid credentials
  2. Verify that you are not able to bypass multi factor authentication steps
  3. Verify that account is locked after 3 tries
  4. Is access to secure end points limited to authenticated users?
  5. Is the timeouts of authentication tokens working as expected?
  6. Is logout working as expected?

Authorization test cases

  1. Is access limited to users that have certain Role?
  2. Authorizations based on thresholds, verify is access is limited based on business logic rules
  3. Can the user assume a Role that they are not assigned to by sending a role on the request?
  4. Is the user authorized to access the object referenced in the URL? This is significant for REST end points where as best practice, IDs are specified in the URL. For e.g. if you have REST end point to retrieve account information, /rs/account/123456789, verify that the authenticated user is authorized to access account 123456789 as the end user can easily manipulate the account number to somebody else’s account number. This is called Direct Object Reference Vulnerability.

Input Validation and Output Encoding test cases

  1. Does the system reject invalid or malicious inputs?
  2. Is the system encoding user inputs before persisting to a sink? For e.g., sending in data containing SQL Injection pay load.

CSRF Protection test cases

  1. Verify that you are not able to perform state changing operations with out a CSRF token in the request

Miscellaneous test cases

  1. Verify is data is encrypted in transit with the use of https protocol
  2. Verify that TLS Certificate is valid
  3. Verify if “secure” flag and “http only” flag is set on cookies that contain sensitive data

How to implement security test cases?

Now that you are convinced to implement security test cases, how do you go about implementing them? There is no secret sauce to security test cases, Developers can use commonly available Open Source testing frameworks such as Selenium, Cucumber, JUnit, Mockito, Jersey Test Framework etc. for implementing security test cases. There are some open source projects such as Gauntlt that can give you a head start in implementing security test cases. In a future blog, I can provide some sample Cucumber test cases to demonstrate how easy it is to incorporate security testing in to your applications!

Advertisements

CORS Demystified!

Background

CORS stands for Cross Origin Resource Sharing. This is security feature supported by Browsers that allows the UI applications to be hosted on a separate domain from the underlying APIs that are used. This is what enables the API Economy work! The consuming applications can call APIs hosted on different domains from different providers to build meaningful applications to the end user. If the UI and API were to be hosted on the same domain, this makes the applications very restrictive in the functionality they can provide as they can only call services that are hosted on the same domain!

Lets talk about how this all started! Long time ago when Dinosaurs were roaming the earth, yeah not so long, but you get the point, browsers allowed AJAX calls only to the domain where the page was loaded from. Let us say that the page was loaded from http://www.xyz.com, the browser would allow AJAX calls back to http://www.xyz.com. The reason they did that was to protect the end user from below scenario.

  1. User logs on to http://www.xyz.com and gets authentication cookie. Let’s call it xyzauthtoken cookie that is scoped to the domain xyz.com
  2. Now the user while logged on to xyz.com navigates to another site, http://www.evil.com
  3. evil.com generates an AJAX request to xyz.com. Browser sends the xyzauthtoken cookie along with the request allowing evil.com to impersonate the user logged in to xyz.com. This is pretty bad!

However as web applications evolved, this security feature made it very restrictive for applications from consuming services/APIs from different providers that are hosted on different domains.

CORS spec was put-together by major Browser providers to solve this problem. Chorme, Safari, Firefox were the early adopters of this security feature where as IE started supporting CORS only from IE version 10 and above!

How does CORS work?

CORS empowers the API providers and allows them to control who can consume their services over AJAX. The below diagram depicts the CORS flow!

  1. User logs on to http://www.xyz.com and gets authentication cookie. Let’s call it xyzauthtoken cookie that is scoped to the domain xyz.com
  2. Let us say, the webapp invokes services hosted on api.123.com to get some data. The user has to authenticate to api.123.com, but that is beyond the scope of this article! Just in case you are curious, OAuth solves that problem, a topic for future blog post!
  3. The CORS supported browser, holds the request and issues something called a pre-flight OPTIONS request to api.123.com with a request header set to Origin=www.xyz.com. The browser does not send any cookies with the preflight request.
  4. Now api.123.com can decide weather to accept a request from xyz.com. If api.123.com is okay serving up a request from xyz.com, it responds with response header, Access-Control-Allow-Origin, that specifies all the domains that can access api.123.com. The header can take regular expressions and if api.123.com can accept requests from any domain, you can set something like Access-Control-Allow-Origin=*.
  5. The browser checks if the value in Access-Control-Allow-Origin matches to the value in Origin. If there is a match, the browser releases the original request to api.123.com
  6. The AJAX request to api.123.com is sent and the app is able to get the data from a service hosted on a different domain!

How does CORS protect the end user?

In the above scenario, lets say api.123.com allows AJAX only from xyz.com and abc.com. The service could have set Access-Control-Allow-Origin header as follows:

Access-Control-Allow-Origin=xyz.com,abc.com

Now, imagine a scenario where the user navigates to http://www.evil.com and the malicious site issues a AJAX request to api.123.com. Let us see how CORS protects the user from this call.

  1. The CORS supported browser, holds the request and issues a pre-flight OPTIONS request to api.123.com with a request header set to Origin=www.evil.com. The browser does not send any cookies with the preflight request.
  2. api.123.com responds with Access-Control-Allow-Origin=xyz.com,abc.com
  3. The browser checks if the value in Access-Control-Allow-Origin matches to the value in Origin. In this case, it does not match and the Browser drops the request and no call is made to api.123.com

CORS spec allows the Provider of any API to specify what Http Methods and Http Headers can be sent by the Consumers and provides flexibility in accepting lets say a GET request from any domain and restrict a PUT/POST to only a sub-set of trusted domains.  If you need more information on CORS and all the features supported by CORS, it is well documented here!

Next time you are Banking or checking your investments online, turn on Developer Tools (F12) in your browser and see how the AJAX calls are being handled!

Authorization Checks in REST APIs

Lets take a look at sample REST APIs that allows Students to view their grades and professors to add/update grades.

If a student wants to view his/her grade in English, your system perhaps has a REST API like:

GET /student/{student_id}/english/grade

The Professor perhaps has access to the following REST APIs to be able to view and update any one of their students’ grades:

  1. View a student’s grade

GET /student/{student_id}/english/grade

2. Post a student’s grade

POST /student/{student_id}/english/grade

3. Update a student’s grade

PUT /student/{student_id}/english/grade

Of course there is a portal that the Student logs in to to view their grades and the professor logs in to post and update grades.

A savvy student is able to turn on HttpWatch to view the REST APIs being called by the portal. Lets say, the student A observes that when she clicks on a link to view her English grade, a REST API call is generated that looks like the following:

GET /student/1234/english/grade

What if the student is smart enough to replay this request with a different student id, 6789?

GET /student/6789/english/grade

If there are no proper Authorization checks in the APIs, the student A with id, “1234” is now able to view student B with id “6789” grade.

Even worse if if the student was able to update their own grade. How about the student try the following API?

PUT /student/1234/english/grade with payload “A”

or update someone else’s grade to “F”

PUT /student/6789/english/grade with payload “F”

However, a professor should be able to view, post or update anyone of their students’ grades. All of the above APIs are fair if they are issued on behalf of a professor.

So, every REST API call needs to enforce proper authorization to make sure that the user on whose behalf the API call is being made has access to the Resource on which they are taking action.

Since Java 6, the following Authorization annotations were added to make it easy to decorate methods with Authorization checks:

Annotation Types Summary
DeclareRoles Used by application to declare roles.
DenyAll Specifies that no security roles are allowed to invoke the specified method(s) – i.e that the methods are to be excluded from execution in the J2EE container.
PermitAll Specifies that all security roles are allowed to invoke the specified method(s) i.e that the specified method(s) are “unchecked”.
RolesAllowed Specifies the list of roles permitted to access method(s) in an application.
RunAs Defines the identity of the application during execution in a J2EE container.

However, these are annotations do not allow you to check if the user has access to a specific Resource ID. This is where, I find using Spring Security to be very helpful.

Spring Security provides a mechanism to do Data Level Authorizations using “hasPermission” annotation. Below is a reference from the documentation:

hasPermission(Object targetId, String targetType, Object permission) Returns true if the user has access to the provided target for the given permission. For example, hasPermission(1, ‘com.example.domain.Message’, ‘read’)

This makes it a bit easy to centralize logic for authorization checks. In the case of a REST Call such as POST /student/1234/english/grade “A” would translate in to a hasPermissions check:

hasPermission(“1234”, Grade, “update”) The method has access to the Principal on whose behalf the call is being. So, you have access to the Principal and the Target, and you can verify if the Principal has access to act up on the target ID. In the case of a student, this check returns a true only if the Principal and the Target ID are the same and also the permission is “view”. In the case of a professor, the check may be something like does the Target ID belong to a student that is currently enrolled in the Professor’s class.

If you are using Spring Security or some other framework, make sure you provide an easy way to apply authorization checks to ensure that the Principal is able to act on a given Resource.

Newest OWASP Top 10 Release Candidate List is Out

OWASP Top 10 is updated every 3 years and the latest 2016 Release Candidate list of OWASP Top 10 Vulnerability Categories list is out. There two new categories of vulnerabilities that were added and that is the focus of this Blog Post.

OWASP Top 10 Project team added the following two new categories to the list:

  1. A7 – Insufficient Attack Protection
  2. A10 – Underprotected APIs

Lets talk about these two.

A7 – Insufficient Attack Protection

This category suggests that most applications have insufficient Preventive, Detective and Corrective Controls built in to the applications. Does your AppSec team provide common libraries, frameworks and services for Authentication, Authorization, Input Validations etc.? Do these frameworks log Security events if someone tries to circumvent these controls? Do you have actively monitor for these errors and respond if you receive alerts on these events? Are your applications self healing if they detect an attack in progress? These are some of the questions that this new category prods us to think.

As in most organizations, they rely upon Developers to implement sufficient Logging to be able to Detect malicious activity. But more often than not, the organization that does the monitoring is separate from Development Organizations and most likely are not aware that they need to monitor and respond to these Application Security Events. Most of the times, the monitoring and alerting is only at the Network and Infrastructure layers and not at the App layer. Hopefully, having this new category allows organizations to fortify SOC monitoring to include Application Security Alerts for monitoring.

There are a few critiques of this new category, especially, as this category proposes including a RASP (Realtime Application Security Protection) in your application stack that can detect and protect in real time as the exploit is in progress. The reason being the this category proposal came from Jeff Williams, the co-founder of Contrast Security, that offers RASP capability. Is there a conflict of interest? May be. But, does that stop me from exploring this new category and looking at ways to get better at application security? Definitely not.

I am not endorsing the criticism, but here is one such post to learn about the controversy on A7 – Insufficient Attack Protection. But, who does not like some drama in their chosen field?

http://www.skeletonscribe.net/2017/04/abusing-owasp.html

A10 – Underprotected APIs

If you do not have APIs in your organization, you must be hiding under a Rock or accidentally hitched on to the Mars Rover looking for Alien life. APIs are every where. Every company worth its salt is embracing micro-services architecture. So what is the problem?

All the OWASP Top 10 vulnerabilities typically associated with Web Applications apply to APIs as well. All APIs need to be Authenticated, Authorized, etc. etc. But, one area that we see vulnerabilities is Insecure Direct Object References, where Resource Ids are exposed in the URIs and an attacker can change the Resource Id to see if they are able to get to Resources that they are not authorized for. For e.g., if you have an API to retrieve your bank account information and the API is, /rs/account/{id}, an attacker will enumerate this API with different Account Ids to see if they accidentally get access to someone else’s account information. This is Insecure Direct Object Reference. Does the Authenticated user has access to the Resource being requested, in this Account information referred to by the Account Id, is Business Logic and it is very hard to verify outside of the context of your application.

How do mitigate this vulnerability?

API Developers needs to implement what we can call Data Level Authorization checks in the application code. Does the authenticated user has access to Account Id “xyz” check needs to be implemented before any Account information is sent back to the user. This check may vary based on the Resources and APIs that you deal with and needs to be built with in the context of the application.

Please share your thoughts on what you are seeing as your organization adopt APIs and Micro-Services architecture.

API Gateway: Why you need it?

If your decent sized organization embarking on Micro Services Architecture, I think you need to look at a few infrastructure components to make it easy to manage the APIs.

Some of the basic building blocks for having a robust Micro Services Architecture are:

  1. Distributed Cache: MemCache, Gemfire and several other products out there help you build and manage your cache infrastructure, which is central for building high performing APIs.
  2. Service Registry: Don’t you want to know what your APIs, especially the ones that are exposed to the Internet? Having a Service Registry greatly enables adoption and use of Micro Services. Without a Service Registry, be ready for duplicated services, orphaned services that are no longer used, in ability to scan all APIs if there is no record of them are some of the major headaches you will face if you do not have a Service Registry. But, this is a hard one to get correct unless registering and updating your APIs in the Service Registry is fully automated in the Build Pipeline.
  3. API Deployment: You need a platform that makes it easy for the Development teams to deploy APIs easily. Platforms such as Pivotol Cloudfoundry that offer containers to run your services fill this space.
  4. API Gateway: APIs offer unique challenges in terms of Authentication, Authorization, Service Composition, Request/Response Transformation (Payload, Data Format from XML to JSON and Vice Versa etc.), Throughput handling etc. that need a robust solution. API Gateways fill  this space.

In this post I want to share some of thoughts on API Gateways, particularly Layer 7.

Traditional Web Application Authentication technologies are agent based. You have an agent running on your web server that would intercept and interrogate the Request based on the pre-configured policies. With Micro Services running on containers or server less platforms such as Lambda this architecture is no loner applicable.

API Gatways such as Layer7 make it very easy to apply the follow processing steps for you micro services:

  1. Authentication schemes such as OpenID, Basic, Form, Certificate based authentication
  2. Authorizations Open Auth, RBAC etcc.
  3. Request/Response Transformations
  4. Protocol conversions such as SOAP to REST
  5. Conditional Logic
  6. Error Handling
  7. Threat Protection
  8. Caching
  9. Throttling
  10. API Registry -> This is very important to have to avoid duplication of services and allows service discovery

Organizations that jump on the micro services bandwagon with out first building infrastructure components, will soon run in to Operational and Security nightmare that could be easily avoided by architecting and implementing above mentioned building blocks. These days there are various robust open source solutions that meet your needs without having to break your bank.

Authorizing Access to Data Embedded in REST APIs

Is your REST API vulnerable to Direct Object Reference Attacks?

Designing Client applications using HTML/JavaScript/CSS that call REST APIs to retrieve data is an architecture pattern that lot of companies are adopting these days. In the blog post, I will address a common security vulnerability that the developers expose their applications while implementing the REST APIs.

Lets say you have are building a REST API for your Banking and implement the following REST APIs:

  1. API to retrieve account balances – http://api.yourbank.com/rs/account/{account_id}/balance
  2. API to transfer money – http://api.yourbank.com/rs/transfer/from/{from_account_id}/to/{to_account_id}/amount/{amount}

Although it seems simple enough, the Developers do not verify that the authenticated user (the user logged on) has authorization to operate on the accounts being specified in the API calls. There could be different reasons for this missing security control:

  • Under the covers the API is using legacy code to implement the functionality and the security checks were done in legacy UI that was calling the legacy mid-tier. So, when the Developer is implementing REST API, they are not accounting for the authorization check and are relying upon the UI to enforce the check.
  • The Developers might be under the impression that the user can not change the data in the URL as there is no input from that allows them to control the data as it is displayed as an HTML link on the page. This line of thinking applies to other inputs that could be submitted on the payload such as Cookies, Headers, Query Params, Hidden Inputs, Path Params etc.

In Security, this is called Direct Object References and directly conflicts with REST Design principles to have Unique Ids for Resources. Hence, it is a must that REST API Developers must implement authorization checks on any Ids that appear on the APIs to ensure that the authenticated user (Logged on user) has authorization to access data embedded in the REST APIS.

How to mitigate this vulnerability?

The solution is custom for the API that you are implementing as this is data specific to your use case. The authorization checks could be done at the entry point to your APIs or with in each API to verify that the authenticated user does have access to each data element embedded in the API. For e.g. in the above API calls, verify that the logged on user has access to the Account Id specified in the API call.

Frameworks such as Spring Security, makes this very easy by applying authorization annotations on your REST end points.

The code implementing “Get Balances” REST API could have authorization annotations such as:

@PreAuthorize("hasPermission(#account_id, 'view_account')")
  public Double getBalance(@PathParam("account_id:) Double account_id);

TBD: Reference application that shows implementation details is soon to follow. Please say tuned.

Please suggest frameworks for other languages that you are familiar with.

Verification

Implement test cases to verify that the controls is working as expected and is preventing unautjhorized access to resources specified in the API/URI.

TBD: Reference application that shows implementation details is soon to follow. Please say tuned.

Additional Resources

https://www.owasp.org/index.php/Top_10_2013-A4-Insecure_Direct_Object_References