Spectral OWASP API Security Ruleset

Phil Sturgeon
by Phil Sturgeon on September 26, 2022 9 min read

At first, people used Spectral to tell them if they were writing valid OpenAPI. Then it was used to see if their API matched their API Style Guide. Now, thanks to the Spectral OWASP API Security ruleset, you can use Spectral to see if your API is making any common security blunders.

You can also check out the Shared Style Guides version in Stoplight Platform as a part of our new Style Guide template offerings. You can also sign up below to receive notifications when new style guide templates are available.


What is the OWASP API Security Top 10?

The Open Web Application Security Project (OWASP) is a nonprofit foundation that works to improve the security of software. They maintain open-source software projects, have hundreds of local chapters worldwide with tens of thousands of members, and they run education and training conferences.

OWASP has compiled lots of resources, including what they consider to be the Top 10 mistakes being made in web applications in general. As API developers, we’re a bit more interested in their newer API-specific project, the OWASP API Security Top 10 (2019).

The API security top 10 covers the following topics:

  1. Broken Object Level Authorization
  2. Broken User Authentication
  3. Excessive Data Exposure
  4. Lack of Resources & Rate Limiting
  5. Broken Function Level Authorization
  6. Mass Assignment
  7. Security Misconfiguration
  8. Injection
  9. Improper Assets Management
  10. Insufficient Logging & Monitoring

That is a lot to think about, and thankfully Spectral is here to help.

How does Spectral handle API Security?

Spectral is a generic rules engine with a lot of conveniences built in for JSON/YAML-based API specifications like OpenAPI, JSON Schema, and AsyncAPI.

Anyone can program Spectral to peek into JSON/YAML files, tell it what to look for, and throw errors and warnings if it doesn’t like the look of what it finds.

If you are using OpenAPI, you can point Spectral at your openapi.yaml (or whatever you named it), and it can run a collection of rules (a ruleset) that somebody else made and distributed, either hosted on Stoplight using Shared Style Guides or via NPM as a JavaScript/TypeScript package.

Spectral OWASP Ruleset

If you would like to give the OWASP API Security Ruleset a try, there are a few ways to use it:

Spectral CLI installed via NPM:

npm install --save -D @stoplight/spectral-owasp-ruleset
npm install --save -D @stoplight/spectral-cli

With that setup, navigate your terminal to the working directory that contains your OpenAPI documents and use this command to create a new file which extends the NPM module we just installed.

echo 'extends: ["@stoplight/spectral-owasp-ruleset"]' > .spectral.yaml

Creating this local file acts as a “local ruleset” that extends the distributed ruleset. In its most basic form, this just tells Spectral what ruleset you want to use, but it will allow you to customize things, add your own rules, and turn bits off that is causing trouble.

Once that file is in place, you can run spectral lint {doc} to get a bunch of feedback on your API.

spectral lint api/openapi.yaml

