Skip to content

Automated detection of Broken Access Control vulnerabilities based on enhanced OpenAPI specifications

License

Notifications You must be signed in to change notification settings

peerigon/access-control-testing

Repository files navigation

Access Control Testing Tool

Automated detection of Broken Access Control vulnerabilities based on enhanced OpenAPI specifications


Introduction

This tool automates testing web applications for Broken Access Control vulnerabilities, with a particular focus on detecting Broken Object Level Authorization (BOLA). Broken Access Control is ranked #1 in the OWASP Top 10 (2021), while BOLA is ranked #1 in the OWASP API Security Top 10 (2023), highlighting the importance of effective access control mechanisms in modern web applications.

Developed by Peerigon as part of a bachelor's thesis, it leverages a specially annotated OpenAPI specification to explicitly determine which resources an API endpoint accesses and the type of access involved. For details on annotations, see Annotating Resources.

The tool generates test cases based on defined user-resource relationships and executes them through a test runner, sending requests to the application and verifying whether each request was permitted or denied. The outcome is then compared to the expected behavior defined through a policy replication, enabled by user-resource relationship definitions. Results are displayed in a console-based report.


Installation

Since the tool is not yet published on npm, installation is done using yalc.

Install yalc globally first:

npm install -g yalc

Clone this repository, navigate to the directory, and run:

npm install
npm run publish:local

Then, inside your project's directory, add the tool:

npx yalc add access-control-testing
npm install

Limitations

Additional security mechanisms like CSRF tokens, rate limiting, or IP blocking should be disabled during testing. Otherwise, they may interfere with the testing process. For example, a 403 Forbidden status code caused by IP blocking might be misinterpreted by the tool. Temporarily disable such protections via environment variables or similar mechanisms to ensure accurate test results.

Currently, only one resource per operation can be defined. The tool does not support multiple resources in a single route (e.g., /groups/:groupId/members/:memberId). Simple routes like /members/:memberId are fully supported.

The tool only supports APIs communicating via JSON. XML or other formats are not yet supported.

Combining multiple Security Schemes for authentication is not supported. While OpenAPI allows defining multiple Security Schemes with an OR-relationship, the tool always selects only the first defined Security Scheme and does not use others as fallback.


Assumptions

The tool assumes tested web applications follow this sequence when handling requests:

  1. User identity verification (Authentication)
  2. User permission verification (Authorization)
  3. Request syntax and semantic validation

If this order is not maintained, the tool may produce inaccurate test outcomes.

The tested web application should return semantically correct status codes, as the tool determines whether a test has failed or passed based on the returned status code. The status code 403 Forbidden should only be sent when an authorization check concludes that the requested resource is not accessible to the user making the request. 403 should not be used for violations of business logic (e.g., when a request is semantically or syntactically incorrect or when the requested action is not possible in the current state of the resource).


Setup

1. Provide OpenAPI Specification

Make your application's OpenAPI specification available through your web server in either JSON or YAML format.

Important

Local file paths are not allowed for security reasons. Instead, you must use a URL that starts with http:// or https://.


2. Annotating Resources

First, determine clearly which API routes represent resources and the type of access (create, read, update, delete) they involve.

The following custom annotations (prefixed with x-act-) are required to specify resources and access types:

  • x-act-resource-name: Indicates the resource accessed.
  • x-act-resource-access: Specifies access type.

Annotations can be inline or nested under x-act:

Example of Inline Annotation
x-act-resource-name: Todo
x-act-resource-access: read
Example of Nested Annotation
x-act:
  resource-name: Todo
  resource-access: read

Annotations for resources can be placed in path parameters, query parameters, or the request body. Additionally, they can be defined at the operation level, which is particularly relevant for create operations where no identifier is available for annotation.

Additionally, they can be defined at the operation level for operations that do not include a resource parameter but still perform an action on a resource. This includes, for example, creating (create) a new resource or reading (read) resources without specifying an identifier (i.e., accessing all resources).

Complete Example of OpenAPI Annotations
paths:
  /todos:
    get:
      # ...
      x-act:
        resource-name: Todo
        resource-access: read
    post:
      # ...
      x-act:
        resource-name: Todo
        resource-access: create

  /todos/{id}:
    # ...
    get:
      parameters:
        - name: id
          in: path
          required: true
          schema:
            type: string
          x-act:
            resource-name: Todo
            resource-access: read

