Detection rules › Sigma

Refresh Token Reuse Detection

Status
experimental
Severity
medium
Time window
1d
Log source
product auth0
Author
Okta
Source
github.com/auth0/auth0-customer-detections

This detection alerts when a refresh token is reused in an unsuccessful exchange attempt. Reusing refresh tokens can indicate an attempt to exploit the token or a misconfiguration in the application. This detection requires that the token rotation is enabled for an application.

MITRE ATT&CK coverage

Rule body yaml

title: Refresh Token Reuse Detection
id: a7b2e75c-7171-11f0-aa28-723487b9527c
name: selected_events
status: experimental
description: |
    This detection alerts when a refresh token is reused in an unsuccessful exchange attempt.
    Reusing refresh tokens can indicate an attempt to exploit the token or a misconfiguration in the application.
    This detection requires that the token rotation is enabled for an application.
author: Okta
date: 2025-07-11
modified: 2025-09-02
logsource:
    product: auth0
detection:
    selection:
        data.type: ferrt
        data.description: "Unsuccessful Refresh Token exchange, reused refresh token detected"
    condition: selection
explanation: >
    The query collects events issued when reuse is detected, i.e. ferrt.
    The Splunk query below also collects the number of affected users and total amount of violations.
    The alert is triggered when two criteria are met - 1. excessive number of violations is observed; 2. reuse is detected for too many users.
    It displays affected users.
splunk: |
    index=auth0 data.tenant_name="{your-tenant-name}"
    data.type=ferrt
    data.description="Unsuccessful Refresh Token exchange, reused refresh token detected"
    | fields data.user_id data.type
    | stats count(data.type) as detected_reuse_counter by data.user_id
    | where detected_reuse_counter > {excessive_reuse_threshold}
    | eventstats dc(data.user_id) as affected_users_total_count
    | where affected_users_total_count > {effected_users_threshold}
    ```Show the affected users in a table```
    | table data.user_id detected_reuse_counter
comments:
    - The Splunk query above shall be tuned to reflect a valid tenant name, and two thresholds.
    - The excessive_reuse_threshold is the number of reuse events for a single user that should trigger an alert.
    - The effected_users_threshold is the number of users that should be affected by the reuse to trigger an alert.
tenant_logs: |
    type: "ferrt" AND description: "Unsuccessful Refresh Token exchange, reused refresh token detected"
prevention:
    - Ensure that the application uses refresh tokens correctly to exclude misconfiguration as a cause of the reuse.
    - When tokens are requested by a frontend application, i.e. SPA, ensure that the application is not vulnerable to XSS that leads to token theft.
    - Terminate sessions and revoke tokens for affected users to pause the attack, however, it might come back when the user logs in again.
    - Deploy a post-login action that will compare IP/ASN of initial issuing of a refresh token and IP/ASN of the current refresh token.
      If they are different, terminate the session and revoke all refresh tokens.
    - This measure can help to prevent sophisticated forms of refresh token hijacking attacks, when an adversary times when the application will
      be shut down and thus avoiding a risk of rotation policy violation.
    - Consider to add additional layers to protect access tokens - sender-constrained flows (DPoP or mTLS) to address the possesion issue,
      back-channel logout to be able to revoke tokens, externalized authorization, e.g. with FGA, to avoid relying on permissions written in access tokens.
falsepositives:
    - Misconfigured applications that are caching refresh tokens.
    - Configured rotation overlap period is not adequate for application needs.
level: medium
tags:
    - attack.credential-access
    - attack.persistence
    - attack.t1550.001
    - attack.t1078
---
title: Refresh Token Reuse Detection - Correlation
correlation:
    type: event_count
    rules:
        - selected_events # Referenced here
    group-by:
        - data.user_id
    timespan: 1d
    condition:
        gte: 1
        field: data.type

Stages and Predicates

Stage 0: condition

selection

Stage 1: selection

selection:
    data.type: ferrt
    data.description: "Unsuccessful Refresh Token exchange, reused refresh token detected"

Indicators

Each row is a field, operator, and value that the rule matches. The corpus column counts how many other rules in the catalog look for the same combination: high numbers point to widely-used, community-vetted indicators. Blank or 1 shows that the indicator is specific to this rule.

FieldKindValues
data.descriptioneq
  • Unsuccessful Refresh Token exchange, reused refresh token detected
data.typeeq
  • ferrt