Skip to main content

ai_coding_shield/catalog/
threats.rs

1use serde::{Deserialize, Serialize};
2use crate::types::RiskLevel;
3
4#[derive(Debug, Clone, Serialize, Deserialize)]
5pub struct ThreatCategory {
6    pub id: String,
7    pub name: String,
8    pub mitre_id: Option<String>,
9    pub cwe_id: Option<String>,
10    pub rules: Vec<ThreatRule>,
11}
12
13#[derive(Debug, Clone, Serialize, Deserialize)]
14pub struct ThreatRule {
15    pub id: String,
16    pub pattern: String,
17    pub severity: RiskLevel,
18    pub description: String,
19    pub examples: Vec<String>,
20    pub remediation: String,
21    pub references: Vec<String>,
22    #[serde(default)]
23    pub false_positives: Vec<String>,
24    #[serde(default)]
25    pub context_escalators: Vec<ContextEscalator>,
26}
27
28#[derive(Debug, Clone, Serialize, Deserialize)]
29pub struct ContextEscalator {
30    pub condition: String,
31    pub escalate_by: u8,
32    pub reason: String,
33}
34
35impl ThreatRule {
36    /// Calculate risk score based on base severity and context
37    pub fn calculate_score(&self, has_auto_run: bool, has_network: bool) -> u8 {
38        let base_score = match self.severity {
39            RiskLevel::Low => 10,
40            RiskLevel::Medium => 30,
41            RiskLevel::High => 60,
42            RiskLevel::Critical => 90,
43        };
44
45        let mut score: u8 = base_score;
46
47        // Apply context escalators
48        for escalator in &self.context_escalators {
49            let should_escalate = match escalator.condition.as_str() {
50                "has_auto_run" => has_auto_run,
51                "has_network" => has_network,
52                _ => false,
53            };
54
55            if should_escalate {
56                score = score.saturating_add(escalator.escalate_by);
57            }
58        }
59
60        score.min(100)
61    }
62}