Detection rules › Panther

Panther rules: upwind

Upwind API Detection Passthrough

#
Status
Experimental
Severity
medium
Group by
id, severity
Log types
Upwind.Detections
Tags
Upwind, Passthrough, API, Initial Access, Exploit Public-Facing Application
Reference
docs.upwind.io
Source
github.com/panther-labs/panther-analysis

Re-raises Upwind API security detections in Panther. Covers broken authentication, authorization flaws, injection, mass assignment, token misuse, and sensitive data exposure patterns detected at the API layer.

MITRE ATT&CK coverage

TacticTechniques
Initial Access

Detection logic

from panther_upwind_helpers import (
    upwind_base_alert_context,
    upwind_format_initiators,
    upwind_format_mitre_attacks,
    upwind_is_known_severity,
    upwind_severity,
)

# Upwind API detections cover broken authentication/authorization, injection,
# mass assignment, token misuse, sensitive data exposure, and API abuse patterns.
API_KEYWORDS = ("api",)


def rule(event):
    category = event.get("category", "").lower()
    return upwind_is_known_severity(event) and any(kw in category for kw in API_KEYWORDS)


def title(event):
    return f"[Upwind API]: {event.get('title', '<NO TITLE>')}"


def severity(event):
    return upwind_severity(event)


def dedup(event):
    return f"{event.get('id', '<NO ID>')}_{event.get('severity', '<NO SEVERITY>')}"


def description(event):
    return event.get("description") or "DEFAULT"


def reference(event):
    return event.get("upwind_console_link") or "DEFAULT"


def alert_context(event):
    ctx = upwind_base_alert_context(event)
    ctx["initiators"] = upwind_format_initiators(event)
    ctx["mitre_attacks"] = upwind_format_mitre_attacks(event)
    return ctx

Rule specification

AnalysisType: rule
RuleID: Upwind.Detection.API.Passthrough
DisplayName: Upwind API Detection Passthrough
Description: >
  Re-raises Upwind API security detections in Panther. Covers broken authentication,
  authorization flaws, injection, mass assignment, token misuse, and sensitive data
  exposure patterns detected at the API layer.
Runbook: |
  1. Query Upwind.Detections for all API threat detections against resource.name in the 24 hours before and after this alert to establish the scope of API abuse
  2. Review triggers[].events[].initiator fields (name, arn, userName, accountId) and determine whether this initiating entity has a history of legitimate access to this service in the past 30 days
  3. Search for other alerts from the same triggers[].events[].initiator.arn or triggers[].events[].initiator.accountId in the past 7 days to identify credential misuse or account compromise
Reference: https://docs.upwind.io/restapi/v1/get-threat-detection
Enabled: true
Filename: upwind_api_detection_passthrough.py
Severity: Medium
Status: Experimental
LogTypes:
  - Upwind.Detections
DedupPeriodMinutes: 720
Threshold: 1
Reports:
  MITRE ATT&CK:
    - TA0001:T1190  # Initial Access: Exploit Public-Facing Application
Tags:
  - Upwind
  - Passthrough
  - API
  - Initial Access
  - Exploit Public-Facing Application

Stages and Predicates

Fires on Upwind.Detections events when the condition below holds.

Condition

  • category contains api

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Alert deduplication
repeat matches within 12h group into one alert

Indicators

These rows show field, operator, and value matches.

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
detection_idid
category
type
status
occurrence_count
title

Response runbook

1. Query Upwind.Detections for all API threat detections against resource.name in the 24 hours before and after this alert to establish the scope of API abuse

2. Review triggers[].events[].initiator fields (name, arn, userName, accountId) and determine whether this initiating entity has a history of legitimate access to this service in the past 30 days

