Security as Documentation
Every developer knows the importance of good documentation regardless of whether you’re working on your first ‘Hello World’ program or a complex corporate monolith. Effective documentation can make or break the experience you have when interacting with someone else’s codebase. And, if you’re being honest, it’s likely come in handy when dusting off the cobwebs to one of the many projects you sent to live on the island of misfit toys over the years.
Beyond the typical value drivers like adoption and maintainability, good documentation, specifically for APIs, is critical to your application’s security posture. This is especially relevant today given modern web development’s heavy reliance on SPAs + APIs. If you were to only test the frontend JavaScript, your visibility into the vulnerabilities that haunt your application would be sorely lacking. Additionally, if your documentation is only half baked or incomplete, you face the same issue.
In addition to greater visibility, good API documentation increases the efficacy associated with automated security testing. Rather than relying on the spider to “discover” your API, pre-seeding the scanner with your OpenAPI spec takes the guesswork out of the process. It also leads to better test results since the scanner can infer how to communicate with your API based on defined inputs.
Good Code Documents Itself
But what if you haven’t yet added an OpenAPI spec to your project? Don’t allow a lack of documentation to keep you from shipping secure code. OpenAPI is widely adopted, and as such there are a lot of tools available to help you get started. And given how easy it is to auto-generate Swagger Docs, not having documentation is no longer an excuse.
SmartBear has free online editor that can be used immediately to start building a OpenAPI file that will work with StackHawk: https://swagger.io/tools/swagger-editor/
For new projects, the industry recommended approach is to create an OpenAPI spec file and employ OpenAPI code-generators to stub out the endpoints for the desired server frameworks.
For existing projects, you may want to explore framework specific utilities:
Auto-Generating Swagger Docs for Django Projects
Let’s walk through adding the drf-yasg – Yet another Swagger generator to our hawkling-api codebase.
Clone the Repository
git clone https://github.com/kaakaww/hawkling-api.git
Install drf-yasg
pip install drf-yasg
Add drf-yasg as an installed app in settings.py
INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.messages',
'django.contrib.staticfiles',
'rest_framework',
'drf_yasg',
]
In urls.py import re_path
from django.urls
and add the following under from rest_framework import permissions
from rest_framework import permissions
#---ADD---
from drf_yasg.views import get_schema_view
from drf_yasg import openapi
schema_view = get_schema_view(
openapi.Info(
title="Hawkling API",
default_version='v1',
description="A minimal API",
),
public=True,
permission_classes=(permissions.AllowAny,),
)
Include the following paths in urls.py
re_path(r'^swagger(?P<format>\\.json|\\.yaml)$', schema_view.without_ui(cache_timeout=0), name='schema-json'),
re_path(r'^swagger/$', schema_view.with_ui('swagger', cache_timeout=0), name='schema-swagger-ui'),
re_path(r'^redoc/$', schema_view.with_ui('redoc', cache_timeout=0), name='schema-redoc'),
And that’s it! If you visit localhost:8000/swagger/ in your browser you should see existing routes have been documented and any new route you add to the API will be automatically included in the documentation.
Configure and Run HawkScan
We’ll now configure our stackhawk.yml file similarly to how we did in Part 3 of Security Testing Authenticated Routes series. The only difference is we’ll now add a section for the scanner to ingest the newly created OpenAPI specification.
We have a couple options for seeding HawkScan with our OpenAPI spec.
Option 1: Specify the relative path to either the .json or .yaml file in your project directory.
Option 2: Specify the relative path to pull the file from the target host.
Option 3: Define your API inline or directly within the stackhawk.yml file itself. This is very useful for initial testing or limiting the scope of the API you want to test.
For this example we’ll chose the Option 2 and add app.api: /swagger.json
to our config file.
app:
applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
env: Development
host: http://localhost:8000
api: /swagger.json. #<--- Add API Config Here
authentication:
loggedInIndicator: ".*message.*"
loggedOutIndicator: ".*detail.*"
usernamePassword:
type: JSON
loginPath: /login/
usernameField: username
passwordField: password
scanUsername: admin
scanPassword: adminpassword
tokenExtraction:
type: TOKEN_PATH
value: "access"
tokenAuthorization:
type: HEADER
value: Authorization
tokenType: Bearer
testPath:
path: /kaakaww/
success: ".*200.*"
Now run HawkScan as before
docker run --rm -v $(pwd):/hawk:rw -it \
-e API_KEY=hawk.xxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx \
stackhawk/hawkscan:latest
Notes
There is a reason that documentation is stressed so heavily during the development process. It has real tangible value both for humans and machines when interacting with your applications. Additionally, auto-generators like drf-yasg
help to take the heavy lifting out of the processes of creating and maintaining documentation, making it easier to automate critical business processes like security testing. Lastly, utilizing Swagger Docs in your security automation delivers test results with greater visibility and a higher degree of efficacy, ensuring confidence in the posture of your code as it’s pushed to production.