Homeโ€บ๐Ÿงช DQL Recipesโ€บModule 52 min read ยท 6/10

Security Queries

Hands-on

Security Queries

Dynatrace stores security data in two tables: security.events (vulnerabilities + attacks) and events (security-related Davis events). This module covers the DQL patterns for both.

Vulnerability Queries

Vulnerabilities are tracked via VULNERABILITY_STATE_REPORT_EVENT snapshots that refresh every 30-60 minutes:

// Open vulnerabilities โ€” latest snapshot per entity
fetch security.events, from:now()-30d
| filter dt.system.bucket == "default_securityevents_builtin"
    AND event.provider == "Dynatrace"
    AND event.type == "VULNERABILITY_STATE_REPORT_EVENT"
    AND event.level == "ENTITY"
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
| filter vulnerability.resolution.status == "OPEN"
| sort vulnerability.risk.score desc
| fields vulnerability.display_id, vulnerability.title, vulnerability.risk.level,
        vulnerability.risk.score, affected_entity.name, vulnerability.references.cve

โš ๏ธ OAuth scope storage:security.events:read is REQUIRED โ€” without it you get 403. This is separate from storage:events:read.

Vulnerability Summary

// Count by risk level
fetch security.events, from:now()-30d
| filter event.type == "VULNERABILITY_STATE_REPORT_EVENT" AND event.level == "ENTITY"
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
| filter vulnerability.resolution.status == "OPEN"
| summarize count=count(), by:{vulnerability.risk.level}
| sort count desc

Attack Events

// Recent attack attempts
fetch security.events, from:now()-7d
| filter event.type == "ATTACK_EVENT"
| fields timestamp, attack.type, attack.source.ip, affected_entity.name, attack.action
| sort timestamp desc
| limit 20

Vulnerability by Technology

// Which technologies have the most vulnerabilities?
fetch security.events, from:now()-30d
| filter event.type == "VULNERABILITY_STATE_REPORT_EVENT" AND event.level == "ENTITY"
| dedup {vulnerability.display_id, affected_entity.id}, sort:{timestamp desc}
| filter vulnerability.resolution.status == "OPEN"
| summarize count=count(), by:{affected_entity.name}
| sort count desc
| limit 10

Security Notification Architecture

Security alerting requires TWO parts โ€” an alerting profile alone does nothing:

  1. Alerting profile (builtin:appsec.notification-alerting-profile) โ€” filters WHICH vulnerabilities trigger alerts (risk level, event type)
  2. Notification integration (builtin:appsec.notification-integration) โ€” defines WHERE to send (email, webhook, Jira) and links to the alerting profile

๐Ÿ’ก After patching, vulnerabilities stay "OPEN" until the next state report cycle (30-60 min). Don't panic if vulns don't close immediately after upgrading.

โ–ถ Knowledge Check

Q: What OAuth scope is required to query security.events?

  • โŒ storage:events:read
  • โœ… storage:security.events:read
  • โŒ storage:logs:read

Q: How often do vulnerability state reports refresh?

  • โŒ Every minute
  • โŒ Every 5 minutes
  • โœ… Every 30-60 minutes