Potential Okta Brute Force (Device Token Rotation)

Last updated 13 days ago on 2026-02-19
Created 2 years ago on 2024-06-17

About

Detects potential brute force attacks against a single Okta user account where excessive unique device token hashes are generated, indicating automated tooling that fails to persist browser cookies between attempts.
Tags
Domain: IdentityUse Case: Identity and Access AuditData Source: OktaTactic: Credential AccessLanguage: esql
Severity
low
Risk Score
21
MITRE ATT&CK™

Credential Access (TA0006)(external, opens in a new tab or window)

False Positive Examples
A user experiencing login issues may generate multiple device tokens through repeated legitimate attempts.Automated testing or monitoring tools that do not persist cookies may trigger this rule.
License
Elastic License v2(external, opens in a new tab or window)

Definition

Integration Pack
Prebuilt Security Detection Rules
Related Integrations

okta(external, opens in a new tab or window)

Query
text code block:
FROM logs-okta.system-* METADATA _id, _version, _index | WHERE event.dataset == "okta.system" AND (event.action LIKE "user.authentication.*" OR event.action == "user.session.start") AND okta.outcome.reason IN ("INVALID_CREDENTIALS", "LOCKED_OUT") AND okta.actor.alternate_id IS NOT NULL // Primary authn endpoint; sessions API provides additional coverage AND ( okta.debug_context.debug_data.request_uri == "/api/v1/authn" OR okta.debug_context.debug_data.request_uri LIKE "/api/v1/sessions*" ) // Track whether each event has a device token | EVAL has_dt_hash = CASE(okta.debug_context.debug_data.dt_hash IS NOT NULL, 1, 0) // Aggregate by IP + user to detect single-user brute force | STATS Esql.unique_dt_hashes = COUNT_DISTINCT(okta.debug_context.debug_data.dt_hash), Esql.total_attempts = COUNT(*), Esql.attempts_with_dt = SUM(has_dt_hash), Esql.unique_user_agents = COUNT_DISTINCT(okta.client.user_agent.raw_user_agent), Esql.first_seen = MIN(@timestamp), Esql.last_seen = MAX(@timestamp), Esql.dt_hash_values = VALUES(okta.debug_context.debug_data.dt_hash), Esql.event_action_values = VALUES(event.action), Esql.user_agent_values = VALUES(okta.client.user_agent.raw_user_agent), Esql.device_values = VALUES(okta.client.device), Esql.is_proxy_values = VALUES(okta.security_context.is_proxy), Esql.geo_country_values = VALUES(client.geo.country_name), Esql.geo_city_values = VALUES(client.geo.city_name), Esql.source_asn_values = VALUES(source.as.number), Esql.source_asn_org_values = VALUES(source.as.organization.name), Esql.threat_suspected_values = VALUES(okta.debug_context.debug_data.threat_suspected), Esql.risk_level_values = VALUES(okta.debug_context.debug_data.risk_level), Esql.risk_reasons_values = VALUES(okta.debug_context.debug_data.risk_reasons) BY okta.client.ip, okta.actor.alternate_id // Calculate automation detection metrics (float-safe division) | EVAL Esql.dt_coverage = Esql.attempts_with_dt * 1.0 / Esql.total_attempts, Esql.dt_per_attempt = Esql.unique_dt_hashes * 1.0 / Esql.total_attempts // Detection branches: // A) Many unique DT hashes relative to attempts = tooling generating new tokens per attempt // B) High attempts + very low DT coverage = cookie-less automation (no DT sent at all) // C) Multiple user agents for same user = evasion or automation | WHERE (Esql.unique_dt_hashes >= 7 AND Esql.total_attempts >= 10 AND Esql.dt_per_attempt >= 0.5) OR (Esql.total_attempts >= 12 AND Esql.dt_coverage < 0.15) OR (Esql.total_attempts >= 10 AND Esql.unique_user_agents >= 5) | SORT Esql.total_attempts DESC | KEEP Esql.*, okta.client.ip, okta.actor.alternate_id

Install detection rules in Elastic Security

Detect Potential Okta Brute Force (Device Token Rotation) in the Elastic Security detection engine by installing this rule into your Elastic Stack.

To setup this rule, check out the installation guide for Prebuilt Security Detection Rules(external, opens in a new tab or window).