Over the past few years, we have seen QA and development teams shift left as they go about conducting their software testing. As the need for faster development and deployment stands, starting testing in the early stages of the product cycle is essential.
Application Programming Interface (API) testing is a crucial step that must be included in any software QA process. This testing helps ensure that all components involved in an application can interact with each other as expected without any hiccups. This includes the evaluation of input parameters, response data, and the overall performance of the respective system.
However, it’s not enough to simply perform API tests during the development process and call it a day. Developers must also introduce security testing into their existing QA strategy to protect applications from malicious attacks and vulnerabilities.
APIs enable communication and data exchange from one software system to another. It is a prime target for exploitation and needs to be protected.
This article is going to be something other than an API testing tutorial. I want to focus on the API development lifecycle and how software testing has to be looked at through a security lens so that it can stand up to any sort of penetration testing, be it from your testing team or an adversarial threat actor.
Why is API Testing Important for Security?
When we think about the API endpoints in the web services, we have to build and test it’s important to consider how functional testing demonstrates how it should work. However, from a security testing perspective, we need to think about the negative behavior... how resilient the API functions when a request is altered or tainted that might break it.
This is more commonly called validation testing and is a critical component of API testing.
When you approach API testing this way, you start testing not only for how the API functions but also for how error detection is handled. Development teams start building more defensible code that can handle the API function calls abuse we see in the real world today.
There are also other benefits to consider.
The Benefits of API Testing with a Security Focus
One of the most important benefits of API testing with a focus on security is that it looks at testing business logic differently. Test cases are tailored to abuse how the API performs actions in an effort to misuse the application programming interfaces.
When testing REST APIs, we create tests that look at how an API responds to tainted input. Through API test automation, we can even conduct fuzz testing that stresses the business logic and ensures the web API can withstand malicious inputs.
Regardless of what API testing tool you use, automated tests can help with continuous testing and improves the overall coverage of your web services.
Other benefits include exploring the API call graph in far more detail as you look for brittleness in the endpoint’s data exchange and a new mindset in testing your web API that focuses on negative behavior.
Types of API testing with security in mind
When it comes to automated testing, especially with security in mind, testing APIs is vitally important at all stages of development and release. Let’s explore some of the more common types of API testing and focus on how to look at it through a security lens.
So as we continue to shift left, this means developers need to be part of testing security. Their unit tests should include validating the code to see how it can handle tainted input.
The detection of malicious data and parameters should be built into the tests so that developers are aware even at the unit level of how their code can perform when abused.
When it comes to functional testing for your web services, the focus needs to be on the negative scenarios. What happens when malicious data is sent? How does the API handle incorrect parameters?
These are questions that need to be asked and tested in your functional tests to ensure your APIs aren’t vulnerable to exploitation.
Integration tests should also focus on how the different components of the web service handle malicious input. Suppose your application uses OAuth tokens or other external authentication services. In that case, this is even more important as attackers have been known to abuse this external trust to penetrate systems by bypassing authentication and authorization controls.
We can’t forget the graphical user interface (GUI) that usually consumes or interacts with our web API.
UI testing should also include looking at how the interface interacts with the API and how it handles malicious data, both on input and output. The GUI is just as vulnerable to attack as the backend services it interfaces with, so make sure your UI tests consider these negative scenarios. This is a favorite of attackers who love to abuse things like XSS.
These days, almost every API testing tool has the ability to inject tainted input into fields within HTTP requests. By creating a fuzz testing suite, you can explore the API call graph and see how it responds to malicious data in many different forms.
Through automated tests, you can even generate random input that can be used to stress test the web service in ways manual testers may not think of.
This includes manipulating content-type (i.e., JSON vs. XML) payloads and seeing how the web services react to unexpected changes in the data and data formats. This helps with interoperability testing for those API endpoints that do support multiple content types but for whom we may not get as much test coverage.
It also helps with validation testing as you can see how the web services react to tainted data. In many cases, APIs can fail or otherwise be manipulated due to weaker business logic in failure code paths.
Automated API testing should include performance tests. Since APIs are becoming more commonly abused, API load tests to validate things like rate limiting and excessive data exposure become essential.
You must ensure your web service can handle the expected workload and understand how to model “good behavior” against bad. This helps the operations group know how to monitor the API performance and detect unhealthy behavior such as abuse and misuse.
How to introduce API security testing to your team
So we’ve covered the areas where we can introduce API testing with a security lens. But how do you approach this subject with your team, especially if you don’t do any formal security testing today?
It comes down to your people, the process, and finally, the products you use for testing. And the order in which you approach this matters.
You need to engage with your team and help them understand the importance of testing security in their APIs.
Start by introducing the concept of secure coding best practices so that everyone is aware of it from the start. Then, emphasize how important security testing is, not only from an operational perspective but also in terms of customer privacy and safety.
The goal is to start identifying and building security champions within the team.
But how do you put that foundation in place when you don’t have experts on staff? Approach it by defining a clear process that follows industry standard guidance.
Your API Testing Process
To start, you might want to consider looking at an API testing framework. In a previous article, I talked about leveraging the guidance from OWASP to build your own security testing blueprint.
Using the OWASP Application Security Verification Standard can help you build out your API testing requirements, especially since it includes in section 13 a whole area on API and Web Service testing.
It provides guidance that can help you create API test cases that focus on security and improve your testing techniques. Combined with an approach to use test automation to continuously validate business logic through a security lens, you start to harden your web APIs far earlier in the product lifecycle.
Having your process now written and your test cases defined, you can start operationalizing this with the right tools.
Your API Testing Tools
It’s much easier to say API testing is essential when you don’t have to do it. As automation tools continue to improve, it’s making testing tools more accessible to everyone and making them easier to use.
And last but certainly not least, we can’t forget powerful tools like the OWASP Zed Attack Proxy (ZAP) or BurpSuite, which deliver entire penetration testing platforms that can be run headless to continuously execute your defined API security test cases.
Which API testing tools you use is really up to your team. The more test coverage that can be performed with little to no human interaction, the better.
While functional testing of your web APIs is nice, being able to automate many aspects of your appsec penetration testing gives you and your team far more confidence in the resiliency, reliability, and security of your web services.
Why Input Validation Testing Is So Important
When looking at which test category is most important, you may have noticed a recurring theme in this post… that input validation matters for APIs.
Testing boundaries between client and server, ensuring inputs are properly sanitized, and validating all API parameters should be paramount.
It’s no surprise that injection-related attack vectors, like SQL Injection (SQLi), Command Injection, or Cross-Site Scripting (XSS), still make up a significant portion of the OWASP Top 10 security risks for APIs. Never mind the mass assignment attacks that are prevalent in many APIs due to developers’ reliance on framework object (de)serialization that is easy to manipulate and abuse.
Understanding why input validation matters is a cornerstone of any API testing process. It’s also the cornerstone of writing secure code.
So it’s important that both development and test teams consider that.
What makes up input validation?
Input validation comprises a few different elements, but the main ones to consider with a security lens include:
- Input type enforcement – Ensure that your API accepts only the expected data types. Why accept text in an integer field or an integer in a boolean field?
- Content integrity enforcement – Ensure that an incoming request’s content is as expected. If you expect a JSON object but notice the body is XML based and don’t want to support that content type, don’t allow it. If you can digitally sign content to ensure it isn’t tampered with during transmission, consider it.
- Blacklisting/whitelisting – Put filters in place to control which values are accepted by your API. This could help with partial updates in object serializers if you have ACLs on properties within objects. Regular expression pattern matching of expected data formatting through whitelists (know GOOD patterns) is always better than blacklists.
- Schema validation – Use a schema to validate the structure of an incoming request. This is helpful when APIs have versioned endpoints that accept different object schemas (i.e., updated/additional properties in an object for a newer version)
These techniques should be used to ensure that only valid and expected data is accepted by your APIs, making sure that bad or malicious input can’t make its way through and exploit any potential vulnerabilities in your system.
It’s not just about the data validation though. It’s just as important to consider the failure code paths… how you respond to validation can be just as telling to an attacker.
For example, with limited API knowledge, a threat actor might be able to take advantage of the misuse of HTTP status codes to cause an information disclosure leak based on an input field like “email address.”
How? Imagine if they were abusing a “reset password” endpoint that returns a 404 status code if the email address doesn’t exist, vs. returning a 401 or 403 status code if it does exist, but the reset token was invalid. It becomes possible for the attacker to enumerate the user database by simply trying every email address they collected during recon to see which ones exist in the system.
As you can see, input validation is about more than just ensuring the data being sent is in a valid format… it’s also about the fact that it’s valid within the context of the business logic of the API call.
API security testing is an integral part of any API development project. Making sure that your APIs are secure and resilient to attack is just as important as ensuring that they work as expected.
This means that in addition to functional tests, you should also be running input validation tests, authorization tests, authentication tests, security scans like ZAP or BurpSuite, and other specialized tools like Fuzzers or Mutation-based Testing.
By doing this, you can ensure that the data being sent is valid and expected and that your APIs are resilient to attacks by malicious actors looking to take advantage of them.
Ultimately, having confidence in the security of your web services should be a priority for every organization. You can do this by running security tests on them regularly.
Happy (security) testing! 🙃
Want more resources about API security testing? Make sure you download my Ultimate Guide to API Hacking Resources.