3. Search for other alerts from the same triggers[].events[].initiator.arn or triggers[].events[].initiator.accountId in the past 7 days to identify credential misuse or account compromise

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "category": "API Threat",
  "description": "Broken object-level authorization detected on a REST API endpoint.",
  "first_seen_time": "2026-03-18T11:50:00Z",
  "id": "det-api-001",
  "last_seen_time": "2026-03-18T12:00:00Z",
  "mitre_attacks": [
    {
      "tactic_id": "TA0001",
      "tactic_name": "Initial Access",
      "technique_id": "T1190",
      "technique_name": "Exploit Public-Facing Application"
    }
  ],
  "occurrence_count": 7,
  "p_event_time": "2026-03-18T12:00:00Z",
  "p_log_type": "Upwind.Detections",
  "p_row_id": "ee1122ff3344ee1122ff3344ee1122ff",
  "p_schema_version": 0,
  "resource": {
    "cloud_account_id": "123456789012",
    "cloud_account_name": "prod-aws",
    "cloud_provider": "AWS",
    "name": "payments-api",
    "namespace": "production",
    "region": "us-east-1",
    "type": "Service",
    "upwind_asset_id": "asset-api-001"
  },
  "severity": "HIGH",
  "status": "open",
  "title": "BOLA - Unauthorized Object Access",
  "triggers": [
    {
      "events": [
        {
          "data": {
            "description": "GET /api/v1/users/999/orders returned 200"
          },
          "description": "Access to another user's resource",
          "initiator": {
            "accessKeyId": "AKIAIOSFODNN7EXAMPLE",
            "accountId": "123456789012",
            "arn": "arn:aws:iam::123456789012:user/external-user",
            "name": "external-user",
            "type": "IAMUser",
            "userName": "external-user"
          },
          "timestamp": "2026-03-18T11:55:00Z",
          "type": "api_request"
        }
      ],
      "policy_id": "pol-api-001",
      "policy_name": "Detect BOLA/IDOR Patterns"
    }
  ],
  "type": "api_threat",
  "upwind_console_link": "https://console.upwind.io/detections/det-api-001"
}

Upwind Network Detection Passthrough

#
Status
Experimental
Severity
medium
Group by
id, severity
Log types
Upwind.Detections
Tags
Upwind, Passthrough, Network, Discovery, Network Service Discovery
Reference
docs.upwind.io
Source
github.com/panther-labs/panther-analysis

Re-raises Upwind network security detections in Panther. Covers port scans, DoS activity, DNS anomalies, DNS-over-HTTPS abuse, and other anomalous network behaviors.

MITRE ATT&CK coverage

TacticTechniques
Discovery

Detection logic

from panther_upwind_helpers import (
    upwind_base_alert_context,
    upwind_format_mitre_attacks,
    upwind_is_known_severity,
    upwind_severity,
)

# Upwind network detections cover port scans, DoS activity, DNS anomalies,
# DNS-over-HTTPS abuse, and other anomalous network behaviors.
NETWORK_KEYWORDS = ("network",)

# Defer to higher-priority rules when their keywords also appear in the category
NETWORK_EXCLUSIONS = ("api", "vulnerab")


def rule(event):
    category = event.get("category", "").lower()
    return (
        upwind_is_known_severity(event)
        and any(kw in category for kw in NETWORK_KEYWORDS)
        and not any(ex in category for ex in NETWORK_EXCLUSIONS)
    )


def title(event):
    return f"[Upwind Network]: {event.get('title', '<NO TITLE>')}"


def severity(event):
    return upwind_severity(event)


def dedup(event):
    return f"{event.get('id', '<NO ID>')}_{event.get('severity', '<NO SEVERITY>')}"


def description(event):
    return event.get("description") or "DEFAULT"


def reference(event):
    return event.get("upwind_console_link") or "DEFAULT"


def alert_context(event):
    ctx = upwind_base_alert_context(event)
    ctx["mitre_attacks"] = upwind_format_mitre_attacks(event)
    return ctx

Rule specification

AnalysisType: rule
RuleID: Upwind.Detection.Network.Passthrough
DisplayName: Upwind Network Detection Passthrough
Description: >
  Re-raises Upwind network security detections in Panther. Covers port scans, DoS activity,
  DNS anomalies, DNS-over-HTTPS abuse, and other anomalous network behaviors.
Runbook: |
  1. Query Upwind.Detections for all network detections against resource.name in the 24 hours before this alert to determine if this is isolated or part of a sustained pattern
  2. Check whether resource.internet_exposure.ingress.active_communication is true and correlate with cloud network flow logs for the affected resource.region and resource.cloud_account_id to identify external actors involved
  3. Search for other HIGH or CRITICAL alerts from the same resource.cloud_account_id in the past 7 days to determine whether this network anomaly is associated with broader threat activity
Reference: https://docs.upwind.io/restapi/v1/get-threat-detection
Enabled: true
Filename: upwind_network_detection_passthrough.py
Severity: Medium
Status: Experimental
LogTypes:
  - Upwind.Detections
