| 1 | from enum import Enum |
| 2 | from typing import Dict |
| 3 | from typing import List |
| 4 | from typing import Optional |
| 5 | |
| 6 | from fastapi import HTTPException |
| 7 | from pydantic import BaseModel |
| 8 | from pydantic import Field |
| 9 | from pydantic import field_validator |
| 10 | |
| 11 | |
| 12 | class AvailableMonitoringAlerts(str, Enum): |
| 13 | """ |
| 14 | The available monitoring alerts. |
| 15 | """ |
| 16 | |
| 17 | WAZUH_SYSLOG_LEVEL_ALERT = ( |
| 18 | "This alert monitors the SYSLOG_LEVEL field in the Wazuh logs. When the level is ALERT, " |
| 19 | "it triggers an alert that is created within CoPilot. Ensure that you have a pipeline " |
| 20 | "rule that sets the SYSLOG_LEVEL field to ALERT when the Wazuh rule level is greater than 11." |
| 21 | ) |
| 22 | SURICATA_ALERT_SEVERITY_1 = ( |
| 23 | "This alert monitors the Suricata logs. When an the alert_severity field is 1, it triggers " |
| 24 | "an alert that is created within CoPilot. Ensure that you have a pipeline rule that sets " |
| 25 | ) |
| 26 | OFFICE365_EXCHANGE_ONLINE = ( |
| 27 | "This alert monitors the Office365 Exchange events. When an alert is detected, it triggers an " |
| 28 | "alert that is created within CoPilot. Ensure that you have a pipeline rule that sets the " |
| 29 | "alert_severity field to 1 when the Office365 alert is detected." |
| 30 | ) |
| 31 | OFFICE365_THREAT_INTEL = ( |
| 32 | "This alert monitors the Office365 Threat Intelligence events. When an alert is detected, it triggers an " |
| 33 | "alert that is created within CoPilot. Ensure that you have a pipeline rule that sets the " |
| 34 | "alert_severity field to 1 when the Office365 alert is detected." |
| 35 | ) |
| 36 | CROWDSTRIKE_ALERT = ( |
| 37 | "This alert monitors the CrowdStrike events. When an alert is detected, it triggers an " |
| 38 | "alert that is created within CoPilot. Ensure that you have a pipeline rule that sets the " |
| 39 | "alert_severity field to 1 when the CrowdStrike alert is detected." |
| 40 | ) |
| 41 | # ! --- Fortinet / FortiGate alerts --- |
| 42 | FORTINET_SYSTEM = ( |
| 43 | "This alert monitors the Fortinet System events. When an alert is detected, it triggers an " |
| 44 | "alert that is created within CoPilot. Ensure that you have a pipeline rule that sets the " |
| 45 | "alert_severity field to 1 when the Fortinet alert is detected." |
| 46 | ) |
| 47 | FORTINET_UTM = ( |
| 48 | "This alert monitors the Fortinet UTM events. When an alert is detected, it triggers an " |
| 49 | "alert that is created within CoPilot. Ensure that you have a pipeline rule that sets the " |
| 50 | "alert_severity field to 1 when the Fortinet alert is detected." |
| 51 | ) |
| 52 | FORTINET_FORTIWEB_PATH_TRAVERSAL_VULNERABILITY_EXPLOITATION_ATTEMPT = ( |
| 53 | "Detects potential exploitation attempts targeting CVE-2025-64446, a critical path traversal vulnerability " |
| 54 | "affecting Fortinet FortiWeb Web Application Firewalls (WAF). " |
| 55 | "An adversary can abuse this flaw, which requires no authentication, to create new, unauthorized " |
| 56 | "administrative user accounts on the exposed device. " |
| 57 | "This provides the threat actor with full administrative control over the security appliance, allowing " |
| 58 | "them to bypass security policies, neutralize the WAF, and establish a persistent backdoor for further " |
| 59 | "network intrusions." |
| 60 | ) |
| 61 | FORTINET_WIDS_WIRELESS_VALID_CLIENT_MISASSOCIATION_DETECTED = ( |
| 62 | "Detects when FortiGate Wireless IDS identifies an incident where a legitimate wireless client associates " |
| 63 | "with a rogue or unauthorized access point (AP), a behavior known as valid client misassociation. " |
| 64 | "Attackers may set up malicious APs to impersonate trusted networks, tricking legitimate clients into " |
| 65 | "connecting. " |
| 66 | "This tactic is commonly used in evil twin attacks to intercept traffic, harvest credentials, or inject " |
| 67 | "malicious payloads. Identifying such associations is essential to safeguarding wireless network integrity " |
| 68 | "and preventing data leakage." |
| 69 | ) |
| 70 | FORTINET_WIDS_WIRELESS_MANAGEMENT_FLOODING_DETECTED = ( |
| 71 | "Detects when FortiGate Wireless IDS identifies abnormal surges of wireless management frames, such as " |
| 72 | "authentication, association, or probe requests, which may indicate a management frame flooding attack. " |
| 73 | "Adversaries use this technique to disrupt wireless network operations, exhaust access point resources, or " |
| 74 | "perform denial-of-service (DoS) attacks. " |
| 75 | "Continuous monitoring of management frame activity helps with the early identification and mitigation of " |
| 76 | "wireless network disruptions." |
| 77 | ) |
| 78 | FORTINET_WIDS_WIRELESS_EAPOL_PACKET_FLOODING_DETECTED = ( |
| 79 | "Detects a flood of EAPOL (Extensible Authentication Protocol over LAN) packets on the wireless network " |
| 80 | "identified by FortiGate Wireless IDS. " |
| 81 | "Such flooding can exhaust network resources, disrupt normal authentication processes, or exploit " |
| 82 | "weaknesses in WPA/WPA2 handshakes. " |
| 83 | "Monitoring for this behavior is crucial to maintaining secure and stable wireless authentication services " |
| 84 | "in enterprise environments." |
| 85 | ) |
| 86 | FORTINET_WIDS_ROGUE_ACCESS_POINT_DETECTED = ( |
| 87 | "Detects the rogue access point (AP) in the network as reported by FortiGate Wireless IDS. " |
| 88 | "Rogue APs are unauthorized wireless access points connected to a network, often used by attackers to " |
| 89 | "bypass security controls, capture sensitive data, or conduct man-in-the-middle attacks. " |
| 90 | "Detection of rogue APs is critical to maintaining wireless network integrity and preventing unauthorized " |
| 91 | "access." |
| 92 | ) |
| 93 | FORTINET_WIDS_WIRELESS_LONG_DURATION_ATTACK_DETECTED = ( |
| 94 | "Detects a long duration attack on the wireless network identified by FortiGate Wireless IDS. " |
| 95 | "These attacks often involve persistent connections to rogue access points or the use of compromised " |
| 96 | "clients to maintain unauthorized access over an extended period. " |
| 97 | "Such activity may be used by adversaries for sustained data exfiltration, network reconnaissance, or to " |
| 98 | "establish footholds in the environment. " |
| 99 | "Monitoring these patterns is crucial to detecting stealthy and persistent wireless threats." |
| 100 | ) |
| 101 | FORTINET_FIREWALL_VIRUS_DETECTED = ( |
| 102 | "Detects the virus in the network identified by FortiGate Firewall. " |
| 103 | "This may indicate the presence of malware or a malicious file attempting to execute or transfer within " |
| 104 | "the network. " |
| 105 | "Threat actors may use malware to gain access, maintain persistence, or exfiltrate data. Monitoring such " |
| 106 | "events can help identify compromised systems or prevent further infection spread." |
| 107 | ) |
| 108 | FORTINET_WIDS_WIRELESS_THREAT_DETECTED = ( |
| 109 | "Detects potential wireless-based security threats as identified by FortiGate Wireless IDS. " |
| 110 | "These threats may include spoofed access points, EAPOL flooding, deauthentication attacks, or other " |
| 111 | "suspicious wireless behaviors. " |
| 112 | "Monitoring such events is critical to protecting against wireless intrusion attempts, maintaining the " |
| 113 | "integrity of the Wi-Fi network, and preventing unauthorized access or denial-of-service conditions caused " |
| 114 | "by malicious actors." |
| 115 | ) |
| 116 | FORTINET_WIDS_WIRELESS_INVALID_MAC_OUI_DETECTED = ( |
| 117 | "Detects instances where a FortiGate Wireless IDS identifies a client with an invalid or unrecognized MAC " |
| 118 | "Organizationally Unique Identifier (OUI). " |
| 119 | "This may indicate the presence of unauthorized, rogue, or potentially malicious devices attempting to " |
| 120 | "connect to the wireless network. " |
| 121 | "Monitoring for invalid MAC OUIs helps strengthen network access controls and prevent unauthorized access." |
| 122 | ) |
| 123 | FORTINET_WIDS_WIRELESS_ASLEAP_ATTACK_DETECTED = ( |
| 124 | "Detects the presence of an Asleap attack in a wireless network identified by FortiGate Wireless IDS. " |
| 125 | "Asleap is a tool used to exploit weak authentication in LEAP (Lightweight Extensible Authentication " |
| 126 | "Protocol), potentially allowing attackers to capture and crack wireless credentials. " |
| 127 | "Monitoring for this activity helps identify unauthorized attempts to compromise wireless network security " |
| 128 | "and protect sensitive credentials." |
| 129 | ) |
| 130 | FORTINET_IPS_MALICIOUS_URL_DETECTED = ( |
| 131 | "Detects when FortiGate Intrusion Prevention System (IPS) identifies access to a known malicious URL. " |
| 132 | "This activity may indicate attempts to connect to command and control infrastructure, deliver malware, or " |
| 133 | "exfiltrate data. " |
| 134 | "Monitoring these detections helps identify potential threats, prevent compromise, and maintain network " |
| 135 | "security." |
| 136 | ) |
| 137 | FORTINET_IPS_BOTNET_ACTIVITY_DETECTED = ( |
| 138 | "Detects botnet-related activity identified by FortiGate Intrusion Prevention System (IPS). This may " |
| 139 | "indicate that a host within the network is communicating with known botnet command and control servers or " |
| 140 | "exhibiting behavior consistent with botnet infections. Monitoring these events helps identify compromised " |
| 141 | "systems, prevent data exfiltration, and mitigate the spread of malicious activity within the environment." |
| 142 | ) |
| 143 | FORTINET_ADMIN_USER_CREATED_FROM_PUBLIC_IP = ( |
| 144 | "Detects the creation of a new administrator user account on a Fortinet FortiGate device originating from " |
| 145 | "a public IP address. " |
| 146 | "An adversary who gains access to the management interface may create unauthorized admin accounts to " |
| 147 | "establish persistent, privileged control over the firewall. " |
| 148 | "By creating these accounts from external or atypical network locations, attackers can maintain long-term " |
| 149 | "access, modify security policies, exfiltrate sensitive data, or prepare the environment for additional " |
| 150 | "malicious activity." |
| 151 | ) |
| 152 | FORTINET_SUSPICIOUS_CONFIG_FILE_ACCESS_FROM_EXTERNAL_NETWORK = ( |
| 153 | "Detects attempts to download a FortiGate configuration file from an external or publicly accessible " |
| 154 | "network source. " |
| 155 | "Adversaries may abuse this behavior to obtain sensitive configuration data, including administrative " |
| 156 | "credentials, network topology details, VPN settings, or firewall policies. " |
| 157 | "Access to this information can enable further compromise through targeted lateral movement, privilege " |
| 158 | "escalation, or tailored exploitation of exposed services." |
| 159 | ) |
| 160 | FORTINET_WIDS_WIRELESS_WEAK_ENCRYPTION_DETECTED = ( |
| 161 | "Detects wireless access points using weak or deprecated encryption protocols, as reported by FortiGate " |
| 162 | "Wireless IDS. " |
| 163 | "Risky encryption methods, such as WEP or misconfigured WPA settings, may allow adversaries to eavesdrop " |
| 164 | "on network traffic or perform cryptographic attacks to gain unauthorized access. " |
| 165 | "Identifying and remediating such vulnerabilities is essential to ensure wireless network confidentiality " |
| 166 | "and compliance with security best practices." |
| 167 | ) |
| 168 | FORTINET_SUSPICIOUS_SUPER_ADMIN_LOGIN_DETECTED = ( |
| 169 | "Detects a super admin login attempt to a FortiGate firewall originating from a suspicious or public IP " |
| 170 | "address. " |
| 171 | "This may indicate an attempt to exploit CVE-2025-24472 which allows unauthenticated attackers to gain " |
| 172 | "super admin privileges on vulnerable FortiOS devices (<7.0.16) with exposed management interfaces." |
| 173 | ) |
| 174 | # ! --- Palo Alto Networks (PANW) alerts --- |
| 175 | PALOALTO_ALERT = ( |
| 176 | "This alert monitors the PaloAlto events. When an alert is detected, it triggers an " |
| 177 | "alert that is created within CoPilot. Ensure that you have a pipeline rule that sets the " |
| 178 | "alert_severity field to 1 when the PaloAlto alert is detected." |
| 179 | ) |
| 180 | PALOALTO_FIREWALL_TRAFFIC_TO_PHISHING_URL_ALLOWED = ( |
| 181 | "Detects when the Palo Alto Networks firewall does not block traffic to a URL known to be used in phishing " |
| 182 | "attacks. " |
| 183 | "An adversary can abuse this by directing victims to the phishing site, potentially stealing credentials, " |
| 184 | "deploying malware, or conducting other malicious activities." |
| 185 | ) |
| 186 | PALOALTO_FIREWALL_TRAFFIC_TO_MALICIOUS_URL_ALLOWED = ( |
| 187 | "Detects when the Palo Alto Networks firewall does not block traffic to a URL associated with malware " |
| 188 | "distribution or operation. " |
| 189 | "This typically indicates a lapse in the firewall's threat intelligence or a misconfiguration. " |
| 190 | "An adversary can abuse this by using the unblocked URL to download malware onto a target system, establish " |
| 191 | "a command and control channel, or exfiltrate data." |
| 192 | ) |
| 193 | PALOALTO_FIREWALL_VIRUS_ALLOWED = ( |
| 194 | "Detects active network communication associated with known malware that is being allowed by the Palo Alto " |
| 195 | "Networks firewall. " |
| 196 | "This may indicate an ongoing security threat, where malicious traffic is bypassing firewall protections, " |
| 197 | "potentially leading to system compromise, data exfiltration, or further infiltration within the network." |
| 198 | ) |
| 199 | PALOALTO_FIREWALL_TOR_TRAFFIC_ALLOWED = ( |
| 200 | "Detects allowed network traffic to the TOR network. Adversaries can use TOR to anonymize their network " |
| 201 | "activity, bypass security controls, and evade detection while conducting malicious operations. " |
| 202 | "This could lead to unauthorized access, data exfiltration, and compliance violations if deemed malicious." |
| 203 | ) |
| 204 | PALOALTO_FIREWALL_MEDIUM_SEVERITY_CORRELATION_EVENT_DETECTED = ( |
| 205 | "Detects medium severity correlation events generated by Palo Alto Networks firewall's automated correlation " |
| 206 | "engine. " |
| 207 | "The correlation engine connects isolated network events and looks for patterns that indicate a more " |
| 208 | "significant event. " |
| 209 | "This helps identify suspicious traffic patterns and network anomalies which, when correlated, indicate with " |
| 210 | "a high probability that a host on the network has been compromised." |
| 211 | ) |
| 212 | # ! --- SentinelOne alerts --- |
| 213 | SENTINELONE_NEW_ACTIVE_THREAT_MALICIOUS_DETECTED = "Threat with confidence level malicious detected" |
| 214 | SENTINELONE_NEW_ACTIVE_THREAT_SUSPICIOUS_DETECTED = "Threat with confidence level suspicious detected" |
| 215 | SENTINELONE_NEW_MITIGATION_KILL_PERFORMED_SUCCESSFULLY = "Kill performed successfully" |
| 216 | SENTINELONE_NEW_MITIGATION_QUARANTINE_PERFORMED_SUCCESSFULLY = "Quarantine performed successfully" |
| 217 | SENTINELONE_NEW_EXCLUSION_WAS_ADDED_OR_MODIFIED_BY_USER = "Exclusion was added/modified by user" |
| 218 | SENTINELONE_NEW_PATH_EXCLUSION_ADDED = "Path Exclusion added" |
| 219 | SENTINELONE_ANALYST_VERDICT_CHANGED_TO_TRUE_POSITIVE = 'A management user changed the analyst verdict to "True Positive".' |
| 220 | SENTINELONE_ANALYST_VERDICT_CHANGED_TO_FALSE_POSITIVE = 'A management user changed the analyst verdict to "False Positive".' |
| 221 | # ! --- Mimecast alerts --- |
| 222 | MIMECAST_COMPROMISED_SITE_URL_ACCESSED = ( |
| 223 | "Detects user clicks on compromised websites classified by Mimecast, which were delivered via email. " |
| 224 | "Adversaries can exploit these links to direct users to malicious sites hosting malware, phishing pages, or spam content." |
| 225 | ) |
| 226 | MIMECAST_EXECUTABLE_FILE_ATTACHMENT_DELIVERED = ( |
| 227 | "Detects emails containing executable file attachments that have been delivered to a user's mailbox, as identified by Mimecast. " |
| 228 | "An adversary can abuse this delivery method to distribute malicious payloads, including malware, ransomware, or other executables designed to compromise the recipient's system." |
| 229 | ) |
| 230 | MIMECAST_MALICIOUS_EMAIL_ATTACHMENT_DELIVERED = ( |
| 231 | "Detects emails containing malicious attachments identified by Mimecast that have been delivered to a user's mailbox. " |
| 232 | "Attackers commonly use spearphishing emails with malicious attachments to compromise systems by tricking recipients into opening them." |
| 233 | ) |
| 234 | MIMECAST_MALICIOUS_EMAIL_LINK_ACCESSED = ( |
| 235 | "Detects instances where users click on malicious URLs embedded in emails. " |
| 236 | "These URLs may redirect to phishing sites, initiate malware downloads, or enable advanced threats, posing risks to user and organizational security." |
| 237 | ) |
| 238 | MIMECAST_P2P_FILE_SHARING_URL_ACCESSED = ( |
| 239 | "Detects a user clicking on a peer-to-peer file sharing URL, as classified by Mimecast, that was delivered via email. " |
| 240 | "Adversaries can abuse P2P file-sharing platforms to distribute malicious files, such as malware, ransomware, or unauthorized software, by embedding these links in phishing emails." |
| 241 | ) |
| 242 | MIMECAST_ANONYMIZER_URL_ACCESSED = ( |
| 243 | "Detects user clicks on anonymizer URLs classified by Mimecast that arrived in an email. " |
| 244 | "An adversary can abuse anonymizer services to mask their identity and hide the origin of malicious traffic, making it harder to trace their activities." |
| 245 | ) |
| 246 | MIMECAST_IMPERSONATION_EMAIL_DELIVERED = ( |
| 247 | "Detects unblocked email messages flagged by Mimecast as potential impersonation attempts. " |
| 248 | "These emails are strong indicators of Business Email Compromise (BEC), a sophisticated phishing tactic in which attackers impersonate trusted entities to deceive recipients." |
| 249 | ) |
| 250 | MIMECAST_MALICIOUS_OUTBOUND_EMAIL = ( |
| 251 | "Detects outbound emails identified by Mimecast as malicious, including those containing phishing links, malware-laden attachments, or other suspicious content. " |
| 252 | "Monitoring these events is crucial in identifying potential account compromises or unauthorized activities aimed at distributing threats to external recipients." |
| 253 | ) |
| 254 | MIMECAST_MALICIOUS_RTF_ATTACHMENT_DELIVERED = ( |
| 255 | "Detects emails containing malicious rtf file attachments identified by Mimecast that have been delivered to a user's mailbox. " |
| 256 | "Adversaries can abuse malicious RTF files to exploit vulnerabilities in applications that process these files, potentially executing arbitrary code or delivering malware." |
| 257 | ) |
| 258 | MIMECAST_PHISHING_EMAIL_DELIVERED = ( |
| 259 | "Detects unblocked email messages flagged as phishing by Mimecast, indicating their successful delivery to recipients' mailboxes. " |
| 260 | "Such emails may contain malicious attachments, URLs, or deceptive content." |
| 261 | ) |
| 262 | MIMECAST_SOURCE_CODE_FILE_IN_EMAIL_ATTACHMENT = ( |
| 263 | "Detects the presence of source code files in email attachments by analyzing Mimecast email logs. " |
| 264 | "This activity may indicate potential insider threats, as internal users could be attempting to exfiltrate sensitive or proprietary information." |
| 265 | ) |
| 266 | MIMECAST_URL_WITH_DANGEROUS_FILE_TYPE_ACCESSED = ( |
| 267 | "Detects user clicks on URLs containing dangerous file types, as classified by Mimecast, that were delivered via email. " |
| 268 | "Adversaries often use emails with embedded URLs linking to files with extensions commonly associated with malware, such as .exe, .bat, .js, or .msi." |
| 269 | ) |
| 270 | |
| 271 | |
| 272 | class AvailableMonitoringAlertsResponse(BaseModel): |
| 273 | """ |
| 274 | The available monitoring alerts response. |
| 275 | """ |
| 276 | |
| 277 | success: bool |
| 278 | message: str |
| 279 | available_monitoring_alerts: List[Dict[str, str]] |
| 280 | |
| 281 | |
| 282 | class ProvisionMonitoringAlertRequest(BaseModel): |
| 283 | search_within_last: int = Field( |
| 284 | ..., |
| 285 | description="The time in seconds to search within for the alert.", |
| 286 | ) |
| 287 | execute_every: int = Field( |
| 288 | ..., |
| 289 | description="The time in seconds to execute the alert search.", |
| 290 | ) |
| 291 | alert_name: str = Field( |
| 292 | "WAZUH_SYSLOG_LEVEL_ALERT", |
| 293 | description="The name of the alert to provision.", |
| 294 | ) |
| 295 | |
| 296 | @field_validator("alert_name") |
| 297 | @classmethod |
| 298 | def validate_alert_name(cls, v): |
| 299 | v = v.replace(" ", "_").upper() |
| 300 | if v not in AvailableMonitoringAlerts.__members__: |
| 301 | raise HTTPException( |
| 302 | status_code=400, |
| 303 | detail=f"Invalid alert name: {v}. Must be one of: {', '.join(AvailableMonitoringAlerts.__members__)}", |
| 304 | ) |
| 305 | return v |
| 306 | |
| 307 | @field_validator("search_within_last", "execute_every") |
| 308 | @classmethod |
| 309 | def validate_non_zero(cls, v): |
| 310 | if v == 0: |
| 311 | raise HTTPException( |
| 312 | status_code=400, |
| 313 | detail=f"Invalid value: {v}. Must be greater than 0.", |
| 314 | ) |
| 315 | return v |
| 316 | |
| 317 | |
| 318 | class ProvisionWazuhMonitoringAlertResponse(BaseModel): |
| 319 | success: bool |
| 320 | message: str |
| 321 | |
| 322 | |
| 323 | ########## ! GRAYLOG WHITELIST URL CREATION ! ########## |
| 324 | class GraylogUrlWhitelistEntryConfig(BaseModel): |
| 325 | id: str = Field( |
| 326 | ..., |
| 327 | description="The ID of the URL whitelist entry.", |
| 328 | ) |
| 329 | title: str = Field( |
| 330 | ..., |
| 331 | description="The title of the URL whitelist entry.", |
| 332 | ) |
| 333 | type: str = Field( |
| 334 | "literal", |
| 335 | description="The type of the URL whitelist entry.", |
| 336 | ) |
| 337 | value: str = Field( |
| 338 | ..., |
| 339 | description="The value of the URL whitelist entry.", |
| 340 | ) |
| 341 | |
| 342 | |
| 343 | class GraylogUrlWhitelistEntries(BaseModel): |
| 344 | entries: List[GraylogUrlWhitelistEntryConfig] |
| 345 | disabled: bool |
| 346 | |
| 347 | |
| 348 | ########## ! GRAYLOG WEBHOOK CREATION ! ########## |
| 349 | class GraylogAlertWebhookConfig(BaseModel): |
| 350 | url: str = Field( |
| 351 | ..., |
| 352 | description="The URL to use for the webhook.", |
| 353 | ) |
| 354 | api_key: Optional[str] = Field( |
| 355 | None, |
| 356 | description="The API key to use for the webhook.", |
| 357 | ) |
| 358 | api_secret: Optional[str] = Field( |
| 359 | None, |
| 360 | description="The API secret to use for the webhook.", |
| 361 | ) |
| 362 | basic_auth: Optional[str] = Field( |
| 363 | None, |
| 364 | description="The basic auth to use for the webhook.", |
| 365 | ) |
| 366 | type: str = Field( |
| 367 | ..., |
| 368 | description="The type of the webhook.", |
| 369 | ) |
| 370 | |
| 371 | |
| 372 | class GraylogAlertWebhookNotificationModel(BaseModel): |
| 373 | title: str |
| 374 | description: str |
| 375 | config: GraylogAlertWebhookConfig |
| 376 | |
| 377 | |
| 378 | ########## ! GRAYLOG EVENT CREATION ! ########## |
| 379 | class GraylogAlertProvisionProvider(BaseModel): |
| 380 | template: str |
| 381 | type: str = Field(..., alias="type") |
| 382 | require_values: bool |
| 383 | |
| 384 | |
| 385 | class GraylogAlertProvisionFieldSpecItem(BaseModel): |
| 386 | data_type: str |
| 387 | providers: List[GraylogAlertProvisionProvider] |
| 388 | |
| 389 | |
| 390 | class GraylogAlertProvisionConfig(BaseModel): |
| 391 | query: str |
| 392 | query_parameters: List |
| 393 | streams: List |
| 394 | search_within_ms: int |
| 395 | execute_every_ms: int |
| 396 | group_by: List |
| 397 | series: List |
| 398 | conditions: Dict |
| 399 | type: str = Field(..., alias="type") |
| 400 | event_limit: int = Field(1000, description="The event limit for the config") |
| 401 | |
| 402 | |
| 403 | class GraylogAlertProvisionNotificationSettings(BaseModel): |
| 404 | grace_period_ms: int |
| 405 | backlog_size: Optional[int] = None |
| 406 | |
| 407 | |
| 408 | class GraylogAlertProvisionNotification(BaseModel): |
| 409 | notification_id: str |
| 410 | |
| 411 | |
| 412 | class GraylogAlertProvisionModel(BaseModel): |
| 413 | title: str |
| 414 | description: str |
| 415 | priority: int |
| 416 | config: GraylogAlertProvisionConfig |
| 417 | field_spec: Dict[str, GraylogAlertProvisionFieldSpecItem] |
| 418 | key_spec: List |
| 419 | notification_settings: GraylogAlertProvisionNotificationSettings |
| 420 | notifications: Optional[List[GraylogAlertProvisionNotification]] = [] |
| 421 | alert: bool |
| 422 | |
| 423 | |
| 424 | class AlertPriority(Enum): |
| 425 | LOW = 1 |
| 426 | NORMAL = 2 |
| 427 | HIGH = 3 |
| 428 | |
| 429 | |
| 430 | class CustomFields(BaseModel): |
| 431 | name: str |
| 432 | value: str |
| 433 | |
| 434 | @field_validator("name") |
| 435 | @classmethod |
| 436 | def replace_spaces_with_underscores(cls, v): |
| 437 | return v.replace(" ", "_") |
| 438 | |
| 439 | |
| 440 | class CustomMonitoringAlertProvisionModel(BaseModel): |
| 441 | alert_name: str = Field( |
| 442 | ..., |
| 443 | description="The name of the alert to provision.", |
| 444 | examples=["WAZUH_SYSLOG_LEVEL_ALERT"], |
| 445 | ) |
| 446 | alert_description: str = Field( |
| 447 | ..., |
| 448 | description=( |
| 449 | "The description of the alert to provision. This alert monitors the " |
| 450 | "SYSLOG_LEVEL field in the Wazuh logs. When the level is ALERT, it " |
| 451 | "triggers an alert that is created within DFIR-IRIS. Ensure that you " |
| 452 | "have a pipeline rule that sets the SYSLOG_LEVEL field to ALERT when " |
| 453 | "the Wazuh rule level is greater than 11." |
| 454 | ), |
| 455 | examples=[ |
| 456 | ( |
| 457 | "This alert monitors the SYSLOG_LEVEL field in the Wazuh logs. When " |
| 458 | "the level is ALERT, it triggers an alert that is created within " |
| 459 | "DFIR-IRIS. Ensure that you have a pipeline rule that sets the " |
| 460 | "SYSLOG_LEVEL field to ALERT when the Wazuh rule level is greater than 11." |
| 461 | ), |
| 462 | ], |
| 463 | ) |
| 464 | alert_priority: AlertPriority = Field( |
| 465 | ..., |
| 466 | description="The priority of the alert to provision.", |
| 467 | examples=[2], |
| 468 | ) |
| 469 | search_query: str = Field( |
| 470 | ..., |
| 471 | description="The search query to use for the alert.", |
| 472 | examples=["syslog_type:wazuh AND syslog_level:alert"], |
| 473 | ) |
| 474 | streams: Optional[List[str]] = Field( |
| 475 | [], |
| 476 | description="The streams to use for the alert.", |
| 477 | examples=[["5f3e4c3b3f37b70001f3d7b3"]], |
| 478 | ) |
| 479 | custom_fields: Optional[List[CustomFields]] = Field( |
| 480 | None, |
| 481 | description="The custom fields to use for the alert.", |
| 482 | examples=[[{"name": "source", "value": "Wazuh"}]], |
| 483 | ) |
| 484 | search_within_ms: int = Field( |
| 485 | ..., |
| 486 | description="The time in milliseconds to search within for the alert.", |
| 487 | examples=[300000], |
| 488 | ) |
| 489 | execute_every_ms: int = Field( |
| 490 | ..., |
| 491 | description="The time in milliseconds to execute the alert search.", |
| 492 | examples=[300000], |
| 493 | ) |
| 494 | |
| 495 | # ! I think I can remove the requirement for the CUSTOMER_CODE field. |
| 496 | # ! The new incident management doesnt require the CUSTOMER_CODE to be preset but |
| 497 | # ! rather looks for valid CustomerCodeKeys(Enum) # ! |
| 498 | # @root_validator |
| 499 | # def check_customer_code(cls, values): |
| 500 | # custom_fields = values.get("custom_fields") |
| 501 | # if custom_fields is None: |
| 502 | # raise HTTPException( |
| 503 | # status_code=400, |
| 504 | # detail="At least one custom field with name CUSTOMER_CODE is required", |
| 505 | # ) |
| 506 | # if not any(field.name == "CUSTOMER_CODE" for field in custom_fields): |
| 507 | # raise HTTPException( |
| 508 | # status_code=400, |
| 509 | # detail="At least one custom field with name CUSTOMER_CODE is required", |
| 510 | # ) |
| 511 | # return values |