7. Detection patterns

StatusStable
Version2.0.0
Last updated2026-01-31
AuthorsOpenALBA Working Group

7.1 Overview

This section defines specific detection patterns for common behavioral anomalies. Each pattern includes signal definitions, scoring weights, risk multipliers, and MITRE ATT&CK mappings where applicable.

7.2 User behavioral anomalies

7.2.1 Request volume anomaly

Request Volume Anomalyyaml
name: user_request_volume_anomaly
signals:
  primary: user.request_count
  baseline_window: 30 days
  detection_window: 1 hour
  method: modified_zscore

thresholds:
  zscore: 2.5
  min_absolute_deviation: 50

weights:
  deviation: 0.45
  rarity: 0.20
  velocity: 0.25
  persistence: 0.10

risk_multipliers:
  security:
    high_volume: 1.5  # Automation/scraping
    low_volume: 0.8
  ops:
    high_volume: 1.3  # Capacity
    low_volume: 0.5

mitre: T1078 (Valid Accounts), T1530 (Data from Cloud Storage)

7.2.2 Geographic anomaly

Geographic Anomalyyaml
name: geographic_anomaly
signals:
  new_country:
    method: set_membership
    baseline: 90 days
  impossible_travel:
    method: velocity_check
    threshold: 800 km/h

scoring:
  new_country_base: 60
  impossible_travel: 90
  high_risk_country_bonus: 20
  vpn_detected_reduction: -20

weights:
  deviation: 0.20
  rarity: 0.55  # Rarity is key
  velocity: 0.15
  persistence: 0.10

risk_multipliers:
  security: 2.5
  ops: 0.8

mitre: T1078 (Valid Accounts), T1021 (Remote Services)

7.2.3 Data access volume anomaly

Data Access Volume Anomalyyaml
name: data_access_volume_anomaly
signals:
  - user.response_bytes_total (weight: 0.4)
  - user.data_records_accessed (weight: 0.4)
  - user.sensitive_endpoint_access_count (weight: 0.2)

calculation:
  self_deviation = (current - user_baseline.mean) / user_baseline.stddev
  peer_deviation = (current - peer_baseline.mean) / peer_baseline.stddev
  deviation_score = max(self_deviation, peer_deviation) × 20

thresholds:
  bytes_zscore: 3.0
  records_zscore: 3.0
  absolute_records: 1000  # Always flag

risk_multipliers:
  security:
    base: 2.0
    export_endpoint: 2.0
    pii_data: 1.5
    pre_termination: 3.0  # HR flag
  ops: 0.5

mitre: T1567 (Exfiltration Over Web Service)

7.3 Service behavioral anomalies

7.3.1 Error rate anomaly

Error Rate Anomalyyaml
name: service_error_rate_anomaly
signals:
  primary: service.error_rate
  baseline_window: 7 days
  detection_window: 5 minutes
  seasonal_adjustment: true

breakdown_by:
  - http.response.status_code
  - error.type
  - http.route

weights:
  deviation: 0.50
  rarity: 0.15
  velocity: 0.30  # Sudden spike key
  persistence: 0.05

thresholds:
  zscore: 2.5
  absolute_rate: 0.05  # 5%
  min_volume: 100

risk_multipliers:
  security:
    5xx_spike: 0.5
    401_spike: 1.5  # Auth failures
    403_spike: 1.3  # Authz failures
  ops:
    base: 2.0
    customer_facing: 1.5
  engineering:
    after_deploy: 2.0

mitre: T1499 (Endpoint DoS), T1190 (Exploit Public-Facing App)

7.3.2 Dependency anomaly

Dependency Anomalyyaml
name: service_dependency_anomaly
signals:
  new_destination:
    metric: outbound_destinations
    baseline: 14 days
    method: set_membership
  call_volume_change:
    metric: dependency.call_count
    method: zscore
  error_rate_change:
    metric: dependency.error_rate
    method: zscore

new_destination_scoring:
  internal_ip_new_service: 40
  internal_ip_known_service: 20
  external_ip_known_provider: 50
  external_ip_unknown: 80
  external_ip_high_risk_country: 95

ip_enrichment:
  - geoip (country, ASN)
  - threat_intel (known bad)
  - cloud_provider (AWS/GCP/Azure)
  - reverse_dns