DedupPeriodMinutes: 720
Threshold: 1
Reports:
  MITRE ATT&CK:
    - TA0007:T1046  # Discovery: Network Service Discovery
Tags:
  - Upwind
  - Passthrough
  - Network
  - Discovery
  - Network Service Discovery

Stages and Predicates

Fires on Upwind.Detections events when all of the conditions below hold.

Condition

  • category contains network
  • category does not contain api
  • category does not contain vulnerab

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Alert deduplication
repeat matches within 12h group into one alert

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
categorycontainsapiexcludes:category field:"category" value:"api"
categorycontainsvulnerabexcludes:category field:"category" value:"vulnerab"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
categorycontains
  • network
field:"category" kind:contains value:"network"

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
detection_idid
category
type
status
occurrence_count
title

Response runbook

1. Query Upwind.Detections for all network detections against resource.name in the 24 hours before this alert to determine if this is isolated or part of a sustained pattern

2. Check whether resource.internet_exposure.ingress.active_communication is true and correlate with cloud network flow logs for the affected resource.region and resource.cloud_account_id to identify external actors involved

3. Search for other HIGH or CRITICAL alerts from the same resource.cloud_account_id in the past 7 days to determine whether this network anomaly is associated with broader threat activity

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "category": "Network Anomaly",
  "description": "Port scanning activity detected originating from a pod.",
  "first_seen_time": "2026-03-18T07:50:00Z",
  "id": "det-network-001",
  "last_seen_time": "2026-03-18T08:00:00Z",
  "mitre_attacks": [
    {
      "tactic_id": "TA0007",
      "tactic_name": "Discovery",
      "technique_id": "T1046",
      "technique_name": "Network Service Discovery"
    }
  ],
  "occurrence_count": 10,
  "p_event_time": "2026-03-18T08:00:00Z",
  "p_log_type": "Upwind.Detections",
  "p_row_id": "bb1122cc3344bb1122cc3344bb1122cc",
  "p_schema_version": 0,
  "resource": {
    "cloud_account_id": "123456789012",
    "cloud_account_name": "prod-aws",
    "cloud_provider": "AWS",
    "internet_exposure": {
      "ingress": {
        "active_communication": true
      }
    },
    "name": "scan-pod",
    "namespace": "default",
    "region": "us-east-1",
    "type": "Pod",
    "upwind_asset_id": "asset-net-001"
  },
  "severity": "HIGH",
  "status": "open",
  "title": "Internal Port Scan Detected",
  "triggers": [
    {
      "events": [],
      "policy_id": "pol-net-001",
      "policy_name": "Detect Internal Port Scanning"
    }
  ],
  "type": "network_threat",
  "upwind_console_link": "https://console.upwind.io/detections/det-network-001"
}

Upwind Posture Detection Passthrough

#
Status
Experimental
Severity
medium
Group by
id, severity
Log types
Upwind.Detections
Tags
Upwind, Passthrough, Posture, CSPM, Defense Evasion, Exfiltration, Impair Defenses
Reference
docs.upwind.io
Source
github.com/panther-labs/panther-analysis

Re-raises Upwind cloud posture and CSPM detections in Panther. Covers cloud misconfigurations, exposed secrets, configuration drift, and CSPM policy violations.

MITRE ATT&CK coverage

TacticTechniques
Defense Impairment
Collection

Detection logic

from panther_upwind_helpers import (
    upwind_base_alert_context,
    upwind_is_known_severity,
    upwind_severity,
    upwind_triggered_policies,
)

# Upwind posture detections cover cloud misconfigurations, exposed secrets,
# configuration drift, and CSPM policy violations.
# Note: "config" intentionally excluded — too broad and covered by "misconfigur".
POSTURE_KEYWORDS = ("posture", "cspm", "misconfigur")

# Defer to higher-priority rules when their keywords also appear in the category
POSTURE_EXCLUSIONS = ("api", "vulnerab", "network")


def rule(event):
    category = event.get("category", "").lower()
    return (
        upwind_is_known_severity(event)
        and any(kw in category for kw in POSTURE_KEYWORDS)
        and not any(ex in category for ex in POSTURE_EXCLUSIONS)
    )


def title(event):
    return f"[Upwind Posture]: {event.get('title', '<NO TITLE>')}"


def severity(event):
    return upwind_severity(event)


