If you ever encounter a target API developed by a team that publishes detailed API documentation following the OpenAPI Specification (OAS), you’re in the money baby.
Let me explain why.
Think about it for a second. OAS is a language-agnostic way to describe a RESTful API that people can use to generate code stubs and documentation. Developers love to design their APIs with types and examples for every endpoint before they even start implementing it.
They call it design-first API development.
I call it a blessing in disguise.
Even if they don’t use a design-first methodology, tooling exists to parse their code and generate OpenAPI-compatible spec docs. This means that through inference, you may be able to understand how an API functions.
I say MAY understand because developers aren’t perfect and may miss things from time to time. And therein lies the opportunity.
While I have already explored how to extract artifacts from OpenAPI docs to help attack APIs, the technique I want to show today is different.
In this article, I will show you how to weaponize developer tools used for API design and design reviews against them. In fact, we will use these same tools to discover potential attack vectors in the very APIs they are trying to build and secure.
There tools are called “linters“, and support the technique of “linting“.
Let’s get started.
Linting is the process of running a program that analyzes code and/or text for potential errors. This includes checking for syntax errors, potential bugs, stylistic errors, and suspicious constructs.
Linting helps improve the quality and consistency of code by enforcing coding standards and finding issues that might otherwise go unnoticed until later in the development process. It can be particularly useful in dynamic or loosely typed languages, where some types of errors are not caught until runtime.
Today, most programming languages have some form of linting tool available, often integrated into development environments or available as standalone tools. And it just so happens that API linters exist too.
Yep. They exist.
API linting is the process of analyzing API descriptions to ensure they conform to certain standards, best practices, and specifications. Much like code linting, API linting helps identify issues such as inconsistencies, errors in syntax, and deviations from best practices in API definitions. This is particularly relevant when APIs are defined using standard specification formats like OpenAPI.
Developers and architects use API linters to validate spec docs and complete design reviews.
As API hackers, we can weaponize these linters to point out potential weaknesses in the API that may be more exploitable.
There are several API linters on the market. However, there is one open-source tool for API linting that makes it damn near trivial for API hackers to use.
It’s called Spectral.
Spectral processes API descriptions or any JSON/YAML-based structures by applying a set of rules defined by the user or by default configurations. These rules can check for various issues or enforce specific standards, making it a powerful and versatile tool for us too.
Let me show you how to set up and use Spectral.
You can install Spectral using npm or yarn.
NPM: npm install -g @stoplight/spectral-cli
YARN: yarn global add @stoplight/spectral-cli
Once installed, you can build your first rule for it and test it against OAS-compatible API documentation via the command line.
A typical Spectral rule is written in YAML. You can find the documentation here.
Spectral comes with two built-in rulesets: OpenAPI and AsyncAPI. You can look closer at those if you like. However, I want to show you how to build your own rules so you can weaponize the tool to find things that matter to you.
Let’s start with something simple. Let’s say you want to call out if HTTP Basic Auth is being defined in the API docs. It might look something like this:
rules:
apihacker-no-basic-auth:
description: "Basic Auth is a weaker form of authentication that really shouldn't be used in APIs"
message: "Security schema uses HTTP Basic Auth. Check to see if that can be abused. (CWE-522)"
severity: error
given: $.components.securitySchemes[*]
then:
field: scheme
function: pattern
functionOptions:
notMatch: basic
The rule is self-evident if you have ever looked at YAML-based rules for anything. But let me point out a few things, just in case.
apihacker.rules.yaml
The rules are pretty easy to build if you get the JSONPath right in the given property and apply the correct function to detect what you are after.
Now, let’s run it.
Using spectral at the command line is simple. Just point it to your target API documentation and the ruleset you’ve built, and let it do its API linting black magic.
spectral lint apidoc.json --ruleset apihacker.rules.yaml -f pretty
As you can see, since this API document includes a security scheme that uses HTTP Basic Auth, the linter detected it and let us know.
By the way, there are other useful formats you can pass to the -f option. While I was using “pretty” to make it easy to read on the command line, you can use “json”, “html”, or “text” if you want the output structured differently.
OK. Now that you know how to build and run rules with Spectral, let’s create a few more useful ones to complete the picture.
It would be pretty arrogant of me to say, “Thou shall use my API hacking rulesets.” Only you will know what’s important in your engagement with your targets, so only you will know how to tailor your specific rulesets.
In fact, I typically find myself tailoring my rulesets based on individual targets as I start to understand their specific API documentation.
But let me give you a couple of examples that might be useful starting points for you to build your own rules.
If the API documentation is fully up to spec, it should describe how security is applied against an endpoint, usually mapped to the object(s) defined in the securityScheme. You can learn more about how OpenAPI specs describe security here.
The easiest way to do this is to check if the endpoint path even defines a security property.
apihacker-security-defined:
description: "Any endpoint that has no security defined should be closely looked at to see if it truly is an unauthenticated endpoint"
message: "Check to see if this endpoint runs with no security defined"
severity: warn
given: $.paths.*.*
then:
field: security
function: truthy
To change things up a bit, let’s create an additional rule that will look at all endpoint paths that define HTTP action verbs we care about and make sure they match against a custom security scheme we know about. I am going to run this against the Damn Vulnerable RESTaurant API documentation, which defines a scheme they call “OAuthPasswordBearer”.
apihacker-no-bearer-token:
description: "Any endpoint that does not have some sort of bearer token should be looked at closely for auth method"
message: "Check to see if this endpoint should run without a bearer token"
severity: error
given: $.paths[*][get,put,post,patch,delete,options,head]..security.*
then:
field: OAuthPasswordBearer
function: truthy
Time to run our new rules.
spectral dvRestaurant.json –rules ../spectral/apihacker.rules.yaml -f pretty
Oh, how sweet it is. In just a couple of seconds, we can see precisely which potential attack vectors we should examine more closely.
So, I have a surprise for you. Phil Sturgeon has led an effort to produce a ruleset dedicated to OWASP’s API Security Top 10.
You can find the Spectral OWASP Security Ruleset here.
You can install it locally using: npm install --save -D @stoplight/spectral-owasp-ruleset@^2.0.1
Phil also has a decent writeup about it that you should check out.
The ruleset is pretty robust. But remember that it is designed for developers and architects to use as part of API design reviews. So there will be a lot of noise that may feel like false positives.
My suggestion? Look closely at the ruleset of the package and transcribe that into your own custom ruleset. Extract the things that matter to YOU.
That’s what I did. And it’s helped to keep me focused on what matters for my targets.
Oh, one last thing. Spectral is pretty cool in everything it does. However, I had several false starts when I found the documentation for its rules a bit open-ended. Then I found Microsoft published their Spectral ruleset for APIs built in Azure.
That helped me to hone in on some of the nuances of JSONPath and the more complex functions to use in the then clause. Maybe it will help you too.
You might also like to check out Digital Ocean’s ruleset or maybe read up on how Postman uses spectral rules for API linting and API governance.
As API hackers, understanding how developers build and review API documentation can be hugely valuable. But being able to weaponize their tools to help us find potential attack vectors in their APIs — that’s priceless.
Spectral is an excellent API linter that can do just that. It provides a platform for effectively enforcing standards and identifying deviations that could lead to security risks.
By customizing API linting rules and employing them judiciously, you can expose and address weaknesses in your target APIs before your adversaries exploit them.
I hope I’ve opened your mind to new possibilities for effectively leveraging API documentation. As API development processes mature and these spec docs become more descriptive, it becomes easier for us to understand what to attack.
Have fun with it.
Have you joined The API Hacker Inner Circle yet? It’s my FREE weekly newsletter where I share articles like this, along with pro tips, industry insights, and community news that I don’t tend to share publicly. If you haven’t, subscribe at https://apihacker.blog.
The post Finding Attack Vectors using API Linting appeared first on Dana Epp's Blog.
*** This is a Security Bloggers Network syndicated blog from Dana Epp's Blog authored by Dana Epp. Read the original post at: https://danaepp.com/finding-attack-vectors-using-api-linting