7. Detection patterns
| Status | Stable |
| Version | 2.0.0 |
| Last updated | 2026-01-31 |
| Authors | OpenALBA 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 bug7.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.