def dedup(event):
    return f"{event.get('id', '<NO ID>')}_{event.get('severity', '<NO SEVERITY>')}"


def description(event):
    return event.get("description") or "DEFAULT"


def reference(event):
    return event.get("upwind_console_link") or "DEFAULT"


def alert_context(event):
    ctx = upwind_base_alert_context(event)
    ctx["triggered_policies"] = upwind_triggered_policies(event)
    return ctx

Rule specification

AnalysisType: rule
RuleID: Upwind.Detection.Posture.Passthrough
DisplayName: Upwind Posture Detection Passthrough
Description: >
  Re-raises Upwind cloud posture and CSPM detections in Panther. Covers cloud
  misconfigurations, exposed secrets, configuration drift, and CSPM policy violations.
Runbook: |
  1. Query Upwind.Detections for all posture findings for the same resource.cloud_account_id and resource.type in the past 30 days to determine whether this is an isolated misconfiguration or a systemic issue across the account
  2. Review resource.risk_categories and triggers[].policy_name to assess the exposure scope and identify which compliance policies are violated
  3. Search for runtime or network threat detections against the same resource.name or resource.cloud_account_id in the past 7 days to determine whether the misconfiguration has already been exploited
Reference: https://docs.upwind.io/restapi/v1/get-threat-detection
Enabled: true
Filename: upwind_posture_detection_passthrough.py
Severity: Medium
Status: Experimental
LogTypes:
  - Upwind.Detections
DedupPeriodMinutes: 1440
Threshold: 1
Reports:
  MITRE ATT&CK:
    - TA0005:T1562  # Defense Evasion: Impair Defenses
    - TA0010:T1530  # Exfiltration: Data from Cloud Storage
Tags:
  - Upwind
  - Passthrough
  - Posture
  - CSPM
  - Defense Evasion
  - Exfiltration
  - Impair Defenses

Stages and Predicates

Fires on Upwind.Detections events when all of the conditions below hold.

Condition

  • any of:
    • category contains posture
    • category contains cspm
    • category contains misconfigur
  • category does not contain api
  • category does not contain vulnerab
  • category does not contain network

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Alert deduplication
repeat matches within 1d group into one alert

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
categorycontainsapiexcludes:category field:"category" value:"api"
categorycontainsnetworkexcludes:category field:"category" value:"network"
categorycontainsvulnerabexcludes:category field:"category" value:"vulnerab"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
categorycontains
  • cspm
  • misconfigur
  • posture
field:"category" kind:contains

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
detection_idid
category
type
status
occurrence_count
title

Response runbook

1. Query Upwind.Detections for all posture findings for the same resource.cloud_account_id and resource.type in the past 30 days to determine whether this is an isolated misconfiguration or a systemic issue across the account

2. Review resource.risk_categories and triggers[].policy_name to assess the exposure scope and identify which compliance policies are violated

3. Search for runtime or network threat detections against the same resource.name or resource.cloud_account_id in the past 7 days to determine whether the misconfiguration has already been exploited

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "category": "Misconfiguration",
  "description": "S3 bucket is publicly accessible and contains sensitive data.",
  "first_seen_time": "2026-03-18T15:50:00Z",
  "id": "det-posture-001",
  "last_seen_time": "2026-03-18T16:00:00Z",
  "mitre_attacks": [
    {
      "tactic_id": "TA0010",
      "tactic_name": "Exfiltration",
      "technique_id": "T1530",
      "technique_name": "Data from Cloud Storage"
    }
  ],
  "occurrence_count": 1,
  "p_event_time": "2026-03-18T16:00:00Z",
  "p_log_type": "Upwind.Detections",
  "p_row_id": "ee1122aa3344ee1122aa3344ee1122aa",
  "p_schema_version": 0,
  "resource": {
    "cloud_account_id": "123456789012",
    "cloud_account_name": "prod-aws",
    "cloud_provider": "AWS",
    "name": "my-public-bucket",
    "region": "us-east-1",
    "risk_categories": [
      "public_access",
      "sensitive_data"
    ],
    "type": "S3Bucket",
    "upwind_asset_id": "asset-posture-001"
  },
  "severity": "HIGH",
  "status": "open",
  "title": "Public S3 Bucket with Sensitive Data",
  "triggers": [
    {
      "events": [],
      "policy_id": "pol-posture-001",
      "policy_name": "No Public S3 Buckets"
    }
  ],
  "type": "cspm_finding",
  "upwind_console_link": "https://console.upwind.io/detections/det-posture-001"
}

