OpenAPI Configuration

HawkScan needs to know the routes/endpoints of an application to test for vulnerabilities. While HawkScan can attempt to autodiscover routes/endpoints, it can also use an OpenAPI specification to pre-seed its sitemap. The OpenAPI V2 Specification (AKA Swagger) is an industry-adopted standard for describing RESTful interfaces, which HawkScan can use to deliver a faster, more thorough scan.

Some projects might not have an OpenAPI spec file because their 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. Open API definitions do not have to be publicly published for internal APIs, they can be for limited to internal use only.

HawkScan can work with OpenAPI definitions as separate files or defined inline via the stackhawk.yml file. Additionally, if your project doesn’t already have an OpenAPI file for use with HawkScan, there are multiple ways to get started.

The OpenAPI has a v2 and a v3 versioned implementations.

Example OpenAPI Spec File

A typical OpenAPI spec can be defined in either yaml or json format. A json 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
  api: "openapi.json"

If the stackhawk.yaml includes anapp.api configuration, HawkScan will use the contents of the provided OpenAPI spec to improve the quality of the scan:

  • The routes defined in the OpenAPI spec will pre-seed the sitemap of routes to scan. This can be used to complement any crawled routes, or can be used instead of app spidering altogether.
  • The methods and expected inputs to routes defined in the spec will inform how HawkScan communicates with the web application, and provide clues on how to better attack those paths.

Using An Inline OpenAPI Spec

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, and can 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")
    
  • The SpringFox quickstart reference describes the additional configuration to add to the SpringBoot Application Configuration. It works by using provided annotations on the RestControllers:
  • // 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 swagger spec should be available via the /v2/api-docs endpoint. The spec can then be pulled down to a local file:
  1.   $ curl localhost:8080/openapi > openapi.json
    
  2. Now add that new file to the stackhawk.yml

     app:
       # specify the relative path to an OpenAPI v2 .json or .yaml file
       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 with an assist of 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.