Detection rules › Panther

Salesforce OAuth Credential Abuse Detection

Severity
medium
Group by
CONNECTED_APP_ID, EVENT_TYPE, USER_ID
Entities
actor_ids, ip_addresses, trace_ids, usernames
Log types
Salesforce.RealtimeEvent
Tags
Salesforce, OAuth, Credential Abuse, Token Theft, API Abuse
Reference
https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_oauthtoken.htm
Source
github.com/panther-labs/panther-analysis

Detects OAuth credential abuse and suspicious token usage patterns in Salesforce. OAuth tokens provide API access and can be abused if compromised, making this detection critical for: - Stolen or leaked OAuth tokens - Token replay attacks - Excessive API usage indicating automated abuse - Failed token refresh attempts (potential brute force) - Unauthorized token revocations This detection triggers on OAuth-related security events and adjusts severity based on: - Token revocation events (may indicate compromise response) - Failed OAuth operations (potential attack attempts) - Excessive API usage patterns

MITRE ATT&CK coverage

Rule body yaml

AnalysisType: rule
Description: |
  Detects OAuth credential abuse and suspicious token usage patterns in Salesforce. OAuth tokens provide API access and can be abused if compromised, making this detection critical for:
  - Stolen or leaked OAuth tokens
  - Token replay attacks
  - Excessive API usage indicating automated abuse
  - Failed token refresh attempts (potential brute force)
  - Unauthorized token revocations

  This detection triggers on OAuth-related security events and adjusts severity based on:
  - Token revocation events (may indicate compromise response)
  - Failed OAuth operations (potential attack attempts)
  - Excessive API usage patterns
DisplayName: "Salesforce OAuth Credential Abuse Detection"
Enabled: true
Filename: salesforce_oauth_credential_abuse.py
Runbook: |
  1. Identify the event type and severity of the OAuth activity
  2. Determine if this is a revocation (possible compromise) or failure (attack attempt)
  3. Review the user and connected app involved
  4. Check for multiple failed attempts from the same source
  5. Investigate the source IP and geolocation
  6. Review API usage patterns for anomalies
  7. If token compromise suspected:
     - Immediately revoke all active OAuth tokens for the affected app/user
     - Reset user credentials
     - Review all API calls made using the compromised token
     - Check for data exfiltration or unauthorized changes
     - Contact the connected app owner if third-party
  8. Consider implementing OAuth token rotation policies and IP restrictions