Upwind Runtime Detection Passthrough

#
Status
Experimental
Severity
medium
Group by
id, severity
Log types
Upwind.Detections
Tags
Upwind, Passthrough, Runtime, Execution, Privilege Escalation, Command and Scripting Interpreter
Reference
docs.upwind.io
Source
github.com/panther-labs/panther-analysis

Re-raises Upwind runtime security detections in Panther. Covers process execution anomalies, syscall-based threats, container escapes, and other host/container behavioral threats.

MITRE ATT&CK coverage

TacticTechniques
Execution
Privilege Escalation

Detection logic

from panther_upwind_helpers import (
    upwind_base_alert_context,
    upwind_commands_observed,
    upwind_format_mitre_attacks,
    upwind_is_known_severity,
    upwind_severity,
)

# Upwind runtime detections cover process execution, syscall anomalies,
# container escapes, and other host/container behavioral threats.
RUNTIME_KEYWORDS = ("runtime", "execution", "process", "container")

# Defer to higher-priority rules when their keywords also appear in the category
RUNTIME_EXCLUSIONS = ("api", "vulnerab", "network")


def rule(event):
    category = event.get("category", "").lower()
    return (
        upwind_is_known_severity(event)
        and any(kw in category for kw in RUNTIME_KEYWORDS)
        and not any(ex in category for ex in RUNTIME_EXCLUSIONS)
    )


def title(event):
    return f"[Upwind Runtime]: {event.get('title', '<NO TITLE>')}"


def severity(event):
    return upwind_severity(event)


def dedup(event):
    return f"{event.get('id', '<NO ID>')}_{event.get('severity', '<NO SEVERITY>')}"


def description(event):
    return event.get("description") or "DEFAULT"


def reference(event):
    return event.get("upwind_console_link") or "DEFAULT"


def alert_context(event):
    ctx = upwind_base_alert_context(event)
    ctx["commands_observed"] = upwind_commands_observed(event)
    ctx["mitre_attacks"] = upwind_format_mitre_attacks(event)
    return ctx

Rule specification

AnalysisType: rule
RuleID: Upwind.Detection.Runtime.Passthrough
DisplayName: Upwind Runtime Detection Passthrough
Description: >
  Re-raises Upwind runtime security detections in Panther. Covers process execution anomalies,
  syscall-based threats, container escapes, and other host/container behavioral threats.
Runbook: |
  1. Query Upwind.Detections for all detections against the same resource.name and resource.namespace in the 24 hours before this alert to determine if this is an isolated event or part of a pattern
  2. Review the commands observed in triggers[].events[].data.command and the process user in triggers[].events[].data.user_name to assess whether the activity is consistent with normal workload behavior for this resource
  3. Search for other HIGH or CRITICAL severity alerts from the same resource.cloud_account_id or resource.cluster_id in the past 7 days to identify lateral movement or broader compromise
Reference: https://docs.upwind.io/restapi/v1/get-threat-detection
Enabled: true
Filename: upwind_runtime_detection_passthrough.py
Severity: Medium
Status: Experimental
LogTypes:
  - Upwind.Detections
DedupPeriodMinutes: 720
Threshold: 1
Reports:
  MITRE ATT&CK:
    - TA0002:T1059  # Execution: Command and Scripting Interpreter
    - TA0004:T1611  # Privilege Escalation: Escape to Host
Tags:
  - Upwind
  - Passthrough
  - Runtime
  - Execution
  - Privilege Escalation
  - Command and Scripting Interpreter

Stages and Predicates

Fires on Upwind.Detections events when all of the conditions below hold.

Condition

  • any of:
    • category contains runtime
    • category contains execution
    • category contains process
    • category contains container
  • category does not contain api
  • category does not contain vulnerab
  • category does not contain network

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Alert deduplication
repeat matches within 12h group into one alert

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
categorycontainsapiexcludes:category field:"category" value:"api"
categorycontainsnetworkexcludes:category field:"category" value:"network"
categorycontainsvulnerabexcludes:category field:"category" value:"vulnerab"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
categorycontains
  • container
  • execution
  • process
  • runtime
field:"category" kind:contains

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
detection_idid
category
type
status
occurrence_count
title

