ai_coding_shield/catalog/
threats.rs1use 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 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 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}