Skip to content

Authentication in scanned applications

Authentication verification mechanism

Performs periodic verification of session validity using the configuration in JSON format.

The configuration contains an array of criteria for verifying the validity of the session. The mandatory fields are request, responseConditions with the nested mandatory fields url and statusCode respectively.

Regardless of its type, the criterion is considered fulfilled if and only if all the specified conditions are met. The number of verification rounds affects the authentication decision as follows:

  • the criterion is considered PASSED ⇔ authentication is considered failed if the criterion is not fulfilled N times in a row;
  • the criterion is considered FAILED ⇔ authentication is considered failed if the criterion is fulfilled N times in a row.

Configuration

Type Default value Valid values Description
kind *
string not specified "FAILED", "PASSED" Indicates whether the criterion is met - authentication passed or not
request.url *
string not specified The absolute URL of the criterion subject request
request.method
string GET "GET", "HEAD", "OPTIONS", "TRACE", "PUT", "DELETE", "POST", "PATCH", "CONNECT" The method of the criterion subject request
request.headers
object not specified The criterion subject request headers in the key-value format ("Content-Type": "application/json")
request.body
string not specified The body of the criterion subject request
responseConditions.statusCode *
integer not specified The HTTP status of the criterion subject response. Not equal ⇒ criterion not met
responseConditions.body
string not specified The regular expression for criterion subject response body matching. Unmatched regexp ⇒ criterion not met
responseConditions.headers
object not specified The (name, regexp) pairs for criterion subject response header matching. Any unmatched ⇒ criterion not met
interval
string "10s" Any number with the s suffix The time interval between criterion checks using seconds, e.g. "0.5s", "1s", "10s"
rounds
integer 5 The number of criteria checks to ensure that authorization has failed

* Fields marked with “*” are required.

Configuration example

[
  {
    "kind": "PASSED",
    "request": {
      "url": "http://api.e-shop.com/profile"
    },
    "responseConditions": {
      "statusCode": 200,
      "headers": {
        "Content-Type": "application/json"
      }
    },
    "interval": "7s",
    "rounds": 3
  },
  {
    "kind": "FAILED",
    "request": {
      "url": "http://api.e-shop.com/"
    },
    "responseConditions": {
      "statusCode": 200,
      "body": ".*Unauthorized.*"
    },
    "interval": "1s",
    "rounds": 7
  },
  {
    "kind": "FAILED",
    "request": {
      "url": "http://api.e-shop.com/"
    },
    "responseConditions": {
      "statusCode": 403
    },
    "interval": "1s",
    "rounds": 7
  },
  {
    "kind": "PASSED",
    "request": {
      "method": "POST",
      "url": "http://api.e-shop.com/endpoint/",
      "headers": {
        "Content-Type": "application/json"
      },
      "body": "{\"data\": \"here\"}"
    },
    "responseConditions": {
      "statusCode": 200
    }
  }
]

Updating authentication data with an HTTP request

Periodic refreshing of sessions is performed using the JSON configuration. This only works in conjunction with the authentication verification mechanism.

This configuration describes how to perform an HTTP request to refresh a session in any of its manifestations, and the way to configure new authorization parameters with updated data.

Configuration

