# Specification

## How It Works

Shisho Cloud sends simulated attacks to each registered [**Scenario**](#scenario), which is a sequence of dependent **Endpoints**, to detect vulnerabilities by examining the responses.

Some applications require specific information, such as authentication headers or cookies, to be included in the request after login. You can specify these headers by registering [**Authentication Settings**](#authentication-settings-yaml-reference). These settings will determine the headers to include when sending requests during crawling and assessment. Values for headers can be specified as fixed values or extracted dynamically by replaying scenarios representing login operations.

In some cases, you may want to exclude certain parts of your application from the assessment. You can assess only specific parts of your application by configuring the [**Scope**](#scope).

The following sections describe each concept in more detail.

## Scope {#scope}

Scope defines which parts of the application will be assessed.

In the default input mode, you can specify a URL prefix. URLs starting with that prefix will be assessed. You can specify multiple prefixes by clicking the "Add Scope" button.

![Scope settings](/docs/_md-assets/bf0ef76881-scope-input-default-mode.png)

You can define the scope using regular expressions instead of prefixes by switching to advanced mode using the toggle.

![Scope settings](/docs/_md-assets/6f4bc45636-scope-input-advanced-mode.png)

## Scenario {#scenario}

A Scenario is a unit of assessment represented by a sequence of dependent endpoints. For example, the following request flow can be expressed as a Scenario. This enables assessment based on endpoint relationships.

- Extract the CSRF token from the input screen and include it in a POST request.
- Send a request to create an item before sending a request to delete an item.
- After sending a request to create an item, send a request for the screen that displays the item information to detect vulnerabilities in accumulation.

A Scenario consists of one or more **Steps**. Each step refers to an endpoint that sends a request.

For example, the following two-step Scenario requests the item list screen after an item is created. This detects cumulative vulnerabilities caused by item creation.

![](/docs/_md-assets/cd24cecfbd-scenario-simple.png)

The YAML input field for each step can contain the following options.

- Define the input/output relationship between steps
  - `extractors`: Extracts values from request results, stores those values in variables, and makes them usable in subsequent steps.
  - `bindings`: Injects the values stored in variables by `extractors` in previous steps into the request parameters of the current step.
- Adjust handling during assessment
  - `skipInjection`: Do not inject attack payloads into the step.

![](/docs/_md-assets/a8877489f7-scenario-step-yaml.png)

### `extractors`

This setting extracts values from request results, stores those values in variables, and makes them available in subsequent steps. It specifies an array of [**Extractor Objects**](#extractor). You can extract multiple pieces of information and store them in variables by specifying multiple Extractor Objects as array elements.

For example, if you enter the following in the YAML input field, the response body will be matched against the regular expression `token=([a-z0-9]+)`. The portion matching the first group, `([a-z0-9]+)`, will be stored in the variable named `token`.

```yaml
extractors:
  - name: token
    type: regex
    part: body
    regex:
      - "token=([a-z0-9]+)"
    group: 1
```

#### Extractor Object {#extractor}

An Extractor Object defines how to extract a value from the result of a request and the variable name to store the extracted value.

The basic structure is as follows. The variable name specified in `name` will be used by `bindings` in subsequent steps. Specify the type of extraction method in `type`. This is followed by configuration items for each extraction method.

```yaml
name: "<Variable name to store>"
type: "<Extraction method type>"
# ... <Settings according to the extraction method> ...
```

The extraction method type is one of the following:

- `regex`: Extracts values from strings using regular expressions
- `xpath`: Extracts values from HTML/XML using [XPath](https://developer.mozilla.org/en-US/docs/Web/XPath)
- `json`: Extracts values from JSON using [jq](https://jqlang.github.io/jq/) queries
- `cookie`: Extracts all cookies from the response

##### `regex` Extractor

This Extractor represents extraction using regular expressions.

Configuration items:

- `regex`: An array of regular expressions used for extraction
  - Refer to the [RE2 documentation](https://github.com/google/re2/wiki/Syntax) for syntax.
- `group`: The number of the capture group from which to extract the value
  - Default: `0` (entire match)
- `part`: The target to match with the regular expression
  - `all`: Entire response (default)
  - `body`: The body of the response
  - `header`: The header of the response

For example, the following Extractor matches the response header and stores the value portion of the `Location` header in a variable called `redirect_url`. This is the first group.

```yaml
name: redirect_url
type: regex
part: header
regex:
  - "(?m)^Location: (.+?)$\n"
group: 1
```

##### `xpath` Extractor

This Extractor uses [XPath](https://developer.mozilla.org/en-US/docs/Web/XPath) to extract values from HTML and XML.

Configuration items:

- `xpath`: Array of XPath used for extraction
- `attribute`: Attribute name to extract
  - If not specified: Node text

For example, the following Extractor will search for an element like `<input name="csrf_token" value="...">` inside the first `<form>` element. It then stores the value of its `value` attribute in a variable called `csrf_token`.

```yaml
name: csrf_token
type: xpath
xpath:
  - '(//form)[1]//input[@name="csrf_token"]'
attribute: value
```

You can obtain the XPath to the desired element using the browser's developer tools ([https://devtoolstips.org/tips/en/copy-element-xpath/](https://devtoolstips.org/tips/en/copy-element-xpath/)). The detailed procedure will vary depending on the browser. However, you can copy the XPath pointing to the element by right-clicking on the target element in the developer tools and selecting "Copy XPath". You can also check the XPath search results in the developer tools console. This can be done with the `$x` function (e.g., `$x('//form[1]//input[@name="csrf_token"]')`).

##### `json` Extractor

This Extractor uses [jq](https://jqlang.github.io/jq/) queries to extract values from JSON.

Configuration item:

- `json`: An array of jq queries used for extraction

For example, the following Extractor extracts the `XXXX` part and stores it in a variable called `item_id` if the response body is similar to `{"item": {"id": "XXXX", ...}}`.

```yaml
type: json
name: item_id
json:
  - ".item.id"
```

##### `cookie` Extractor

This Extractor extracts all cookies from the response.

Configuration item:

- None

For example, the following Extractor will search the response header for a string like `Set-Cookie: key=value`. It then stores the string with all the `key=value` pairs concatenated with `;` in a variable called `cookies`.

```yaml
type: cookie
name: cookies
```

For example, if the response header is as follows, the string `cookie1=XXXX; cookie2=YYYY` will be stored in `cookies`.

```http
Set-Cookie: cookie1=XXXX; ...
Set-Cookie: cookie2=YYYY; ...
```

### `bindings` {#bindings}

This setting injects values stored in variables by `extractors` in previous steps into the request parameters of the current step.

For example, the following configuration injects the CSRF token stored in a variable called `csrf_token` in the previous step into the `.csrf_token` parameter in the request body.

```yaml
bindings:
  # Use extractorName
  - type: body # Type of parameter to inject
    key: .csrf_token # Injection destination
    extractorName: csrf_token # Variable name storing the value to be injected

  # Use template
  - type: body
    key: .csrf_token
    template: "{{ .csrf_token }}" # Template specifying the value to inject
```

Specify `pathParam`, `header`, `query`, or `body` for `type`.

`key` specifies the parameter to inject. Specify the parameter name as is if the type is `pathParam`, `header`, or `query` (e.g., specify `key: 'Custom-Header'` to inject into the header `Custom-Header: XXXX`). If the type is `body`, specify the property name for injection by connecting property names with dots (e.g., if the request body is JSON like `{"item": {"id": "XXXX", ...}}`, specify `key: '.item.id'` to inject the value into the `XXXX` portion).

`extractorName` specifies the variable name described in the `name` field in `extractors` in the previous step.

`template` describes a template that specifies a variable. Variables can be described as `{{ .variableName }}` within the template. You can also combine variable values with other strings by adding strings before or after `{{ ... }}`. For example, `template: "Bearer {{ .token }}"` injects the value of the variable named `token` after converting it to a string like `Bearer XXXX`.

:::info

Use only alphanumeric characters and underscores for variable names. However, you cannot use numbers at the beginning of variable names.

For example, variable names such as `token`, `my_token`, and `MyToken` are valid. Variable names such as `123token` and `my-token` are invalid.

:::

### `skipInjection`

If you set `skipInjection: true` in a step, attack payloads will not be injected into that step during the assessment. For example, to detect a cumulative vulnerability, you might want to send an attack request to `POST /items/new` in the first step and then request `GET /items` in the second step to check if there is a problem with the response. Since you only need to inject the attack payload in the first step, set `skipInjection: true` in the second step.

## Authentication Settings YAML Reference

#### `metadata`

Specify the authentication settings' metadata in `metadata`. Enter a description of the authentication settings in `description`. The list screen will display this as the title. The `id` is generated automatically, so there is no need to change it.

```yaml
metadata:
  id: 2359978...
  description: "Authentication settings for cookies"
```

#### `.spec.items`

`.spec.items` defines the data managed by the authentication settings.
Specify the following fields in the object specified as an element of the field:

- `name`: Authentication information name
- `type`: The type of parameter injected by the authentication information (`header`, `query`, or `body`)
- `key`: Key name of the parameter injected with the authentication information (e.g., `Cookie`)
- `template`: Template that specifies the value to inject into the authentication information
- `value`: Authentication information value (set to an empty value unless you set it statically)

Below is an example of defining a value to be injected into the `Cookie` header at request time under the name `cookie`.

```yaml
spec:
  items:
    - name: cookie
      type: header
      key: Cookie
      value: ""
```

#### `.spec.satisfierSpec.steps`

`.spec.satisfierSpec.steps` defines the authentication processing steps.
Use the following fields in the object specified as an element of the field:

- `type`: Step type
  - `request`: Sends a request
  - `firebase`: Performs Firebase authentication
  - `cognito`: Performs Cognito authentication
  - `auth0`: Performs Auth0 authentication
- `spec`: Specific step settings

The schema of the object specified in `spec` depends on the type specified by `type`.

If `type` is `request`, specify the following fields and set the details of the request to be sent in that step.

```yaml
spec:
  satisfierSpec:
    steps:
      - type: request
        spec:
          # HTTP method
          method: POST

          # Origin the request will be sent to (combination of scheme, host, and port)
          origin: https://example.test

          # Path to send the request to
          path: /api/v1/

          # Request headers
          headers:
            - key: Authorization
              value: Bearer 123456789

          # Query parameters
          queries:
            - key: id
              value: 1

          # Request body
          body:
            contentType: application/json
            parameter: { ... }

          # Extractor settings for parameters to propagate between steps
          # Same specifications as the Extractor Object
          extractors:
            - { ... }

          # Settings for using parameters extracted in one step in this step
          # Same specifications as bindings
          bindings:
            - { ... }
```

When setting the request body, refer to the following and set it in the `body` field.

:::info How to specify the request body

Specify the following fields in the `body` field.

- `contentType`: Request body Content-Type (e.g., `application/json`, `application/x-www-form-urlencoded`)
- `parameter`: Request body content

Specify the request body content in `parameter`. The specifications of the field are as follows.

- `type`: Parameter type (e.g., `object`, `array`, `string`)
- `name`: Parameter name
- `value`: Parameter value
- `properties`: Child parameters that the parameter has
  - Specified when `type` is `object`
  - In key-value format, the key is the name of the child element and the value is the same format as `parameter`.
- `items`: Child parameters that the parameter has
  - Specified when `type` is `array`
  - In array format, each element is the same format as `parameter`.

For example, if the request body is JSON like `{"item": {"id": "12345", "roles": ["admin"]}}`, set it as follows.

```yaml
body:
  contentType: application/json
  parameter:
    type: object
    properties:
      item:
        type: object
        name: item
        properties:
          id:
            type: string
            name: id
            value: "12345"
          roles:
            type: array
            name: roles
            items:
              - type: string
                value: admin
```

Note that you can use [bindings](#bindings) to dynamically change the value of a particular element.

:::

If `type` is `firebase`, `cognito`, or `auth0`, specify the following fields to configure the authentication processing details in that step.

```yaml
# Firebase authentication
spec:
  satisfierSpec:
    steps:
      - type: firebase
        email: test@example.test
        password: testpassword
        apiKey: testapikey
        extractors:
          - {...}

# Cognito authentication
spec:
  satisfierSpec:
    steps:
      - type: cognito
        email: test@example.test
        password: testpassword
        region: ap-northeast-1
        clientId: testclientid
        extractors:
          - {...}

# Auth0 authentication
spec:
  satisfierSpec:
    steps:
      - type: auth0
        email: test@example.test
        password: testpassword
        domain: example.test
        clientId: testclientid
        clientSecret: testclientsecret
        callbackUrl: https://example.test/callback
        extractors:
          - {...}
```

#### `.spec.satisfierSpec.extractors`

`.spec.satisfierSpec.extractors` configures the Extractor to run on the combined result of all responses obtained in each step. The Extractor notation is the same as the [**Extractor Object**](#extractor).

#### Injecting Values Extracted by Extractor into an Item

You can use either of the following methods to inject the value extracted by Extractor into the Item:

The first method is to **use the Item's Template function**.

You can inject a value extracted by an Extractor whose variable name matches the value of its `name` by describing a template such as `{{ .variableName }}` in the Item's `template` field. Of course, you can also combine the value of a variable with other strings by adding strings before or after `{{ ... }}`. For example, in the example below, the value extracted by the Extractor named `cookie` is injected using the template `{{ .cookie }}`.

```yaml
spec:
  items:
    - type: header
      key: Cookie
      template: "{{ .cookie }}"
  satisfierSpec:
    steps:
      - type: ...
        spec:
          {...}
          extractors:
            - name: cookie
              type: regex
              part: header
              group: 1
              regex:
                - "Set-Cookie: (SESSID=[a-zA-Z0-9]+)"
```

The second method is to **match the Extractor's name with the Item's name**.

If the value of an Extractor's `name` matches the value of an Item's `name`, the value extracted by that Extractor is injected into that Item. For example, in the example below, the value extracted by the Extractor named `cookie` will be injected into the Item named `cookie` defined in `items`.

```yaml
spec:
  items:
    - name: cookie # Item name
      type: header
      key: Cookie
      value: ""
  satisfierSpec:
    steps:
      - type: ...
        spec:
          {...}
          extractors:
            - name: cookie # Extractor name
              type: regex
              part: header
              group: 1
              regex:
                - "Set-Cookie: (SESSID=[a-zA-Z0-9]+)"
```

#### `.spec.validatorSpecs`

`.spec.validatorSpecs` defines the conditions that trigger authentication setting updates.

This setting will already be configured when you open the editor. Change the `expiresIn` value only if you want to change the update interval. The value specified in this field should be interpretable as `time.Duration` in Go.

```yaml
spec:
  validatorSpecs:
    - type: BLANK
      config: {}
    - type: EXPIRE
      config:
        expiresIn: 10m
```
