Skip to content

Tenant Isolation, Access Control, and Data Segregation Testing

Introduction

When dealing with REST or GraphQL APIs, ensuring proper data isolation and tenant segregation becomes paramount, especially in multi-tenant environments. Due to the versatile and interconnected nature of APIs, data can be accessed through multiple paths, necessitating secure strategies at every juncture.

Tenant isolation vulnerabilities can take several forms, but they usually show the following factor:

  • The authentication/authorization in place does not protect objects from one user to be accessed by the other ones.
  • In other terms: object IDs do not have any authorization checks on them, leading to potential cross-user leaks if the id is known

UUIDs and ID Reinjection

This is often debated with large entropy IDs such as UUIDs. An attacker could not guess a UUID value from another user easily.

But if a single endpoint in your API leaks IDs cross-tenant/users an attacker could pivot and retrieve data.

UUIDs can create a false sense of security in APIs, leading to catastrophic chains of exploitation if not checked against real Authorization rules.

Hence, Escape allows you to crawl and explore your APIs, and validate cross-tenant Authentication/Authorization.

In some cases, the isolation issues also can be more easily detected through detection of private information from one user, in responses of another user.

This use-case doesn't rely on ID reinjection and pivoting cross-users, instead checking for data presence.

Escape provides you with powerful tools to ensure that data remains in its designated boundaries. This documentation will guide you through using Escape's features to enhance access control and maintain the sanctity of your data.

Once you provide multiple users in the authentication configuration of your scan, Escape will automatically attempt to replay requests from one user with the other's authentication.

This is also done during WebApp scans, where one user is used for crawling (the main user, which must be defined for WebApp scans), and the other user replays the API traffic.

Tenant Isolation

In multi-tenant applications, where various customers share the same software instance, tenant isolation is non-negotiable. By default, when configuring 2 users, Escape's business logic algorithm will automatically run tenant isolation tests by comparing all requests made by both users to test cross-user authorization. The system analyzes the similarity in responses and evaluates the estimated sensitivity of each endpoint to detect potential authorization breaches.

For instance, consider a GraphQL schema exposing a User object with an email field. Without proper tenant isolation, there's potential for users to see others' email addresses - in some cases, a clear violation of privacy. GraphQL brings its own set of challenges, where diverse users or tenants might unintentionally access shared GraphQL objects.

Escape's advanced Tenant Isolation security tests ensure that separate users shouldn't access the same GraphQL object or scalar field value.

Example Configurations

Natural-language rule generation

This configuration allows you to instruct an LLM to generate a valid list of detectors that can tailor the security test to your use case.

You are able to review it from the scan logs, searching for [Agentic - Tenant Isolation]

security_tests:
  tenant_isolation:
    main_user: 'user1' # corresponds to your authentication username
    natural_language_rule: |
      Ensure that a user's notes cannot be accessed by other users.

You can view the generation of the rule

rule-generation.png

And if an issue was found, it will also be repeated:

alert-found.png

Default rule

security_tests:
  tenant_isolation:
    main_user: 'user1' # corresponds to your authentication username
    other_users:
      detect: # conditions on which the isolation is considered broken. 
      # Here by default: If the 2 responses come from an authenticated user, and their fingerprints are the same
      - if_: request.is_authenticated
        is_: true
      - if_: helpers.fingerprints.same
        is_: true

It will validate that:

  • between 2 users
  • for the same request and simply switching their authentications
  • the response fingerprints are the same

This yields a great default detection for most cases.

Custom detection rule

You might have trickier scenarios, for example if your responses slightly vary between users (timestamps, other data), but you want to target a specific part that should not be the same across tenants or users.

security_tests:
  tenant_isolation:
    main_user: user1
    other_users:
      detect:
        - if: helpers.json_matches.all # the values extracted are the same between users
          jq: '.notes[].content'
          is: true
        - if: helpers.regex_matches.all # the values extracted are the same between users
          regex: '.*User 1 Private Note.*'
          is: true

Of course, the detect block support all other kinds of detectors from Custom Rules

For more information, see the Tenant Isolation documentation.

High Number of Custom Scalars

Data sensitivity demands that certain data remains accessible only to authorized users.

Say, you're aware that Bob shouldn't access Alice's email: alice@example.com. Instead of setting up multiple manual tests to check this, Escape can automatically validate this for you with the Private Data security test.

The High Number of Custom Scalars security test can be configured to analyze all responses and ensure that the scalars you've defined do not leak.

You can configure Custom Scalars by checking the Custom Payloads - Custom Scalars

Example Configuration:

security_tests:
  high_number_of_custom_scalars:
    assets_allowed:
    - REST
    - GRAPHQL
    - WEBAPP
    detection_threshold: 4
    skip: false