Type Default value Valid values Description
request.url *
string not specified The absolute URL of the session-refresh endpoint. This field is mandatory
request.method
string "GET" "GET", "HEAD", "OPTIONS", "TRACE", "PUT", "DELETE", "POST", "PATCH", "CONNECT" The HTTP method of the session-refresh endpoint
request.headers
object not specified The "key": "value" pairs which specify additional headers for a session-refresh request
request.body
string not specified A string representation of the HTTP body needed for a session-refresh request
request.timeout
string "10s" Any number with the s suffix The timeout configuration for session-refresh request using seconds, e.g. "0.5s", "1s", "10s"
responseExtractors *
array not specified Describes how the endpoint response is processed for a session update. An array, each element of which describes a single strategy of extraction
responseExtractors[].extractor *
string not specified Contains a regular expression in RE2 format, corresponding to the extracted data for the current element of the responseExtractors array. This field is mandatory for each element of the responseExtractors array. The regular expression searches for matches in the response body and headers in the format Header-Key: Header-Value. The search continues until the first match, after which it stops
responseExtractors[].proxyParams
object not specified a description of the hook which will be added after successful data extraction. Field is an object, which allows the cookie, header, httpAuth and jsonReplacer keys.
This field is mutually exclusive with responseExtractors[].placeholderVariableName
responseExtractors[].proxyParams.cookie
object not specified Valid keys: schema, hostname, port, path, name
responseExtractors[].proxyParams.header
object not specified Valid keys: schema, hostname, port, path, name
responseExtractors[].proxyParams.httpAuth
object not specified Valid keys: schema, hostname, port, path, username
responseExtractors[].proxyParams.jsonReplacer
object not specified Valid keys: schema, hostname, port, path
responseExtractors[].proxyParams.[cookie,header,httpAuth,jsonReplacer].schema
string from base URL The schema (network protocol) used for authentication in the scanned application
responseExtractors[].proxyParams.[cookie,header,httpAuth,jsonReplacer].hostname
string from base URL Hostname in any valid variant: domain (including with subdomains), IPv4 or IPv6
responseExtractors[].proxyParams.[cookie,header,httpAuth].path
string from base URL The path for authentication in the scanned application
responseExtractors[].proxyParams.[cookie,header,httpAuth,jsonReplacer].port
string from base URL "0""65535" The port number for authentication in the scanned application
responseExtractors[].proxyParams.[cookie,header].name *
string not specified The name of the header or the cookie whose values will be replaced by the extracted data
responseExtractors[].proxyParams.httpAuth.username *
string not specified Describes the username for HTTP Basic where the extracted data will be replaced by a password
responseExtractors[].proxyParams.jsonReplacer.path *
string from base URL Describes the path to the JSON keys to change the values using the extracted data
responseExtractors[].placeholderVariableName
string not specified The name of the key where the extracted data will be stored. This data will be used in the next session-refresh request in the relevant templated parts of the HTTP request. Use case: changing the refresh token after each session refresh. This field is mutually exclusive with responseExtractors[].proxyParams
responseExtractors[].valueTransformationTemplate
string not specified Describes the context corresponding to the {{ .Matched }} placeholder, the templated part of which is substituted for the extracted data. This context is displayed in the HTTP request to update the session in the placeholder corresponding to the responseExtractors[].placeholderVariableName value. Usage example: The extracted data should be used in the Authorization header, but the value is returned without the Bearer prefix. The context will look like Bearer {{ .Matched }}
placeholdersInitValues
object not specified Contains "key": "value"pairs which will be used in the template rendering of the request field of the HTTP request. All key-value pairs must be filled in with initial values which will be used during the first session-refresh request. For other session-refresh requests, values will be rewritten using the extracted data with the corresponding responseExtractors[].placeholderVariableName key
dropHooksBeforeRefreshRequest
boolean false true, false Indicates whether to remove authentication data (proxy hooks) retrieved by the refresher before executing next HTTP request for a refresh

* Fields marked with “*” are required.

Configuration examples

{
  "request": {
    "url": "http://example.com/login",
    "method": "POST",
    "body": "login=admin&password=secretpass"
  },
  "responseExtractors": [
    {
      "extractor": "Set-Cookie:.*session_token=(.*);",
      "proxyParams": {
        "cookie": {
          "name": "session_token"
        }
      }
    }
  ]
}
{
  "request": {
    "url": "http://api.example.com/refresh-with-token",
    "method": "POST",
    "body": "{\"authData\": {\"refreshToken\": \"{{ .RefreshToken }}\"}}"
  },
  "responseExtractors": [
    {
      "extractor": "{\"token\": \"(.*)\",}",
      "proxyParams": {
        "header": {
          "name": "X-Auth",
          "hostname": "api.example.com"
        }
      }
    },
    {
      "extractor": "\"authData\": {\"refreshToken\": \"(.*)\"}",
      "placeholderVariableName": "RefreshToken"
    }
  ],
  "placeholdersInitValues": {
    "RefreshToken": "c2712990-ec19-414b-8be0-8a66e9271253"
  }
}
{
  "request": {
    "url": "http://example.com/refresh-with-token",
    "method": "POST",
    "body": "{\"authData\": {\"refreshToken\": \"{{ .RefreshToken }}\"}}"
  },
  "responseExtractors": [
    {
      "extractor": "{\"token\": \"(.*)\"}",
      "proxyParams": {
        "header": {
          "name": "Authorization"
        }
      },
      "valueTransformationTemplate": "Bearer {{ .Matched }}"
    },
    {
      "extractor": "\"authData\": {\"refreshToken\": \"(.*)\"}",
      "placeholderVariableName": "RefreshToken"
    }
  ],
  "placeholdersInitValues": {
    "RefreshToken": "c2712990-ec19-414b-8be0-8a66e9271253"
  }
}

Updating authentication data with browser script

Periodic refreshing of sessions is performed using the JSON configuration and the browser script, recorded with Chrome DevTools Recorder. An entity called a browser authenticator executes a browser script, then transmits the Cookie and the browser's local storage status at the time of script completion to the scanner. The configuration file should describe how the received Cookie and local storage will be used in the updated authentication data. It only works in combination with the authentication verification mechanism. It is mutually exclusive with the mechanism for updating authentication data with an HTTP request.

Configuration

The configuration regulates the execution of the browser script and describes how to configure new authentication parameters with updated data.

