OpenAPI Configuration

The OpenAPI Specification (AKA Swagger) is an industry-adopted standard for describing RESTful interfaces, which HawkScan can use to deliver a faster, more thorough scan.

HawkScan will use the contents of a provided OpenAPI spec to improve the quality of the scan by:

  • Pre-seeding the sitemap using the routes defined in the OpenAPI spec. This can be used to complement any crawled routes, or can be used instead of app spidering altogether.
  • Using defined inputs to routes in the the spec to inform how to communicate with the web application and gather clues on how to better attack endpoints.

HawkScan can work with OpenAPI definitions as separate files or defined inline via the stackhawk.yml.

Creating an OpenAPI Spec

A project may not have an OpenAPI spec because its API is for internal application use only. We have found that even for internal APIs it is useful to have an OpenAPI spec for integration not only with HawkScan, but a wide variety of tools and technologies. OpenAPI definitions do not have to be publicly published for internal APIs, they can be for limited to internal use only.

If your project doesn’t already have an OpenAPI file for use with HawkScan, there are multiple ways to get started.

The OpenAPI has v2 and v3 versioned implementations. HawkScan supports both versions.

Example OpenAPI Spec File

A typical OpenAPI spec can be defined in either YAML or JSON format (e.g. openapi.yml). A YAML version might look like the following:

swagger: "2.0"
info:
  title: Sample Example Web API
  description: Web API description in _markdown_.
  version: 1.0.0
host: api.example.com
basePath: /v1
schemes:
  - https
paths:
  /users:
    get:
      summary: Returns a list of users.
      description: extended description in Markdown.
      produces:
        - application/json
      responses:
        200:
          description: OK

Using An OpenAPI Spec File in HawkScan

If your project already uses an existing v2 OpenAPI specification file, you can integrate it with HawkScan by including the following in your stackhawk.yaml:

# in the "app" config...
app:
  # specify the relative path to an OpenAPI v2 .json or .yaml file
  # prefix the path with / to pull from the target host
  api: "openapi.yaml"

Using an Inline OpenAPI Spec in HawkScan

You can define portions of your web app structure within the app.api configuration of your stackhawk yaml in the OpenAPI format:

# in the "app" config...
app:
  # instead of a string path to a file, provide the openapi spec inline
  api:
    basePath: /v1
    schemes:
    - https
    paths:
      /users:
        get:
          summary: Returns a list of users.
          description: extended description in Markdown.
          produces:
            - application/json
          responses:
            200:
              description: OK

This can be useful for segmenting scan results to portions of your web application. It can also start as the foundation of more thorough API documentation to start your own openapi.yaml specification file.

Tips For Creating A New OpenAPI Spec For HawkScan

Because OpenAPI is widely adopted, there are a lot of available tools to help a project get started: https://openapi.tools/

SmartBear has free online editor that can be used immediately to start building a OpenAPI file that will work with HawkScan: 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, there are various ways to get an OpenAPI specification defined.

Framework specific help:

Spring/Springboot

SpringFox is a utility to generate OpenAPI spec files from annotated controller routes in a SpringBoot project. It exposes the generated OpenAPI file from a configured rest endpoint.

  1. Add the SpringFox dependency to your build pom file:
  <dependency>
   <groupId>io.springfox</groupId>
   <artifactId>springfox-swagger2</artifactId>
   <version>2.9.2</version>
  </dependency>

or add the dependency to your build gradle if using that:

  implementation("io.springfox:springfox-swagger2:2.9.2")

Note: Use SpringFox version 2.9.2 or greater. Earlier versions do not output the security schemes needed for a complete openapi generation.

The SpringFox Quickstart Reference describes the additional configuration to add to the SpringBoot Application Configuration. It works by using provided annotations on the REST Controllers:

  // example spring restcontroller annotations

  @ApiOperation(value = "Find pet by Status",
       notes = "${SomeController.findPetsByStatus.notes}"...)
  @RequestMapping(value = "/findByStatus", method = RequestMethod.GET, params = {"status"})
  public Pet findPetsByStatus(
       @ApiParam(value = "${SomeController.findPetsByStatus.status}",
            required = true,...)
       @RequestParam("status",
           defaultValue="${SomeController.findPetsByStatus.status.default}") String status) {
       //...
  }

  @ApiOperation(notes = "Operation 2", value = "${SomeController.operation2.value}"...)
  @ApiImplicitParams(
      @ApiImplicitParam(name="header1", value="${SomeController.operation2.header1}", ...)
  )
  @RequestMapping(value = "operation2", method = RequestMethod.POST)
  public ResponseEntity<String> operation2() {
    return ResponseEntity.ok("");
  }

