# 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!