Response runbook

1. Query Upwind.Detections for all detections against the same resource.name and resource.namespace in the 24 hours before this alert to determine if this is an isolated event or part of a pattern

2. Review the commands observed in triggers[].events[].data.command and the process user in triggers[].events[].data.user_name to assess whether the activity is consistent with normal workload behavior for this resource

3. Search for other HIGH or CRITICAL severity alerts from the same resource.cloud_account_id or resource.cluster_id in the past 7 days to identify lateral movement or broader compromise

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "category": "Container Execution",
  "description": "Suspicious process execution detected inside a container.",
  "first_seen_time": "2026-03-18T09:55:00Z",
  "id": "det-runtime-001",
  "last_seen_time": "2026-03-18T10:00:00Z",
  "mitre_attacks": [
    {
      "tactic_id": "TA0002",
      "tactic_name": "Execution",
      "technique_id": "T1059",
      "technique_name": "Command and Scripting Interpreter"
    }
  ],
  "occurrence_count": 3,
  "p_event_time": "2026-03-18T10:00:00Z",
  "p_log_type": "Upwind.Detections",
  "p_row_id": "aabbcc112233aabbcc112233aabbcc11",
  "p_schema_version": 0,
  "resource": {
    "cloud_account_id": "123456789012",
    "cloud_account_name": "prod-aws",
    "cloud_provider": "AWS",
    "cluster_id": "cluster-abc123",
    "internet_exposure": {
      "ingress": {
        "active_communication": true
      }
    },
    "name": "api-server-pod",
    "namespace": "production",
    "region": "us-east-1",
    "type": "Pod",
    "upwind_asset_id": "asset-abc-001"
  },
  "severity": "CRITICAL",
  "status": "open",
  "title": "Suspicious Container Process Execution",
  "triggers": [
    {
      "events": [
        {
          "data": {
            "command": "/bin/bash -c whoami",
            "execution_count": 3,
            "user_name": "root"
          },
          "description": "bash executed inside container",
          "timestamp": "2026-03-18T09:55:00Z",
          "type": "process_execution"
        }
      ],
      "policy_id": "pol-001",
      "policy_name": "Detect Suspicious Shell Execution"
    }
  ],
  "type": "runtime_threat",
  "upwind_console_link": "https://console.upwind.io/detections/det-runtime-001"
}

Upwind Vulnerability Detection Passthrough

#
Status
Experimental
Severity
medium
Group by
id, severity
Log types
Upwind.Detections
Tags
Upwind, Passthrough, Vulnerability, Initial Access, Exploit Public-Facing Application
Reference
docs.upwind.io
Source
github.com/panther-labs/panther-analysis

Re-raises Upwind vulnerability detections in Panther. Covers exploitable CVEs identified in runtime containers, VMs, and serverless environments, prioritized by active exposure.

MITRE ATT&CK coverage

TacticTechniques
Initial Access

Detection logic

from panther_upwind_helpers import (
    upwind_base_alert_context,
    upwind_is_known_severity,
    upwind_severity,
    upwind_triggered_policies,
)

# Upwind vulnerability detections surface exploitable CVEs in runtime
# containers, VMs, and serverless environments, prioritized by actual exposure.
VULNERABILITY_KEYWORDS = ("vulnerab",)  # matches "vulnerability" and "vulnerabilities"

# Defer to higher-priority rules when their keywords also appear in the category
VULNERABILITY_EXCLUSIONS = ("api",)


def rule(event):
    category = event.get("category", "").lower()
    return (
        upwind_is_known_severity(event)
        and any(kw in category for kw in VULNERABILITY_KEYWORDS)
        and not any(ex in category for ex in VULNERABILITY_EXCLUSIONS)
    )


def title(event):
    return f"[Upwind Vulnerability]: {event.get('title', '<NO TITLE>')}"


def severity(event):
    return upwind_severity(event)


def dedup(event):
    return f"{event.get('id', '<NO ID>')}_{event.get('severity', '<NO SEVERITY>')}"


def description(event):
    return event.get("description") or "DEFAULT"


def reference(event):
    return event.get("upwind_console_link") or "DEFAULT"


def alert_context(event):
    ctx = upwind_base_alert_context(event)
    ctx["triggered_policies"] = upwind_triggered_policies(event)
    return ctx

Rule specification