risk_multipliers:
  security:
    new_external: 2.5
    high_risk_geo: 2.0
    data_service: 2.0
  ops:
    new_destination: 1.2
    dependency_degradation: 2.0

mitre: T1071 (App Layer Protocol), T1041 (Exfil Over C2)

7.4 Authentication anomalies

7.4.1 Brute force detection

Brute Force Detectionyaml
name: brute_force_detection
signals:
  by_source_ip:
    metric: auth_failures_by_ip
    window: 5 minutes
    threshold: 10
  by_username:
    metric: auth_failures_by_username
    window: 15 minutes
    threshold: 5
  by_ip_range:
    metric: auth_failures_by_cidr24
    window: 15 minutes
    threshold: 20

patterns:
  classic_brute_force:
    description: Many attempts against single account
    score: 70
  password_spraying:
    description: Few attempts each against many accounts
    detection: unique_usernames > 50 AND attempts_per_user < 3
    score: 85
  credential_stuffing:
    description: Known breached credentials
    detection: high_failure_rate AND diverse_usernames AND some_successes
    score: 90

risk_multipliers:
  security:
    base: 2.0
    with_successes: 2.5
    admin_targeted: 2.0
  ops: 0.8

mitre: T1110.001/.003/.004 (Brute Force variants)

7.4.2 Account takeover detection

Account Takeover Detectionyaml
name: account_takeover_detection
signals:
  pre_takeover:
    - auth_failures_spike
    - password_reset_requests
  takeover:
    - geographic_shift
    - device_change
    - session_overlap (impossible concurrency)
  post_takeover:
    - behavior_change
    - credential_change
    - security_setting_change (MFA disabled)
    - data_access_spike
    - permission_change (self-granted)

composite_scoring:
  weights:
    geographic_shift: 25
    device_change: 20
    behavior_change: 15
    credential_change: 30
    security_setting_change: 35
    data_access_spike: 20

  high_confidence_combinations:
    [geographic_shift, credential_change]: 90
    [device_change, security_setting_change]: 95
    [geographic_shift, data_access_spike]: 85

time_correlation:
  window: 24 hours
  sequence: anomalous_login → sensitive_action (within 4h)
  score_boost: 25

mitre: T1078 (Valid Accounts), T1098 (Account Manipulation)

7.5 API anomalies

7.5.1 API abuse / scraping detection

API Abuse Detectionyaml
name: api_abuse_detection
signals:
  volumetric:
    - request_rate
    - total_volume
  pattern:
    - sequential_ids (/items/1, /items/2...)
    - systematic_enumeration
  timing:
    - request_interval_cv (coefficient of variation)
    - burst_pattern
  session:
    - no_navigation_context
    - missing_referrer
    - missing_cookies

sequential_detection:
  ids = extract_ids(request_paths)
  gaps = diff(sort(ids))
  sequential_ratio = count(gaps == 1) / len(gaps)

  if sequential_ratio > 0.8:
    score += 40

timing_detection:
  human: mean_gap 2-30s, cv > 0.5
  bot: mean_gap < 1s OR constant, cv < 0.1

risk_multipliers:
  security:
    authenticated: 2.0
    targeting_user_data: 2.0
    targeting_pricing: 1.5
  ops:
    resource_impact: 1.5

mitre: T1213 (Data from Information Repositories)

7.5.2 IDOR detection

IDOR Detectionyaml
name: idor_detection
signals:
  primary:
    accessing_other_users_resources:
      condition: user.id != resource.owner_id AND status == 200
    systematic_id_probing:
      description: Sequential/random IDs not belonging to user
    403_to_200_pattern:
      description: Many 403s then successful access

detection:
  if user.id != resource.owner_id AND status == 200:
    if not has_permission(user, resource):
      flag_idor()

  recent_403s = count(status == 403, window=1h)
  recent_200s = count(status == 200, similar_endpoint)

  if recent_403s > 10 AND recent_200s > 0:
    score = 80  # Found bypass

risk_multipliers:
  security:
    base: 2.5
    successful_access: 3.0
    pii_resource: 2.0
  engineering:
    base: 2.0  # Indicates authz bug

7.6 Conformance

Implementations:

  • SHOULD implement at least three detection patterns
  • MUST document which patterns are implemented
  • MAY implement additional patterns beyond those specified
  • SHOULD include MITRE ATT&CK mappings for security-relevant patterns

Note

Continue to Section 8: Alert Framework for alert routing and notification.