Skip to content

Commit aa89d25

Browse files
terrancedejesusDefSecSentinelshashank-elastic
authored
[Rule Tuning] Multiple Device Token Hashes for Single Okta Session (#5948)
Fixes #5947 Co-authored-by: Colson Wilhoit <48036388+DefSecSentinel@users.noreply.github.com> Co-authored-by: shashank-elastic <91139415+shashank-elastic@users.noreply.github.com>
1 parent d8a3986 commit aa89d25

1 file changed

Lines changed: 70 additions & 45 deletions

File tree

rules/integrations/okta/credential_access_multiple_device_token_hashes_for_single_okta_session.toml

Lines changed: 70 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2,54 +2,54 @@
22
creation_date = "2023/11/08"
33
integration = ["okta"]
44
maturity = "production"
5-
updated_date = "2026/04/10"
5+
updated_date = "2026/04/13"
66

77
[rule]
88
author = ["Elastic"]
99
description = """
10-
This rule detects when a specific Okta actor has multiple device token hashes for a single Okta session. This may
11-
indicate an authenticated session has been hijacked or is being used by multiple devices. Adversaries may hijack a
12-
session to gain unauthorized access to Okta admin console, applications, tenants, or other resources.
10+
This rule detects when a specific Okta actor has multiple device token hashes and multiple source IPs for a single Okta
11+
session. This may indicate an authenticated session has been hijacked or replayed from a different device and network.
12+
Adversaries may steal session cookies or tokens to gain unauthorized access to Okta admin console, applications,
13+
tenants, or other resources.
1314
"""
1415
from = "now-9m"
16+
interval = "8m"
1517
language = "esql"
1618
license = "Elastic License v2"
1719
name = "Multiple Device Token Hashes for Single Okta Session"
1820
note = """## Triage and analysis
1921
2022
### Investigating Multiple Device Token Hashes for Single Okta Session
2123
22-
This rule detects when a specific Okta actor has multiple device token hashes for a single Okta session. This may indicate an authenticated session has been hijacked or is being used by multiple devices. Adversaries may hijack a session to gain unauthorized access to Okta admin console, applications, tenants, or other resources.
24+
This rule detects when a specific Okta actor has multiple device token hashes and multiple source IPs for a single Okta session. This may indicate an authenticated session has been hijacked or replayed from a different device and network. Adversaries may steal session cookies or tokens to gain unauthorized access to Okta admin console, applications, tenants, or other resources.
25+
26+
> **Note**: This is an ES|QL aggregation-based rule. Exceptions can be added on the original ECS or integration-related fields. We recommend using the indicators from the alert document to pivot into the raw events for analysis.
2327
2428
#### Possible investigation steps:
25-
- Since this is an ESQL rule, the `okta.actor.alternate_id` and `okta.authentication_context.external_session_id` values can be used to pivot into the raw authentication events related to this alert.
26-
- Identify the users involved in this action by examining the `okta.actor.id`, `okta.actor.type`, `okta.actor.alternate_id`, and `okta.actor.display_name` fields.
27-
- Determine the device client used for these actions by analyzing `okta.client.ip`, `okta.client.user_agent.raw_user_agent`, `okta.client.zone`, `okta.client.device`, and `okta.client.id` fields.
28-
- With Okta end users identified, review the `okta.debug_context.debug_data.dt_hash` field.
29-
- Historical analysis should indicate if this device token hash is commonly associated with the user.
30-
- Review the `okta.event_type` field to determine the type of authentication event that occurred.
31-
- Authentication events have been filtered out to focus on Okta activity via established sessions.
32-
- Review the past activities of the actor(s) involved in this action by checking their previous actions.
33-
- Evaluate the actions that happened just before and after this event in the `okta.event_type` field to help understand the full context of the activity.
34-
- This may help determine the authentication and authorization actions that occurred between the user, Okta and application.
35-
- Aggregate by `okta.actor.alternate_id` and `event.action` to determine the type of actions that are being performed by the actor(s) involved in this action.
36-
- If various activity is reported that seems to indicate actions from separate users, consider deactivating the user's account temporarily.
29+
- Use `okta.actor.alternate_id` and `okta.authentication_context.external_session_id` from the alert to pivot into the raw Okta system log events for the affected session.
30+
- Review the source IPs (`okta.client.ip`) and ASN information (`source.as.organization.name`) to determine if the session was used from multiple distinct networks.
31+
- Multiple ASNs or geolocations (`client.geo.country_name`, `client.geo.city_name`) within the same session strongly suggest session hijacking.
32+
- Compare the `okta.debug_context.debug_data.dt_hash` values to identify the device token hashes associated with the session.
33+
- A legitimate session should have a consistent device token hash. Multiple distinct hashes indicate the session cookie may have been replayed from a different device.
34+
- Examine `okta.client.user_agent.raw_user_agent` and `okta.client.device` for inconsistencies that suggest different devices or browsers using the same session.
35+
- Review `event.action` to understand what actions were performed during the session.
36+
- Look for suspicious post-authentication activity such as admin console access, policy changes, or application assignment modifications.
37+
- Check `okta.debug_context.debug_data.risk_level`, `okta.debug_context.debug_data.risk_reasons`, and `okta.debug_context.debug_data.behaviors` for Okta's own risk assessment of the session activity.
38+
- Review the past activities of the actor(s) involved by checking their previous sessions and login patterns.
3739
3840
### False positive analysis:
39-
- It is very rare that a legitimate user would have multiple device token hashes for a single Okta session as DT hashes do not change after an authenticated session is established.
41+
- OAuth application integrations (e.g., backend services exchanging authorization codes for tokens) can generate multiple device token hashes per session due to the multi-step token grant flow. These typically involve `Okta-Integrations` user agents and known infrastructure IPs.
42+
- Users switching between networks (e.g., VPN reconnects, WiFi to cellular transitions) may produce multiple source IPs for the same session, though the device token hash should remain consistent.
43+
- Automated tools or scripts that interact with Okta APIs on behalf of a user may generate additional device token hashes.
4044
4145
### Response and remediation:
42-
- Consider stopping all sessions for the user(s) involved in this action.
43-
- If this does not appear to be a false positive, consider resetting passwords for the users involved and enabling multi-factor authentication (MFA).
44-
- If MFA is already enabled, consider resetting MFA for the users.
45-
- If any of the users are not legitimate, consider deactivating the user's account.
46-
- Conduct a review of Okta policies and ensure they are in accordance with security best practices.
47-
- Check with internal IT teams to determine if the accounts involved recently had MFA reset at the request of the user.
48-
- If so, confirm with the user this was a legitimate request.
49-
- If so and this was not a legitimate request, consider deactivating the user's account temporarily.
50-
- Reset passwords and reset MFA for the user.
51-
- Alternatively adding `okta.client.ip` or a CIDR range to the `exceptions` list can prevent future occurrences of this event from triggering the rule.
52-
- This should be done with caution as it may prevent legitimate alerts from being generated.
46+
- If the alert shows multiple distinct ASNs or geolocations for the same session, immediately revoke all active sessions for the affected user via the Okta admin console.
47+
- Reset the user's password and all active MFA factors.
48+
- If MFA is not enabled, enforce MFA enrollment before allowing re-authentication.
49+
- Review Okta system logs for any administrative or sensitive actions performed during the suspicious session window.
50+
- If the session was used to access downstream applications, review those application logs for unauthorized activity.
51+
- Check with the user to confirm whether they were actively using Okta during the alert time window.
52+
- For recurring false positives from known integrations, add exceptions on `okta.actor.alternate_id` for the specific service account or application client ID.
5353
"""
5454
references = [
5555
"https://developer.okta.com/docs/reference/api/system-log/",
@@ -62,22 +62,20 @@ references = [
6262
]
6363
risk_score = 47
6464
rule_id = "cc382a2e-7e52-11ee-9aac-f661ea17fbcd"
65-
setup = """## Setup
66-
67-
The Okta Fleet integration, Filebeat module, or similarly structured data is required to be compatible with this rule."""
6865
severity = "medium"
6966
tags = [
70-
"Use Case: Identity and Access Audit",
67+
"Domain: Identity",
68+
"Domain: SaaS",
7169
"Data Source: Okta",
70+
"Data Source: Okta System Logs",
7271
"Tactic: Credential Access",
73-
"Domain: SaaS",
7472
"Resources: Investigation Guide",
7573
]
7674
timestamp_override = "event.ingested"
7775
type = "esql"
7876

7977
query = '''
80-
from logs-okta*
78+
from logs-okta.system-*
8179
| where
8280
data_stream.dataset == "okta.system" and
8381
not event.action in (
@@ -87,21 +85,48 @@ from logs-okta*
8785
) and
8886
okta.actor.alternate_id != "system@okta.com" and
8987
okta.actor.alternate_id rlike "[^@\\s]+\\@[^@\\s]+" and
90-
okta.authentication_context.external_session_id != "unknown"
91-
| keep
92-
event.action,
93-
okta.actor.alternate_id,
94-
okta.authentication_context.external_session_id,
95-
okta.debug_context.debug_data.dt_hash
88+
okta.authentication_context.external_session_id != "unknown" and
89+
(
90+
okta.authentication_context.external_session_id IS NOT NULL and
91+
okta.debug_context.debug_data.dt_hash IS NOT NULL and
92+
okta.client.ip IS NOT NULL and
93+
okta.client.user_agent.raw_user_agent IS NOT NULL
94+
) and
95+
(
96+
okta.authentication_context.external_session_id != "-" and
97+
okta.debug_context.debug_data.dt_hash != "-" and
98+
okta.client.user_agent.raw_user_agent != "-"
99+
)
96100
| stats
97-
Esql.okta_debug_context_debug_data_dt_hash_count_distinct = count_distinct(okta.debug_context.debug_data.dt_hash)
101+
Esql.dt_hash_count_distinct = count_distinct(okta.debug_context.debug_data.dt_hash),
102+
Esql.client_ip_count_distinct = count_distinct(okta.client.ip),
103+
Esql.event_count = count(*),
104+
Esql.first_event_time = min(@timestamp),
105+
Esql.last_event_time = max(@timestamp),
106+
Esql.dt_hash_values = values(okta.debug_context.debug_data.dt_hash),
107+
Esql.event_action_values = values(event.action),
108+
Esql.client_ip_values = values(okta.client.ip),
109+
Esql.user_agent_values = values(okta.client.user_agent.raw_user_agent),
110+
Esql.device_values = values(okta.client.device),
111+
Esql.is_proxy_values = values(okta.security_context.is_proxy),
112+
Esql.geo_country_name_values = values(client.geo.country_name),
113+
Esql.geo_city_name_values = values(client.geo.city_name),
114+
Esql.source_asn_number_values = values(source.`as`.number),
115+
Esql.source_asn_org_name_values = values(source.`as`.organization.name),
116+
Esql.threat_suspected_values = values(okta.debug_context.debug_data.threat_suspected),
117+
Esql.risk_level_values = values(okta.debug_context.debug_data.risk_level),
118+
Esql.risk_reasons_values = values(okta.debug_context.debug_data.risk_reasons),
119+
Esql.behaviors_values = values(okta.debug_context.debug_data.behaviors),
120+
Esql.device_fingerprint_values = values(okta.debug_context.debug_data.device_fingerprint),
121+
Esql.risk_behaviors_values = values(okta.debug_context.debug_data.risk_behaviors),
122+
Esql.request_uri_values = values(okta.debug_context.debug_data.request_uri)
98123
by
99124
okta.actor.alternate_id,
100125
okta.authentication_context.external_session_id
101126
| where
102-
Esql.okta_debug_context_debug_data_dt_hash_count_distinct >= 2
103-
| sort
104-
Esql.okta_debug_context_debug_data_dt_hash_count_distinct desc
127+
Esql.dt_hash_count_distinct >= 4 and
128+
Esql.client_ip_count_distinct >= 2
129+
| keep Esql.*, okta.*
105130
'''
106131

107132

0 commit comments

Comments
 (0)