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:
- Broken Object Level Authorization
- Broken User Authentication
- Excessive Data Exposure
- Lack of Resources & Rate Limiting
- Broken Function Level Authorization
- Mass Assignment
- Security Misconfiguration
- Injection
- Improper Assets Management
- 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:
- Go to your Stoplight workspace.
- Create a style guide project OR edit a project that has an API.
- Select Manage Style Guides.
- Enable
OWASP Top 10
from a list of public style guides.
You can then:
- Use the style guide as-is to automatically lint your API files
- Disable individual rules that do not follow your organization’s standards
- Reuse and customize rules to meet your needs
- Enforce them in your CI/CD pipeline
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.