---
title: "Inject Multiple Cookies and Tokens"
description: "Multiple Cookie & Token Injection Authentication"
url: https://docs.stackhawk.com/hawkscan/authenticated-scanning/inject-multiple-cookies-and-tokens/
---

# Inject Multiple Cookies and Tokens

## Overview

Sometimes authentication is not performed with just a username and password. For example, API key access or third-party authentication services like OAuth require custom tokens.

To support this type of authentication, HawkScan supports externally supplying authorization tokens with the `authentication.external` configuration.

The `authentication` section of the `stackhawk.yml` will have 3 parts:

1. Logged in/out indicators
   - How HawkScan checks it is logged in throughout the scan.
2. Auth(Z)
   - Using `authentication.external` to tell HawkScan you will be injecting valid cookies or tokens for authorization
3. Test Path
   - How HawkScan sees if it successfully logged in

Make sure your file has all 3 of these parts filled out.

## YAML for Injecting Credentials

#### Injecting Tokens:

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  env: Test
  host: ${APP_HOST:http://localhost:3000}
  authentication:
    # Paths that HawkScan checks to see if it is still logged in during the scan
    loggedInIndicator: "HTTP.*2[0-9][0-9]\\s*O[kK](\\s*)|HTTP.*3[0-9][0-9].*" # Change me
    loggedOutIndicator: "HTTP.*4[0-9][0-9](\\s*)Unauthorized.*" # Change me
    # Auth(Z) External Injection - this example will result in 2 request headers:
    #   Authorization: Bearer ${AUTH_TOKEN}
    #   AnotherToken: ${ANOTHER_TOKEN}
    external:
      values:
          # Indicates whether the injected value is a cookie or token
        - type: TOKEN
          # If specified tokenType will be prepended the header value e.g. "Bearer xxxxxxxxx"
          tokenType: Bearer
          value:
            # Name of the request header
            name: Authorization
            # Value of token
            val: ${AUTH_TOKEN}
        - type: TOKEN
          value:
            name: AnotherToken
            val: ${ANOTHER_TOKEN}
    # A path that can only be seen when successfully logged in. HawkScan will check this path to see if log in was successful
    testPath:
      path: /mysettings
      success: ".*200.*"
      requestMethod: GET
```

#### Injecting Cookies:

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  env: Test
  host: ${APP_HOST:http://localhost:3000}
  authentication:
    # Paths that HawkScan checks to see if it is still logged in during the scan
    loggedInIndicator: "HTTP.*2[0-9][0-9]\\s*O[kK](\\s*)|HTTP.*3[0-9][0-9].*" # Change me
    loggedOutIndicator: "HTTP.*4[0-9][0-9](\\s*)Unauthorized.*" # Change me
     # Auth(Z) External Injection
    external:
      values: 
          # Indicates whether the injected value is a cookie or token
        - type: COOKIE
          value:
            # Name of the cookie
            name: JSESSIONID
            # Value of the cookie
            val: ${AUTH_COOKIE}
        - type: COOKIE
          value:
            name: EXTRAID
            val: ${ANOTHER_COOKIE}
    # A path that can only be seen when successfully logged in. HawkScan will check this path to see if log in was successful
    testPath:
      path: /login-multi-check #Change me
      success: ".*200.*"
      requestMethod: GET
```

## YAML Sections in Detail

#### Injecting Authorization with `.external`

The first half of your `authentication` section in your `stackhawk.yml` will be to tell HawkScan you are using an externally supplied authorization.

The `.values` will be a list off cookies or header tokens or both that will be injected into each request that StackHawk sends to the application.

For the `.type` of `TOKEN`, headers are added to each request in this format “`.name:` `.tokenType .val`”.

For the `.type` of `COOKIE`, cookies are added to each request in this format “Cookie: `.name`=`.val`”.

Values for tokens and cookies will need to be added at run time either in your run command or as stored secrets. We do not recommend adding it directly to your `stackhawk.yml` file. This is both for security reasons, but also to avoid errors if the token expires.

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  env: Test
  host: ${APP_HOST:http://localhost:3000}
  authentication:
    loggedInIndicator: "\\QLog out\\E"
    loggedOutIndicator: "\\QLog in\\E"
    external:
      values: 
        - type: COOKIE
          value:
            name: JSESSIONID
            val: ${AUTH_COOKIE}
        - type: TOKEN
          tokenType: Bearer
          value:
            name: Authorization
            val: ${AUTH_TOKEN}
    testPath:
      path: /authenticated/path
      success: '.*200.*'
```

#### Maintaining the Session

Unlike other authentication types, the session is maintained by injecting the headers and cookies into each request as indicated in the `stackhawk.yml`.

#### Test Paths and Logged In/Out Indicators

No matter what type of Authorization/Authentication your app is using, HawkScan requires `.testPath`, `.loggedInIndicator` and `.loggedOutIndicator`.

Test Path:

A `testPath` configuration needs to be provided to verify HawkScan authenticated its session correctly before scanning the application. The `testPath` configuration also provides `requestMethod` and `requestBody` options to support alternate HTTP request verbs, such as `POST` or `PUT`. The default action is `GET`.

Your `testPath` should be a path that HawkScan can only access when successfully logged in. This could be a path like “/dashboard” or “/accountdetails”

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  env: Test
  host: ${APP_HOST:http://localhost:3000}
  authentication:
    loggedInIndicator: "\\QLog out\\E"
    loggedOutIndicator: "\\QLog in\\E"
    testPath:
      path: /login-multi-check
      success: ".*200.*"
      requestMethod: GET
```

Logged In/Out Indicators

Throughout the scan, HawkScan will check to see if it is still logged in by the `.loggedInIndicator` and `.loggedOutIndicator`. These are regex strings to match against http responses from requests in the web application.

A `.loggedInIndicator` could be a “Log Out” or ”Sign Out” button a user would see if logged in. An example of a `.loggedOutIndicator` would be a “Log In” button on the sign in page. These can also leverage http status codes from the response.

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  env: Test
  host: ${APP_HOST:http://localhost:3000}
  authentication:
    loggedInIndicator: "HTTP.*2[0-9][0-9]\\s*O[kK](\\s*)|HTTP.*3[0-9][0-9].*"
    loggedOutIndicator: "HTTP.*4[0-9][0-9](\\s*)Unauthorized.*"
    testPath:
      path: /authenticated/path
      success: '.*200.*'
```

### Example Multiple External Cookie Authorization

This scenario will use the following route layout.

```text
GET       /login-code
GET       /login-form-multi
POST      /login-form-multi
GET       /login-multi-check <- protected route
```

#### Detailed Configuration

You would want a `stackhawk.yml` configuration like this.

```yaml title="stackhawk.yml"
app:
  applicationId: xxXXXXXX-xXXX-xxXX-XXxX-xXXxxXXXXxXX
  env: Test
  host: ${APP_HOST:http://localhost:3000}
  authentication:
    loggedInIndicator: "HTTP.*2[0-9][0-9]\\s*O[kK](\\s*)|HTTP.*3[0-9][0-9].*"
    loggedOutIndicator: "HTTP.*4[0-9][0-9](\\s*)Unauthorized.*"
    external:
      values:
      - type: COOKIE
        value:
          name: "XLOGINID"
          val: ${XLOGINID}
      - type: COOKIE
        value:
          name: "JSESSIONID"
          val: ${JSESSIONID}
    testPath:
      path: /login-multi-check
      success: ".*200.*"
      requestMethod: GET
```

In the above configuration we are specifying `.external.values[0].val=${XLOGINID}` and `.external.values[0].val=${JSESSIONID}` to allow the authorization cookies to be passed in as an environment variable at runtime.

Now create a script to generate the authorization cookies. This is an example using a customized route in the [javaspringvulny](https://github.com/kaakaww/javaspringvulny) project to generate a session cookie and a login cookie as well as parsing and saving the `_csrf` token. It logs in the user and then runs hawk scan with those cookie values passed as environment variables.

```bash
#!/usr/bin/env bash

# Request login (XLOGINID) and session (JSESSIONID) cookies from server and saves them to the cookie-jar.txt file.
curl -c  cookie-jar.txt https://localhost:9000/login-code
# Parses cookie-jar.txt file to get the JSESSIONID.
JSESSIONID=$(awk 'match($0, /JSESSIONID.*/){print substr($0, RSTART + 11, RLENGTH)}' cookie-jar.txt )
# Parses cookie-jar.txt file to get the XLOGINID.
XLOGINID=$(awk 'match($0, /XLOGINID.*/){print substr($0, RSTART + 9, RLENGTH)}' cookie-jar.txt)
# Request page with cookie-jar.txt cookies and extract the _csrf token from the response
CSRF=$(curl  -b  cookie-jar.txt \
    https://localhost:9000/login-form-multi | awk 'match($0,/_csrf".*/) { print substr($0, RSTART+14, RLENGTH -17)}')

# Log into the mutli cookie endpoint using XLOGINID and JSESSIONID cookies (stored in cookie-jar.txt) and username/password.
# This example also uses the XLONGID as a paremeter passed to the server in the request body.
curl -v -k  \
  -d "_csrf=${CSRF}&loginCode=${XLOGINID}&username=user&password=password&remember=on"  \
  -b  cookie-jar.txt \
  -H  "Content-Type: application/x-www-form-urlencoded" \
  "https://localhost:9000/login-form-multi"

# Run HawkScan injecting local variables as environment variables
hawk scan -e JSESSIONID=${JSESSIONID} -e XLOGINID=${XLOGINID}
```

### Authorized GET Request to `/login-multi-check`

```http
GET /login-multi-check HTTP/1.1
Host: localhost:9000
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:109.0) Gecko/20100101 Firefox/114.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate, br
Connection: keep-alive
Cookie: JSESSIONID=CDDC53E08070E78BF0A8C8F240B2157E; XLOGINID=a30c2167-87c4-4905-9554-66e58a64289c
```