3. Annotating Authentication Endpoints

Before annotating authentication endpoints, ensure a valid security scheme is defined in your OpenAPI specification. See the Security Scheme documentation.

Warning

The tool does not support combining multiple Security Schemes for authentication. If an operation or the entire API requires multiple Security Schemes to be used together for authentication, this will not work. While OpenAPI allows defining multiple Security Schemes as an OR-relationship, the tool always selects only the first defined Security Scheme and does not use others as fallback.

Use these annotations to allow the tool to authenticate automatically:

  • x-act-auth-endpoint: Must match your defined security scheme key and must be provided on operation-level.

  • x-act-auth-field: Defines the relevant fields for authentication and must be set to one of the following valid types:

    Type Description
    identifier Specifies the field in the request body that contains the user identifier (e.g., username or email).
    password Defines the field in the request body that holds the user's password.
    token Specifies the field in the response body where the authentication token is returned.

Each value must be explicitly defined either as x-act-auth-field-type directly or as follows:

x-act-auth-field:
  type: identifier | password | token

Warning

For bearer authentication, the token field must be at the top level of the response.
Nested fields like { data: { token: "<token>" } } are currently not supported.

Example of an Authentication Endpoint (Bearer)
paths:
  /login/bearer:
    post:
      requestBody:
        required: true
        content:
          application/json:
            schema:
              type: object
              properties:
                username:
                  type: string
                  x-act-auth-field:
                    type: identifier
                password:
                  type: string
                  x-act-auth-field:
                    type: password
      responses:
        "200":
          content:
            application/json:
              schema:
                type: object
                properties:
                  token:
                    type: string
                    x-act-auth-field:
                      type: token
      x-act-auth-endpoint: bearerHttpAuthentication

4. Defining Users and Resources

Define user-resource relationships explicitly. Resource names must match exactly (case-sensitive) the values used in the OpenAPI annotations (x-act-resource-name):

Example of User-Resource Definition
import { Resource, User } from "access-control-testing";

const user1 = new User("myusername", "mysecretpassword");
const todoResource = new Resource("Todo"); // Name must exactly match OpenAPI spec annotation

user1.canView(todoResource, 123); // user1 can view Todo instance with identifier 123
user1.canEdit(todoResource, 123); // user1 can edit Todo instance with identifier 123
user1.canDelete(todoResource, 123); // user1 can delete Todo instance with identifier 123
user1.canCreate(todoResource); // user1 can create new Todo instances
user1.owns(todoResource); // user1 owns created Todo instances

5. Configuration Options

Provide the following properties when configuring the tool:

  • apiBaseUrl: The base URL where your API is accessible. It must be present in the servers array of the OpenAPI spec.
  • openApiUrl: URL pointing to your annotated OpenAPI spec.
  • users: Array of defined users.
  • resources: Array of defined resources.

Warning

The tool currently does not support templates for the apiBaseUrl inside of the servers array of the OpenAPI spec.

Example of Tool Configuration
import { Act, NodeTestRunner, Resource, User } from "access-control-testing";

const users = [user1];
const resources = [todoResource];

const act = new Act({
  apiBaseUrl: "http://localhost:3333/",
  openApiUrl: "http://localhost:3333/openapi.yml",
  users,
  resources,
});

Running Tests

Once all setup steps are completed, you can generate test cases using generateTestCases() and run them with a test runner using .run().

Tests can be run with any test runner by extending the abstract class TestRunner.
To use the built-in Node.js test runner, the adapter NodeTestRunner is available (requires Node.js version 18 or higher).

Example of Running Tests
import { Act, NodeTestRunner, Resource, User } from "access-control-testing";

// Assuming setup steps are completed and `act` instance is configured
const testCases = await act.generateTestCases();
const testRunner = new NodeTestRunner();

await testRunner.run(testCases);

Results are automatically presented in a clear tabular format in the console.

About

Automated detection of Broken Access Control vulnerabilities based on enhanced OpenAPI specifications

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published