Reference: https://developer.salesforce.com/docs/atlas.en-us.object_reference.meta/object_reference/sforce_api_objects_oauthtoken.htm
Severity: Medium
Tests:
  - ExpectedResult: true
    Log:
      EVENT_TYPE: OAuthTokenRevoked
      TIMESTAMP: "2024-01-30 17:45:30.123"
      TIMESTAMP_DERIVED: "2024-01-30 17:45:30.123"
      EVENT_DATE: "2024-01-30"
      ORGANIZATION_ID: 00D5f000005uVo7
      USER_ID: 0055f00000RzTCE
      USER_ID_DERIVED: 0055f00000RzTCEIII
      USER_NAME: security.admin@company.com
      USER_TYPE: Standard
      SOURCE_IP: 10.10.10.10
      REQUEST_ID: 9HzSED8SpDD3JDW-CCZkX-
      CONNECTED_APP_ID: 0H05f000000XzDqEEN
      CONNECTED_APP_NAME: CompromisedApp
      CLIENT_ID: 3MVG9yZ.WNe6byQCPj8xYzKlMqR
      STATUS: Success
      SESSION_KEY: kN3pP6huf17t3/Ao
      p_event_time: "2024-01-30 17:45:30.123"
      p_parse_time: "2024-01-30 17:46:15.456"
      p_log_type: Salesforce.OAuthTokenRevoked
      p_row_id: o2t7r89s1pq3t5s4o7r0t2p6s9r1o3p5
      p_source_id: f7e3c18d-837b-461f-9c2e-7f2g4ffa2c17
      p_source_label: Salesforce - Production
      p_any_ip_addresses:
        - 10.10.10.10
      p_any_usernames:
        - security.admin@company.com
      p_any_actor_ids:
        - 0055f00000RzTCE
      p_any_trace_ids:
        - 9HzSED8SpDD3JDW-CCZkX-
    Name: OAuth Token Revoked - High Severity
  - ExpectedResult: true
    Log:
      EVENT_TYPE: OAuthTokenRefreshFailed
      TIMESTAMP: "2024-01-31 11:20:15.789"
      TIMESTAMP_DERIVED: "2024-01-31 11:20:15.789"
      EVENT_DATE: "2024-01-31"
      ORGANIZATION_ID: 00D5f000005uVo7
      USER_ID: 0055f00000SzUDF
      USER_ID_DERIVED: 0055f00000SzUDFJJJ
      USER_NAME: api.user@company.com
      USER_TYPE: Standard
      SOURCE_IP: 203.45.67.89
      REQUEST_ID: 0IATFe9TqEE4KEY-DDAlY-
      CONNECTED_APP_ID: 0H05f000000XzErFFO
      CONNECTED_APP_NAME: SuspiciousIntegration
      CLIENT_ID: 3MVG9yZ.WNe6byQCPj8xYzKl123
      STATUS: Failed
      SESSION_KEY: lO4qQ7ivg28u4/Bp
      p_event_time: "2024-01-31 11:20:15.789"
      p_parse_time: "2024-01-31 11:21:03.123"
      p_log_type: Salesforce.OAuthTokenRefreshFailed
      p_row_id: p3u8s90t2qr4u6t5p8s1u3q7t0s2p4q6
      p_source_id: f7e3c18d-837b-461f-9c2e-7f2g4ffa2c17
      p_source_label: Salesforce - Production
      p_any_ip_addresses:
        - 203.45.67.89
      p_any_usernames:
        - api.user@company.com
      p_any_actor_ids:
        - 0055f00000SzUDF
      p_any_trace_ids:
        - 0IATFe9TqEE4KEY-DDAlY-
    Name: OAuth Token Refresh Failed - Medium Severity
  - ExpectedResult: true
    Log:
      EVENT_TYPE: ApiTotalUsage
      TIMESTAMP: "2024-02-01 14:30:45.456"
      TIMESTAMP_DERIVED: "2024-02-01 14:30:45.456"
      EVENT_DATE: "2024-02-01"
      ORGANIZATION_ID: 00D5f000005uVo7
      USER_ID: 0055f00000TzVEG
      USER_ID_DERIVED: 0055f00000TzVEGKKK
      USER_NAME: integration.service@company.com
      USER_TYPE: Standard
      SOURCE_IP: 192.168.1.100
      REQUEST_ID: 1JBUGf0UrFF5LFZ-EEBmZ-
      CONNECTED_APP_ID: 0H05f000000XzFsGGP
      CONNECTED_APP_NAME: HighVolumeApp
      CLIENT_ID: 3MVG9yZ.WNe6byQCPj8xYzKl456
      API_TOTAL_COUNT: 15000
      STATUS: Success
      SESSION_KEY: mP5rR8jwh39v5/Cq
      p_event_time: "2024-02-01 14:30:45.456"
      p_parse_time: "2024-02-01 14:31:28.789"
      p_log_type: Salesforce.ApiTotalUsage
      p_row_id: q4v9t01u3rs5v7u6q9t2v4r8u1t3q5r7
      p_source_id: f7e3c18d-837b-461f-9c2e-7f2g4ffa2c17
      p_source_label: Salesforce - Production
      p_any_ip_addresses:
        - 192.168.1.100
      p_any_usernames:
        - integration.service@company.com
      p_any_actor_ids:
        - 0055f00000TzVEG
      p_any_trace_ids:
        - 1JBUGf0UrFF5LFZ-EEBmZ-
    Name: Excessive API Usage - High Severity
  - ExpectedResult: true
    Log:
      EVENT_TYPE: ApiConnectedApp
      TIMESTAMP: "2024-02-02 09:15:20.123"
      TIMESTAMP_DERIVED: "2024-02-02 09:15:20.123"
      EVENT_DATE: "2024-02-02"
      ORGANIZATION_ID: 00D5f000005uVo7
      USER_ID: 0055f00000UzWFH
      USER_ID_DERIVED: 0055f00000UzWFHLLL
      USER_NAME: normal.integration@company.com
      USER_TYPE: Standard
      SOURCE_IP: 172.16.0.100
      REQUEST_ID: 2KCVHg1VsGG6MGZ-FFCna-
      CONNECTED_APP_ID: 0H05f000000XzGtHHQ
      CONNECTED_APP_NAME: NormalApp
      CLIENT_ID: 3MVG9yZ.WNe6byQCPj8xYzKl789
      API_TOTAL_COUNT: 500
      STATUS: Success
      SESSION_KEY: nQ6sS9kxi40w6/Dr
      p_event_time: "2024-02-02 09:15:20.123"
      p_parse_time: "2024-02-02 09:16:05.456"
      p_log_type: Salesforce.ApiConnectedApp
      p_row_id: r5w0u12v4st6w8v7r0u3w5s9v2u4r6s8
      p_source_id: f7e3c18d-837b-461f-9c2e-7f2g4ffa2c17
      p_source_label: Salesforce - Production
      p_any_ip_addresses:
        - 172.16.0.100
      p_any_usernames:
        - normal.integration@company.com
      p_any_actor_ids:
        - 0055f00000UzWFH
      p_any_trace_ids:
        - 2KCVHg1VsGG6MGZ-FFCna-
    Name: Normal OAuth Usage - Default Severity
  - ExpectedResult: false
    Log:
      EVENT_TYPE: Login
      TIMESTAMP: "2024-02-03 10:30:15.789"
      TIMESTAMP_DERIVED: "2024-02-03 10:30:15.789"
      ORGANIZATION_ID: 00D5f000005uVo7
      USER_ID: 0055f00000VzXGI
      USER_ID_DERIVED: 0055f00000VzXGIMMM
      USER_NAME: regular.user@company.com
      USER_TYPE: Standard
      LOGIN_STATUS: LOGIN_NO_ERROR
      SOURCE_IP: 10.10.10.10
      REQUEST_ID: 3LDWIh2WtHH7NHa-GGDob-
      API_VERSION: "59.0"
      BROWSER_TYPE: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7)
      p_event_time: "2024-02-03 10:30:15.789"
      p_parse_time: "2024-02-03 10:31:02.123"
      p_log_type: Salesforce.Login
      p_row_id: s6x1v23w5tu7x9w8s1v4x6t0w3v5s7t9
      p_source_id: f7e3c18d-837b-461f-9c2e-7f2g4ffa2c17
      p_source_label: Salesforce - Production
      p_any_ip_addresses:
        - 10.10.10.10
      p_any_usernames:
        - regular.user@company.com
      p_any_actor_ids:
        - 0055f00000VzXGI
      p_any_trace_ids:
        - 3LDWIh2WtHH7NHa-GGDob-
    Name: Normal Login Event - Not OAuth
