# Spectral OWASP API Security Ruleset
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](https://github.com/stoplightio/spectral-owasp-ruleset), you can use Spectral to see if your API is making any common security blunders.
## What is the OWASP API Security Top 10?
The [Open Web Application Security Project (OWASP)](https://owasp.org/) 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 have complied lots of resources including what they consider to be the [Top 10 mistakes](https://owasp.org/www-project-top-ten/) 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)](https://owasp.org/www-project-api-security/).
The API security top 10 covers the following topics:
1. [Broken Object Level Authorization](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa1-broken-object-level-authorization.md)
2. [Broken User Authentication](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa2-broken-user-authentication.md)
3. [Excessive Data Exposure](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa3-excessive-data-exposure.md)
4. [Lack of Resources & Rate Limiting](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa4-lack-of-resources-and-rate-limiting.md)
5. [Broken Function Level Authorization](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa5-broken-function-level-authorization.md)
6. [Mass Assignment](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa6-mass-assignment.md)
7. [Security Misconfiguration](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa7-security-misconfiguration.md)
8. [Injection](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa8-injection.md)
9. [Improper Assets Management](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xa9-improper-assets-management.md)
10. [Insufficient Logging & Monitoring](https://github.com/OWASP/API-Security/blob/master/2019/en/src/0xaa-insufficient-logging-monitoring.md)
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 convenience 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](https://meta.stoplight.io/docs/platform/71b92b2b5e388-style-guide-overview), or [via NPM as a JavaScript/TypeScript package](https://apisyouwonthate.com/blog/distribute-spectral-style-guides-with-npm).
## Spectral OWASP Ruleset
If you would like to give the [OWASP API Security Ruleset](https://github.com/stoplightio/spectral-owasp-ruleset) a try there are a few ways to use it, but we will use Spectral CLI installed via NPM:
```bash
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.
```bash
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](https://meta.stoplight.io/docs/spectral/e5b9616d6d50c-custom-rulesets), add your own rules, turn bits off they are causing trouble.
Once that file 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](https://meta.stoplight.io/docs/spectral/e5b9616d6d50c-custom-rulesets#overrides) if there are good reasons I'm ignoring the security advice.
## Limitations
Some of you may have already thought of this, but some of those security concerns are not something Spectral can detect, as it is looking at OpenAPI and that is only describing the surface level of the API. Anything happening inside the code, or at the SysOps concerns like using an old version of TLS), is inaccessible to Spectral.
Spectral can spot obvious issues that are described in the OpenAPI, or point out things which 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 doing to manage it all, adding functionality for people, fixing bugs, etc. We'll do a lot of that, when the community can pitch in we really appreciate it, and there is a lot more we can do with OWASP Security Rules together. See the [OWASP ruleset issues](https://github.com/stoplightio/spectral-owasp-ruleset/issues) for ideas!