AnalysisType: rule
RuleID: Upwind.Detection.Vulnerability.Passthrough
DisplayName: Upwind Vulnerability Detection Passthrough
Description: >
  Re-raises Upwind vulnerability detections in Panther. Covers exploitable CVEs identified
  in runtime containers, VMs, and serverless environments, prioritized by active exposure.
Runbook: |
  1. Check whether resource.internet_exposure.ingress.active_communication is true and review resource.risk_categories to assess the blast radius of the vulnerability on resource.name in resource.cloud_account_id
  2. Query Upwind.Detections for all vulnerability detections on the same resource.name in the past 90 days to evaluate patch cadence and determine if this finding is recurring
  3. Search for runtime or network threat detections against the same resource.name or resource.cloud_account_id in the past 30 days to determine whether the vulnerability has already been exploited
Reference: https://docs.upwind.io/restapi/v1/get-threat-detection
Enabled: true
Filename: upwind_vulnerability_detection_passthrough.py
Severity: Medium
Status: Experimental
LogTypes:
  - Upwind.Detections
DedupPeriodMinutes: 1440
Threshold: 1
Reports:
  MITRE ATT&CK:
    - TA0001:T1190  # Initial Access: Exploit Public-Facing Application
Tags:
  - Upwind
  - Passthrough
  - Vulnerability
  - Initial Access
  - Exploit Public-Facing Application

Stages and Predicates

Fires on Upwind.Detections events when all of the conditions below hold.

Condition

  • category contains vulnerab
  • category does not contain api

This rule also runs imperative logic the parser cannot express as a filter. The conditions above are the structured part it could extract.

Alert deduplication
repeat matches within 1d group into one alert

Exclusions

The rule actively suppresses these predicates.

FieldKindExcluded valuesSearch
categorycontainsapiexcludes:category field:"category" value:"api"

Indicators

These rows show field, operator, and value matches.

FieldKindValuesSearch
categorycontains
  • vulnerab
field:"category" kind:contains value:"vulnerab"

Output fields

Fields the rule emits when it matches, drawn from the rule's alert_context.

FieldSource
detection_idid
category
type
status
occurrence_count
title

Response runbook

1. Check whether resource.internet_exposure.ingress.active_communication is true and review resource.risk_categories to assess the blast radius of the vulnerability on resource.name in resource.cloud_account_id

2. Query Upwind.Detections for all vulnerability detections on the same resource.name in the past 90 days to evaluate patch cadence and determine if this finding is recurring

3. Search for runtime or network threat detections against the same resource.name or resource.cloud_account_id in the past 30 days to determine whether the vulnerability has already been exploited

Worked example

A sample event from the rule's unit tests that triggers a match.

Sample Test Event
{
  "category": "Vulnerability",
  "description": "Critical CVE-2024-1234 detected in a runtime container image.",
  "first_seen_time": "2026-03-18T13:50:00Z",
  "id": "det-vuln-001",
  "last_seen_time": "2026-03-18T14:00:00Z",
  "mitre_attacks": [
    {
      "tactic_id": "TA0001",
      "tactic_name": "Initial Access",
      "technique_id": "T1190",
      "technique_name": "Exploit Public-Facing Application"
    }
  ],
  "occurrence_count": 1,
  "p_event_time": "2026-03-18T14:00:00Z",
  "p_log_type": "Upwind.Detections",
  "p_row_id": "bb2233cc4455bb2233cc4455bb2233cc",
  "p_schema_version": 0,
  "resource": {
    "cloud_account_id": "123456789012",
    "cloud_account_name": "prod-aws",
    "cloud_provider": "AWS",
    "cluster_id": "cluster-abc123",
    "internet_exposure": {
      "ingress": {
        "active_communication": true
      }
    },
    "name": "frontend-pod",
    "namespace": "production",
    "region": "us-east-1",
    "risk_categories": [
      "internet_facing",
      "critical_workload"
    ],
    "type": "Pod",
    "upwind_asset_id": "asset-vuln-001"
  },
  "severity": "CRITICAL",
  "status": "open",
  "title": "Critical Vulnerability in Runtime Container",
  "triggers": [
    {
      "events": [],
      "policy_id": "pol-vuln-001",
      "policy_name": "Critical Runtime CVE Policy"
    }
  ],
  "type": "vulnerability",
  "upwind_console_link": "https://console.upwind.io/detections/det-vuln-001"
}