Manipulating APIs for Security Test Automation
We perform application-level security assessments of APIs quite frequently. About a year ago I was working on a project with a large REST API. Roughly 1,300 routes implemented across dozens of micro-services with a very complex role based authorization framework. There was no API documentation at all. A developer emailed me a Postman file with a few dozen queries and wished us luck.
Needless to say I spent a lot of time discovering what the API did and building a test client to use the API.
A few weeks later I started a similar project. This time the project had Swagger files defining all of their micro-services. Good, right? Wrong. I was on the project about a week when I learned that a) the Swagger files really didn't define behavioral characteristics of the API and b) they had stopped maintaining the Swagger files.
Argh
This got me really frustrated. Discovering hidden or unknown content is always part of a security assessment but that shouldn't be the primary task! We wasted a lot of time reverse-engineering an API from internal wiki documents and source code snapshots. We would find the routes pretty easily but deducing the full resource definitions would be another task. Just saying "Our API uses JSON" is not enough. Lastly we had to work out resource state dependencies. The API won't let you POST a /fizz
until you've already PATCHED /buzz/{buzz_id}
with the fizz_name
field? That's going to take some time to figure out.
The problem was that besides being less than fully documented these APIs were not designed for testability. If you can't even stimulate some of the deeply buried logic within application it become far more difficult to make progress using automation. A security scanner is useless if every request is banging up against the same validation check again and again.
Restrike
I built a tool, called Restrike, which helps manipulate REST APIs into testable states so that security test automation is effective. Restrike is a Python package with a set of API modeling classes. We use these modeling classes to describe the API's testable surface area in terms of Routes (methods, URIs, and content) and Resources. There is also a hook system for code to automate the usage of the declarative API model. This covers basics such as how to authenticate and how to recognize if the server is reporting an error.
This modeling phase can be done manually (Python code), by observing API traffic, or by using a Postman, Swagger, or SoapUI file as a starting point.
What do we get out of this effort?
- Test Client: The API model is implemented in Python and creates a convenient Python programming interface for sending requests to the server.
- Test Framework: Restrike has pytest plugins which makes it very easy to write automated security tests.
- IPython/Jupyter Shell: The Restrike model is easy to use by hand for generating API requests.
It may not sound like much but the biggest payoff is that the API becomes uniform and testable. Uniformity may not be important to software developers but it is essential for our work because we assess many APIs. We need them to be consistent so we can create common tooling to find security vulnerabilities.
Once the API interfaces is uniform it is easy to write tests that assert security properties across the entire API. Say for example you have an opaque identifier, buzz_id
, and that whenever a request is made that uses buzz_id
the request should be checked to make sure that the authenticated user is entitled to view or edit that buzz_id
(OWASP 2017 A5 Broken Access Control).
Restrike makes it possible to write a simple test that checks for this all too common insecure direct object reference vulnerability:
- Make sure that Restrike can make a valid call to the API that returns an OK result as an authenticated user.
- Create or get a Resource identifier.
- Log into a secondary account.
- Attempt to access the resource using the identifier under the secondary account.
Release?
We have found Restrike useful on the types of projects that Carve works on but it is a niche tool. I'd love to know if more people are interested in using this tool.