Boy, did I get a lot of feedback.

  44:17      warning  owasp:api3:2019-define-error-responses-400:400 response should be defined.. Missing responses[400]         paths./upload.post.responses
  44:17      warning  owasp:api3:2019-define-error-responses-429:429 response should be defined.. Missing responses[429]         paths./upload.post.responses
  44:17      warning  owasp:api3:2019-define-error-responses-500:500 response should be defined.. Missing responses[500]         paths./upload.post.responses
  45:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./upload.post.responses[201]
  47:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./upload.post.responses[401]
  53:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./upload.post.responses[403]
  59:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./upload.post.responses[409]
  65:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./upload.post.responses[422]
  86:17      warning  owasp:api3:2019-define-error-responses-400:400 response should be defined.. Missing responses[400]         paths./orders.post.responses
  86:17      warning  owasp:api3:2019-define-error-responses-429:429 response should be defined.. Missing responses[429]         paths./orders.post.responses
  86:17      warning  owasp:api3:2019-define-error-responses-500:500 response should be defined.. Missing responses[500]         paths./orders.post.responses
  87:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orders.post.responses[201]
  93:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orders.post.responses[401]
  99:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orders.post.responses[403]
 105:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orders.post.responses[422]
 129:17      warning  owasp:api3:2019-define-error-responses-400:400 response should be defined.. Missing responses[400]         paths./orders/{order}.get.responses
 129:17      warning  owasp:api3:2019-define-error-responses-429:429 response should be defined.. Missing responses[429]         paths./orders/{order}.get.responses
 129:17      warning  owasp:api3:2019-define-error-responses-500:500 response should be defined.. Missing responses[500]         paths./orders/{order}.get.responses
 130:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orders/{order}.get.responses[200]
 136:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orders/{order}.get.responses[401]
 142:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orders/{order}.get.responses[404]
 167:17      warning  owasp:api3:2019-define-error-responses-400:400 response should be defined.. Missing responses[400]         paths./orgs/{organization}.get.responses
 167:17      warning  owasp:api3:2019-define-error-responses-429:429 response should be defined.. Missing responses[429]         paths./orgs/{organization}.get.responses
 167:17      warning  owasp:api3:2019-define-error-responses-500:500 response should be defined.. Missing responses[500]         paths./orgs/{organization}.get.responses
 168:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orgs/{organization}.get.responses[200]
 174:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orgs/{organization}.get.responses[401]
 180:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./orgs/{organization}.get.responses[404]
 193:16  information  owasp:api2:2019-protection-global-safe      This operation is not protected by any security scheme.         paths./sites.get.security
 194:17      warning  owasp:api3:2019-define-error-responses-400:400 response should be defined.. Missing responses[400]         paths./sites.get.responses
 194:17      warning  owasp:api3:2019-define-error-responses-429:429 response should be defined.. Missing responses[429]         paths./sites.get.responses
 194:17      warning  owasp:api3:2019-define-error-responses-500:500 response should be defined.. Missing responses[500]         paths./sites.get.responses
 195:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./sites.get.responses[200]
 210:16  information  owasp:api2:2019-protection-global-safe      This operation is not protected by any security scheme.         paths./species.get.security
 211:17      warning  owasp:api3:2019-define-error-responses-400:400 response should be defined.. Missing responses[400]         paths./species.get.responses
 211:17      warning  owasp:api3:2019-define-error-responses-429:429 response should be defined.. Missing responses[429]         paths./species.get.responses
 211:17      warning  owasp:api3:2019-define-error-responses-500:500 response should be defined.. Missing responses[500]         paths./species.get.responses
 212:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./species.get.responses[200]
 227:16  information  owasp:api2:2019-protection-global-safe      This operation is not protected by any security scheme.         paths./supervisors.get.security
 228:17      warning  owasp:api3:2019-define-error-responses-400:400 response should be defined.. Missing responses[400]         paths./supervisors.get.responses
 228:17      warning  owasp:api3:2019-define-error-responses-429:429 response should be defined.. Missing responses[429]         paths./supervisors.get.responses
 228:17      warning  owasp:api3:2019-define-error-responses-500:500 response should be defined.. Missing responses[500]         paths./supervisors.get.responses
 229:15        error  owasp:api3:2019-rate-limit                  All 2XX and 4XX responses should define rate limiting headers.  paths./supervisors.get.responses[200]
 254:16  information  owasp:api2:2019-protection-global-safe      This operation is not protected by any security scheme.         paths./maps/sites/{uuid}.get.security

My API has several endpoints which are not protected, which for some public APIs may well be ok but can lead to misuse. That could be solved with rate limiting, but looks like I forgot to set that up too as no rate limit headers are described.

Either I forgot to add rate limiting to the API, or I forgot to document the headers so API consumers won’t know to look out for them, which means, either way, I need to fix something. Thanks for noticing Spectral!

I’ll get to work fixing what I can of this API, and perhaps I’ll create some overrides if there are good reasons I’m ignoring the security advice.

Quick Start with Stoplight Platform:

Stoplight Platform comes with a set of public style guides that can be enabled within your Stoplight workspace with a single click. The OWASP Top 10 is the latest edition to the list.

To use these rules:

  1. Go to your Stoplight workspace.
  2. Create a style guide project OR edit a project that has an API.
  3. Select Manage Style Guides.
  4. Enable OWASP Top 10 from a list of public style guides.

Screenshot of Stoplight Public Style Guides tool

You can then:

Limitations

Some of you may have already thought of this, but some of those OWASP security concerns are not something Spectral could ever detect, as it is looking at OpenAPI, and that is only describing the surface level of the API. Anything happening inside the code, or SysOps concerns like using an old version of TLS, would all be inaccessible to Spectral.

Spectral can spot obvious issues that are described in the OpenAPI or point out things that are missing from the definition, but using it alone will not guarantee your API is now completely safe from all forms of attack. Consider it to be one tool in your toolkit for spotting problems rather than a single litmus test.

Open-source Contributions

There are also more rules that could be written, which will increase confidence with each addition. Stoplight is dedicated to open-source, and we release as much of our software as we can – not all of it; we have staff to pay . Having so much open source can be tricky as it increases the work that needs to be done to manage it all, adding functionality for people, fixing bugs, etc. We’ll do a lot of that, but when the community can pitch in we really appreciate it, and there is a lot more we can do with OWASP Security Rules together.

For more security best practices, check out our webinar below.

Share this post

Stoplight to Join SmartBear!

As a part of SmartBear, we are excited to offer a world-class API solution for all developers' needs.

Learn More
The blog CTA goes here! If you don't need a CTA, make sure you turn the "Show CTA Module" option off.

Take a listen to The API Intersection.

Hear from industry experts about how to use APIs and save time, save money, and grow your business.

Listen Now