Modern web applications, especially single-page applications, are often built upon APIs that serve data to more than just HTML-based web browsers. These applications do not rely on web forms for authentication. Instead, a common approach is to create an API route that accepts a POST
request with a JSON payload containing the user’s credentials. The server will then return an authorization token as part of the JSON response. After the initial login, the API expects only the token to be sent on all subsequent requests to protected routes.
Stackhawk’s scanner, HawkScan, supports this scenario by default. Here we will focus on how to define both the username and password fields, values, and payload type for HawkScan. We’ll also add a tokenExtraction
section for obtaining the value of the token from the JSON response and a tokenAuthorization
section for using the token on all subsequent API calls.
Note: This API is designed to be intentionally minimal for authentication testing purposes only. It is not meant to showcase scan results.
Prerequisites:
You will need accounts with StackHawk and GitHub. You will also need some familiarity with Git, Curl, and Docker. Familiarity with Python and Django is helpful, but not necessary.
You should have the following software installed on your computer.
Docker: (download from docker.com)
Python 3: (
[brew](http://<https://brew.sh/>) install python
on MacOS)jq: (‘brew install jq’ on MacOS)
Clone and run hawkling-api
Clone the hawkling-api repository and install the project dependencies outlined in the README.md file.
In your terminal, navigate to the hawklingAPI/hawlingAPI/
directory that contains the manage.py
file and run the application.
python manage.py runserver
Visit http://localhost:8000/ in your browser and verify you can access the home path.
Navigating hawkling-api
The hawkling-api contains 3 paths: /
, login/
, and kaakaww/
. The first two routes are publicly available, meaning all the content at each path is freely accessible. The third route, kaakaww/
, requires a Bearer token in order to display the greeting message.
If you try to access kaakaww/
without a token, you’ll receive a message asking for credentials. While the message says “credentials,” what it really means is an “Authentication token was not provided.”.
{
"detail": "Authentication credentials were not provided."
}
First, obtain your access token by POSTing credentials to login/
curl -X POST -H "Content-Type: application/json" \
-d '{"username":"admin", "password":"adminpassword"}' \
http://localhost:8000/login/ | jq
A successful post should return a response similar to the following
{
"refresh": "YyyYYYyYY.YyyYYYyYY",
"access": "xxxXXXxXXxx.xxxXXXxXXxx"
}
Next use the value of the access
token to make a request to kaakaww/
curl -X GET http://localhost:8000/kaakaww/ \
-H 'Authorization: Bearer xxxXXXxXXxx.xxxXXXxXXxx'
A request with a valid token will yield a friendly greeting
{
"message": "Hello, Hawkling!"
}
Configure and Run HawkScan
To scan the application, you’ll need to add the stackhawk.yml
file to your project directory. Filling out the file is as simple as describing the process we just stepped through using cURL.
authentication:
Most often, when a user interacting with your application will innately understand whether they’re logged-in or logged-out based on context clues. To enable HawkScan to simulate scanning your application as an authorized user, we need to specifically define those clues.
In this case, when I made a request to kaakaww/
without a Bearer token, I noticed the response contained the word “detail”. Likewise, when I made a request to kaakaww/
with a Bearer token, the response changed to include the word “message.” Consequently, “detail” becomes my loggedOutIndicator
, and “message” becomes my loggedInIndicator
.
usernamePassword:
Knowing that the hawkling-api accepts POST
requests and expects a JSON payload, we specify the data expected with, type: JSON
, and define the loginPath
as login/
. Next, we need to tell the scanner the names of the credential fields (usernameField
and passwordField
) to be defined in the JSON payload. Lastly, we’ll specify the actual values of the usernameField
and passwordField
as scanUsername
and scanPassword
. Simply put, these fields recreate our cURL command to login/
.
tokenExtraction:
Following the POST request to login/
, the API returns a token in the response. type:
TOKEN_PATH
tells the scanner we’re expecting the token to be located in a JSON payload and value
defines the name of the token to be extracted.
tokenAuthorization:
After the scanner has extracted the token, it needs to understand how to use it for making subsequent calls to other API routes. type
, value
, tokenType
all describe how the scanner should use the token, similar to the cURL command we previously made to kaakaww/
.
testPath:
Once the token is obtained, path
tells HawkScan which route to use to verify authentication is working before running a scan and success
gives the scanner an indicator that the request to path
was successful.
app:
applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
env: Development
host: http://localhost:8000
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 that you’ve added the stackhawk.yml
file to your project directory, replace the value of applicationId
for the corresponding value in the StackHawk web platform.
Lastly, in your terminal, navigate to the directory where you saved the stackhawk.yml
file and run the docker command to initiate the scanner!
docker run --rm -v $(pwd):/hawk:rw -it \
-e API_KEY=hawk.xxxxxxxxxxxxxxxxxxxx.xxxxxxxxxxxxxxxxxxxx \
stackhawk/hawkscan:latest
Notes
cURL is a great way to orient yourself around your applications. As you become more familiar with how your applications work, configuring HawkScan quickly becomes a walk in the park. If you need more help configuring HawkScanyou can always reach out to support@stackhawk.com. We’re more than happy to help get you up and running!
Adding security testing for authenticated app routes to your development processes ensures complete visibility into any vulnerabilities your application has before they’re found in production by the wrong crowd. If you’d like more information on how to move HawkScan from your local environment to your build pipeline, learn how to use StackHawk with Travis CI and Docker-Compose!