Once properly configured the OpenAPI spec should be available via the /v2/api-docs endpoint.

The spec can then be pulled down to a local file:

  $ curl localhost:8080/openapi > openapi.json

Now add that new file to the stackhawk.yml

  app:
    # specify the relative path to an OpenAPI v2 .json or .yaml file
    # prefix the path with / to pull from the target host
    api: "openapi.json"

Rails

There isn’t a way to automatically find and define routes for OpenAPI, but a good way to start is to output all the app’s routes and then use something like swagger-docs to document them.

List out the app’s routes with rails routes

Set up swagger-docs and document each route: https://github.com/richhollis/swagger-docs

    swagger_controller :users, "User Management"

    swagger_api :index do
    param :query, :page, :integer, :optional, "Page number"
    response :unauthorized
    response :not_acceptable
    response :requested_range_not_satisfiable
    end

Express

There isn’t a way to automatically find and define routes for OpenAPI, but a good way to start is to output all the app’s routes and then use something like swagger-jsdoc to document them.

Find all your routes with some code like this:

    var route, routes = [];

    app._router.stack.forEach(function(middleware){
      if(middleware.route){ // routes registered directly on the app
          routes.push(middleware.route);
      } else if(middleware.name === 'router'){ // router middleware
          middleware.handle.stack.forEach(function(handler){
              route = handler.route;
              route && routes.push(route);
          });
      }
    });

    routes.forEach(function(temp){
        var methods = "";
        for(var method in temp.methods){
            methods += method + ", ";
        }
        console.log(temp.path + ": " + methods);
    });

Set up swagger-jsdoc and then document each route: https://github.com/Surnet/swagger-jsdoc/blob/master/docs/GETTING-STARTED.md

  /**
  * @swagger
  *
  * /login:
  *   post:
  *     description: Login to the application
  *     produces:
  *       - application/json
  *     parameters:
  *       - name: username
  *         description: Username to use for login.
  *         in: formData
  *         required: true
  *         type: string
  *       - name: password
  *         description: User's password.
  *         in: formData
  *         required: true
  *         type: string
  *     responses:
  *       200:
  *         description: login
  */
  app.post('/login', (req, res) => {
  // Your implementation comes here ...
  });

Django

Django projects can use the Django REST swagger Python package to generate an OpenAPI v2 spec file with their code.

Run pip install django-rest-swagger and add the following to your Django settings:

  INSTALLED_APPS = [
  ...
  'rest_framework_swagger',
  ...
  ]

PHP

Laravel and other PHP frameworks can utilize zircote/swagger-php to generate OpenAPI spec files by using code annotations. For OpenAPI v2 spec generation you can explicitly require version 2._ with composer require zircote/swagger-php:2._. The SWAGGER_VERSION=2.0 environment variable will need to be set in your .env file or defined with export SWAGGER_VERSION=2.0

Add phpdoc annotations to your code to assist with OpenAPI spec generation. When you build your site a swagger.json file will be written out to the local working directory.

    /**
    * @OA\Info(title="My First API", version="0.1")
    */

    /**
    * @OA\Get(
    *     path="/api/resource.json",
    *     @OA\Response(response="200", description="An example resource")
    * )
    */

    /** Generate documentation with your php site */
    <?php
    require("vendor/autoload.php");
    $openapi = \OpenApi\scan('/path/to/project');
    header('Content-Type: application/x-yaml');
    echo $openapi->toYaml();

ASP.NET

The Swashbuckle package will expose an OpenAPI spec for the app via a URL.

Install the package:

  Install-Package Swashbuckle

Enable Swashbuckle in something like Program.cs

  httpConfiguration
       .EnableSwagger(c => c.SingleApiVersion("v1", "A title for your API"))
       .EnableSwaggerUi();

Then download the spec to a file from the URL: <your-root-url>/swagger/docs/v1

Add that new file to the stackhawk.yml

  app:
      # specify the relative path to an OpenAPI v2 .json or .yaml file
      api: "myproj.json"

Note: The above steps are for if your app is hosted in IIS. If it’s not, please look at the the Swashbuckle docs for similar install instructions.