Finding Attack Vectors using API Linting
2024-5-1 00:0:0 Author: securityboulevard.com(查看原文) 阅读量:1 收藏

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.

AIE

Techstrong Podcasts

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.

What is “Linting”?

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.

API Linters?

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.

Setting up 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.

Building your first Spectral rule

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.

Rule breakdown

  • I like to use descriptive rule names. For this example, I prefixed it with “apihacker” so I could determine that it was a custom rule I had made. I stored this rule in a file called apihacker.rules.yaml
  • The description is useful for describing its purpose. The message will be displayed in the console output. Make sure you output something that reminds you what action to take.
  • If you don’t include a severity, it defaults to “warn”. Here’s the thing… if it’s important enough for you to build a rule for it… it really should be a severity of error or warn. We are not doing an API design review here; we only want to look for critical stuff. This is also why we use our own rules, instead of the built-in ones… to reduce the noise.
  • The given property is conceptually similar to a selector in CSS in that it indicates the part of the document to which rules should be applied. The syntax is JSONPath, which is similar to XPath. Make it easy on yourself, and use the JSONPath Online Evaluator to help you construct valid paths. It’ll save you time and headaches.
  • The then part of the rule defines which function to apply to the given path. The two main keywords to concern yourself with are field and function. There is a lot of nuance to this. You can read the details here. For this rule, I am doing a pattern match to ensure that no securityScheme has a scheme set to “basic”.

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.

Running your Spectral rules against your target

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.

Building some useful rules for API hacking

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.

Detect endpoints that have no security definition

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

Detect endpoints that aren’t using a bearer token

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

Run our new rules

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.

OWASP API Security Top 10 spectral rules

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.

Conclusion 

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.

One last thing…

API Hacker Inner Circle

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


文章来源: https://securityboulevard.com/2024/04/finding-attack-vectors-using-api-linting/
如有侵权请联系:admin#unsafe.sh