Best Practices: Security Vulnerability Testing
Testing your APIs for security vulnerabilities is essential if they are meant to be made available publicly on the internet. A large number of attacks can be used to compromise your API and its infrastructure with severe consequences if they succeed, as we have seen with the Playstation Network outage and the Twitter security breach. Ensuring that your API is not vulnerable needs to be in the mind of all involved roles during an APIs lifecycle.
Static Code Analysis
Often the root cause for a security vulnerability lies in the source code itself, for example not correctly parsing or handling input parameters could open for injection, buffer overrun or out-of-bounds attacks. Many modern static-code analysis tools have basic support for detecting these kinds of errors - and there are more specialized tools available. Detected errors should be given a high priority and the analysis should be part of automated build and test processes - so that corresponding errors are detected immediately.
Simulate Functional Attacks
Many security attacks are directed at the functionality of an API, for example by injecting malicious SQL scripts into query arguments, sending invalid data as form input or attempt secondary cross-site scripting attacks. To assess that an API is not correspondingly vulnerable, these attacks can easily be simulated with basic tools:
- SQL injection attacks - A login call that looks up credentials in a database should be tested with known SQL injection attacks to see if the can log in without supplying credentials.
- Cross-site scripting - An API that allows you to store or update content that is made available via a web interface needs to be checked for secondary cross-site scripting attacks; attempt to insert client side scripts or malicious attachments and validate that the corresponding web interface displays these in a non-harmful way.
- Tokens and sessions - Hijacked session or access tokens can be used by attackers to gain access to systems they should have access to; make sure that your API handles this by re-using tokens in an “unexpected” way.
- Fuzzing - More-or-less randomly making API calls with random input attempting to put the API in an inconsistent state that results in some other vulnerabilities or error messages that disclose sensitive system information.
Combine Security Tests with Load Testing
Putting a system under high load is a great way to provoke erratic behavior. Both the component itself and its dependencies (databases, the file system, other APIs, legacy systems, etc) are all put under pressure which can result in memory leaks, lock/race conditions, et c. This in turn can induce security vulnerabilities which can be exploited. Therefore, running the security tests simultaneously with a load-test is a great way to further ensure that your system isn’t correspondingly vulnerable.
If possible it is recommended to run security load tests for a prolonged period of time (hours to days) to identify slowly building contention or lock issues and corresponding security vulnerabilities. Also, be sure to add security-related assertions to the load-test itself, for example checking for sensitive system information in load-related error messages.
Analyze Error Messages
Error messages are a common source of security vulnerabilities; if the API does not sufficiently handle error conditions that could be provoked by an attacker, the resulting error page could conceal detailed information about the backend system and its technologies. Some examples;
- Attempting an SQL injection attack might fail but show a database error message that discloses information about tables, users, database version, et c - which could be used in subsequent more targeted attacks.
- Sending out-of-bounds data or invalid message payloads could throw errors that disclose which message parsers or frameworks that are being used - which could be used to compromise known issues within these.
Both when running standard functional test and simulated security tests, make sure that you assert expected or unexpected error messages for not disclosing any kind of sensitive system information that could be exploited.
Assess 3rd Party Dependencies For Vulnerabilities
Often an API integrates with other APIs - either internal or external - which in turn could be vulnerable. End users will likely see these external dependencies as part of your API and thus your problem. Contact the external API owner and ask them about their security efforts or arrange to run your own simulated security attacks with them.
Make Security Part of the Process
Make ure to assess security just as you would with other non-functional requirements like performance and availability. Make sure you foster corresponding awareness in your entire team - developers, testers, operations and managers. If your API reaches a large audience and/or exposes sensitive customer data, always add security related requirements to your backlog or project definition. Don't forget to allocate required time in your plans and schedules for proactive security testing and assessments - just as you would for performance testing.