Type Default value Valid values Description
browserAuthenticatorName
string "fuchsia-browser-authenticator" Base name of the browser authenticator executable file. It is recommended to leave this field empty. The required value is set by default
loginScript
object not specified An object which describes the browser script.
When creating a scan via fuchsiactl, it is recommended not to fill in this field and use the --file=@browserAuthenticator:loginScript@/path/to/script.json flag.
Scanning via the HTTP API is only possible with a key indicating the location of the file.
When running via the dashboard, this field is filled in by uploading the script file in the parameters of the scanned target
outputExtractors *
array of objects not specified Describes how to handle new Cookie and local storage for session updates. This is an array, each element of which describes one single data extraction strategy
outputExtractors[].type *
string not specified "TYPE_COOKIE", "TYPE_LOCAL_STORAGE" Data source type
outputExtractors[].selectors
array of strings not specified An array of Cookie names or local storage keys that must be present to the browser authenticator after the browser script is executed. If the array is not empty, then if at least one of its elements is missing in the browser authenticator output, the authentication data update will be considered failed. Required if the outputExtractors[].extractSelectorsOnly field is specified
outputExtractors[].extractSelectorsOnly
boolean false true, false A flag indicating whether to take all the data from the browser authenticator output or only those which matched the selectors. The true value is valid only if the outputExtractors[].selectors array is not empty
outputExtractors[].proxyParams
object depends on data source type A description of the authentication mechanism that will be added after successful data extraction.
  • This field can only be set if the value of the outputExtractors[].type field is specified as "TYPE_LOCAL_STORAGE".
    If this parameter is empty, an authentication mechanism will be created for this type using the entire updated local storage (accurate to outputExtractors[].selectors and outputExtractors[].extractSelectorsOnly) in order to transfer the content to browser modules.
  • If outputExtractors[].type field is specified as "TYPE_COOKIE", then extracted Cookies automatically create a new authentication mechanism that adds them to the authentication data, taking into account the Domain and Path properties.
  • In all other cases, the field allows cookie, header, httpAuth and jsonReplacer keys
outputExtractors[].proxyParams.[cookie,header].name *
string not specified The name of the header or the name of the cookie file, the values of which will be replaced by the extracted data
outputExtractors[].proxyParams.httpAuth.username *
string not specified The username for basic HTTP authentication, for which the extracted data will be replaced with a password
outputExtractors[].proxyParams.jsonReplacer.path *
string not specified Specifies the path for replacing values in the JSON bodies of outgoing scanner requests. It is applied only if the following conditions are met simultaneously:
  • the request body is fully presented in JSON format,
  • the specified JSON path exists in the structure.
If the conditions are met, the value along the specified path is replaced with data from the extracted source
responseExtractors[].valueTransformationTemplate
string not specified It is supported only if the following conditions are met simultaneously: The field specifies a template in the context of which, using go text/template the extracted values will be processed. The result is a string inserted in the outputExtractors[].proxyParams field.
The keys of the pairs extracted from the local storage act as placeholders.
For example, the token extracted by the key "authToken" must be inserted into the header as follows: Authorization: Bearer <token>. Then this field will take the Bearer: {{ .authToken }} value, and outputExtractors[].proxyParams will contain a {"header": {"name": "Authorization"}} object.
You can use more than one placeholder.
It is strongly recommended to use the {{ index . "some-name" }} form for passing to a template string, because for a template engine, for example, “-” is a service character, therefore, in the Bearer: {{ .some-name }} form the template will not be processed successfully

* Fields marked with “*” are required.

Configuration examples

  • Retrieving all Cookie if there is at least one named “token” among them:

    {
      "output_extractors": [
        {
          "type": "TYPE_COOKIE",
          "selectors": ["token"]
        }
      ]
    }
    
  • Extracting a Cookie named "token”, if present:

    {
      "output_extractors": [
        {
          "type": "TYPE_COOKIE",
          "selectors": ["token"],
          "extract_selectors_only": true
        }
      ]
    }
    
  • Extracting all Cookie. Extracting local storage and transferring it to browser modules. Extracting the values for the token_secret_name and token keys from the local storage and passing them to the Authorization header according to the template. Failure for the entire update if at least one value was not found:

    {
      "output_extractors": [
        {
          "type": "TYPE_COOKIE"
        },
        {
          "type": "TYPE_LOCAL_STORAGE"
        },
        {
          "type": "TYPE_LOCAL_STORAGE",
          "selectors": ["token_secret_name", "token"],
          "extractSelectorsOnly": true,
          "proxy_params": {
            "hostname": "example.com",
            "scheme": "https",
            "port": "443",
            "header": {
              "name": "Authorization"
            },
            "value_transformation_template": "Bearer {{ .token_secret_name }}||{{ .token }}"
          }
        }
      ]
    }
    

Recording a browser script

Google Chrome browser is required to record the browser script. The sequence of actions is described in the Chrome Developer Documentation. In this section, it is specified in order to obtain the highest quality script recording.

The following is used as a demonstration example: http://juiceshop.stands.appsecuritytesting.fun/.

  1. Open the Google Chrome browser in incognito mode. The incognito tab
  2. Press “F12” to open Chrome Developer Tools → click “⋮” in the upper right corner → select “More Tools” → press “Recorder”. How to open recorder
  3. Press “Create a new recording”. Begin script creation
  4. Enter a name for the future script and press “Start recording”. Begin script recording
  5. Go to the authentication page, enter the required credentials, log in, and press “End recording”. Script recording
  6. Export the resulting record in JSON format. Script export

The resulting file is a browser script required to update the scan authentication data.