Detection rules › Sigma

Credential stuffing sttack risk

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

Detects potential credential stuffing attacks by monitoring failed logins and Auth0 Attack Protection feature events.

MITRE ATT&CK coverage

TacticTechniques
Credential AccessT1110.004 Brute Force: Credential Stuffing

Rule body yaml

title: Credential stuffing sttack risk
name: selected_events
id: e604e40e-9db6-449d-854d-2b5323644fd7
status: experimental
description: |
    Detects potential credential stuffing attacks by monitoring failed logins and Auth0 Attack Protection feature events.
author: Okta
date: 2025-10-15
modified: 2025-10-15
references:
    - https://auth0.com/docs/secure/attack-protection/view-attack-protection-events
logsource:
    product: auth0
detection:
    selection:
        data.type:
            - f # Failed login
            - fu # Failed login: Invalid username or email
            - fp  # Failed login: Incorrect password
            - pwd_leak # Attempt to login with a known breached password
            - limit_wc # User blocked from logging in from a specific IP
            - limit_sul # User blocked from logging in from all IPs
            - limit_mu # IP address block from logging in
            - fcoa # Failed cross-origin authentication
    condition: selection
explanation: >
    This rule identifies **credential stuffing** activity by analyzing patterns of **failed logins** (f, fu, fp, fcoa)
    and **Auth0 Attack Protection** events (pwd_leak, limit_wc, limit_sul, limit_mu).
    The accompanying Splunk query includes three distinct detection **Signals** over 1-hour windows:
    **Signal 1** (High volume of failed/attack protection events from a single IP),
    **Signal 2** (Significant surge in total failed/protection events),
    and **Signal 3** (Anomalous spike in unique source IP addresses, indicating a botnet).
    The query also incorporates **normality** calculations for comparison and collects JA3/JA4 TLS fingerprint data for
    attack traffic clustering and investigation.
    The Sigma correlation feature implements Signal 1 (count per IP), but lacks normality calculation.
splunk: |
    index=auth0 data.tenant_name="{your-tenant-name}"
    data.type IN (f, fu, fp, pwd_leak, limit_wc, limit_sul, limit_mu, fcoa)

    ``` Signal 1 - any single IP triggers excessive number of failed/attack protection events ```
    | bin _time span=1h
    | stats values(data.security_context.ja4) as ja4
     count as cnt_events_per_ip by _time data.ip
    | where cnt_events_per_ip > {threshold_events_per_ip}
    ``` Normality for Signal 1 - average number of successful logins per IP (per hour) ```
    | join [
        search index=auth0 data.type = s
        | stats count AS successful_logins_per_ip by data.ip
        | stats avg(successful_logins_per_ip) AS avg_successful_logins_per_ip
    ]

    ``` Signal 2 - surge in failed login or attack protection events ```
    ```
    | stats values(data.security_context.ja4) as ja4
    count as cnt_total_per_event by _time data.type
    | where cnt_total_per_event > {threshold_count_per_event}```
    ``` Normality for Signal 2 - average number successful logins (per hour) ```
    ```
    | join [
        search index=auth0 data.type = s
        | stats count AS successful_logins_per_s by data.type
        | stats avg(successful_logins_per_s) AS avg_successful_logins_per_s
    ]```

    ``` Signal 3 - surge of observed IPs with failed events ```
    ```
    | stats dc(data.ip) as cnt_total_ips values(data.ip) as ip
      values(data.security_context.ja4) as ja4 by _time
    | where cnt_total_ips > {threshold_total_ips}```
    ``` Normality for Signal 3 - average number of IPs with successful logins (per hour) ```
    ```| join [
        search index=auth0 data.type = s
        | stats dc(data.ip) AS successful_logins_ips by _time
        | stats avg(successful_logins_ips) AS avg_successful_logins_ips
    ]```
comments:
    - The Splunk query above shall be tuned to reflect a valid tenant name,
      and one of the three thresholds (selected) - number of events per IP, i.e. {threshold_events_per_ip};
      number of failed events in total, i.e. {threshold_count_per_event};
      and total number of unique IPs, i.e .{threshold_total_ips}.
    - The detection can be adjusted to monitor the attack protection feature in use.
    - Failed login events (f, fu, fp, fcoa) could be monitored separately from Attack Protection events
      (pwd_leak, limit_wc, limit_sul, limit_mu).
    - If IP enrichment data is available, consider monitoring for traffic originating from unexpected locations
      (e.g., anonymizing proxies, Tor exit nodes, irrelevant countries).
    - Often the abnormal rates of failed events tend to happen without much change to the rate of successful logins.
tenant_logs: |
    type: (f fu fp pwd_leak limit_wc limit_sul limit_mu fcoa)
prevention:
    - Require MFA for password-based authentication flows
    - Migrate to passwordless or passkeys as a preferred login method
    - Use Bot Protection, Suspicious IP throttling, and Breached Password Protection, and Brute Force Protection
      to present CAPTCHA challenges to requests from suspicious IPs
    - Apply strong password policies (e.g. disallow common passwords)
    - Use 3rd party Auth0 Actions, e.g. from Auth0 Marketplace, integrations to check if an IP is associated with an anonymizing proxies
    - Deny access by location using Network ACL, WAF or via the Country-based Access Control post-login Actions
    - Analyze if suspicious traffic (failed events) can be attributed to specific JA3/JA4 fingerprints
      and block/monitor/redirect it using the Network ACL feature.
falsepositives:
    - ja3/ja4 might be attributed to legitimate traffic
level: medium
tags:
    - attack.credential-access
    - attack.t1110.004
---
title: Credential stuffing sttack risk - correlated rule # This correlation implements Signal 1 from the Splunk query above. Adjust for Signal 2 or Signal 3 if needed.
correlation:
    type: event_count
    rules:
        - selected_events # Referenced here
    group-by:
        - data.ip
    timespan: 1h
    condition:
        gt: 1

Stages and Predicates

Stage 0: condition

selection

Stage 1: selection

selection:
    data.type:
        - f
        - fu
        - fp
        - pwd_leak
        - limit_wc
        - limit_sul
        - limit_mu
        - fcoa

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.typeeq
  • f
  • fcoa
  • fp
  • fu
  • limit_mu
  • limit_sul
  • limit_wc
  • pwd_leak