DedupPeriodMinutes: 60
LogTypes:
  - Salesforce.RealtimeEvent
RuleID: "Salesforce.OAuth.Credential.Abuse"
Threshold: 1
Tags:
  - Salesforce
  - OAuth
  - Credential Abuse
  - Token Theft
  - API Abuse
Reports:
  MITRE ATT&CK:
    - TA0006:T1528  # Credential Access: Steal Application Access Token
    - TA0006:T1110  # Credential Access: Brute Force
    - TA0005:T1550  # Defense Evasion: Use Alternate Authentication Material
    - TA0010:T1020  # Exfiltration: Automated Exfiltration

Detection logic

Condition

EVENT_TYPE in ["OAuthTokenRevoked", "OAuthTokenRefreshFailed", "ApiTotalUsage", "ApiConnectedApp"] or EVENT_TYPE contains "oauth"

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
EVENT_TYPEcontains
  • oauth
EVENT_TYPEin
  • ApiConnectedApp
  • ApiTotalUsage
  • OAuthTokenRefreshFailed
  • OAuthTokenRevoked

Output fields

Fields the rule emits when it matches. Chronicle authors list these in the outcome block; they appear on the detection and $risk_score drives alerting. Sentinel / Defender XDR rules build them up through project / summarize / extend stages. Sentinel maps these into alert fields via entityMappings and customDetails; Defender XDR custom detections surface them as alert fields directly.

FieldSource
Event TypeEVENT_TYPE
User IDUSER_ID
UsernameUSER_NAME
Connected App IDCONNECTED_APP_ID
Connected App NameCONNECTED_APP_NAME
Client IDCLIENT_ID
Client NameCLIENT_NAME
Source IPSOURCE_IP
StatusSTATUS
API Total CountAPI_TOTAL_COUNT
Request IDREQUEST_ID
Organization IDORGANIZATION_ID
Session KeySESSION_KEY