princemaxp commited on
Commit
734dc8c
·
verified ·
1 Parent(s): a09e64c

Update scoring_engine.py

Browse files
Files changed (1) hide show
  1. scoring_engine.py +68 -101
scoring_engine.py CHANGED
@@ -1,115 +1,82 @@
1
  # scoring_engine.py
2
 
3
  def compute_final_score(
4
- header_score,
5
- body_score,
6
- url_score,
7
- attachment_score,
8
- header_findings,
9
- body_findings,
10
- url_findings,
11
- attachment_findings,
12
- auth_results
 
 
 
13
  ):
14
  """
15
- Returns:
16
- final_score (0–100),
17
- verdict (string),
18
- reasoning (list of strings)
19
  """
20
 
21
  reasoning = []
22
- score = 0
23
 
24
- hf = " ".join(header_findings).lower()
25
- bf = " ".join(body_findings).lower()
26
- uf = " ".join(url_findings).lower()
27
- af = " ".join(attachment_findings).lower()
28
- auth = str(auth_results).lower()
29
-
30
- # =========================
31
- # 🚨 CRITICAL CORRELATIONS
32
- # =========================
33
-
34
- # 1️⃣ Malware attachment
35
- if attachment_score >= 40:
36
- score = max(score, 90)
37
- reasoning.append("High-risk attachment detected")
38
-
39
- # 2️⃣ Brand spoof + auth failure
40
- if "brand" in hf and ("spf fail" in auth or "dkim fail" in auth):
41
- score = max(score, 85)
42
- reasoning.append("Brand spoofing combined with authentication failure")
43
-
44
- # 3️⃣ URL phishing + credential language
45
- if url_score >= 30 and any(k in bf for k in ["password", "login", "verify"]):
46
- score = max(score, 80)
47
- reasoning.append("Credential harvesting attempt detected")
48
-
49
- # 4️⃣ BEC pattern
50
- if (
51
- "reply-to domain mismatch" in hf
52
- and url_score == 0
53
- and attachment_score == 0
54
- ):
55
- score = max(score, 75)
56
- reasoning.append("Business Email Compromise pattern detected")
57
-
58
- # =========================
59
- # ⚠️ MEDIUM RISK CORRELATIONS
60
- # =========================
61
-
62
- # 5️⃣ New domain + urgency
63
- if "very new" in hf and "urgent" in bf:
64
- score = max(score, 65)
65
- reasoning.append("New sender domain combined with urgency")
66
-
67
- # 6️⃣ Auth soft fail + suspicious wording
68
- if any(x in auth for x in ["softfail", "neutral"]) and body_score >= 30:
69
- score = max(score, 60)
70
- reasoning.append("Authentication weakness combined with suspicious content")
71
-
72
- # =========================
73
- # 🟢 LOW RISK / BENIGN
74
- # =========================
75
-
76
- if (
77
- score == 0
78
- and header_score < 10
79
- and body_score < 20
80
- and url_score == 0
81
- and attachment_score == 0
82
- ):
83
- score = 5
84
- reasoning.append("No meaningful threat signals detected")
85
-
86
- # =========================
87
- # 🎚 FALLBACK SCORE
88
- # =========================
89
-
90
- if score == 0:
91
- score = min(
92
- int(
93
- header_score * 0.8
94
- + body_score * 0.9
95
- + url_score * 1.1
96
- + attachment_score * 1.2
97
- ),
98
- 100,
99
- )
100
- reasoning.append("Score derived from weighted indicators")
101
-
102
- # =========================
103
- # 🧾 VERDICT
104
- # =========================
105
-
106
- if score >= 80:
107
  verdict = "🚨 Malicious"
108
- elif score >= 60:
109
  verdict = "⚠️ Suspicious"
110
- elif score >= 30:
111
- verdict = "📩 Spam"
112
  else:
113
  verdict = "✅ Safe"
114
 
115
- return score, verdict, reasoning
 
1
  # scoring_engine.py
2
 
3
  def compute_final_score(
4
+ *,
5
+ header_score: int,
6
+ body_score: int,
7
+ url_score: int,
8
+ attachment_score: int,
9
+ behavior_score: int,
10
+ header_findings: list,
11
+ body_findings: list,
12
+ url_findings: list,
13
+ attachment_findings: list,
14
+ behavior_findings: list,
15
+ auth_results: dict,
16
  ):
17
  """
18
+ Correlation-based scoring engine (Phase 4.2)
19
+ Returns: final_score, verdict, reasoning[]
 
 
20
  """
21
 
22
  reasoning = []
 
23
 
24
+ # -------------------------
25
+ # BASE SCORE
26
+ # -------------------------
27
+ final_score = (
28
+ header_score * 0.20 +
29
+ body_score * 0.25 +
30
+ behavior_score * 0.30 + # 🔥 highest weight
31
+ url_score * 0.15 +
32
+ attachment_score * 0.10
33
+ )
34
+
35
+ reasoning.append(f"Header score contribution: {header_score * 0.20:.1f}")
36
+ reasoning.append(f"Body score contribution: {body_score * 0.25:.1f}")
37
+ reasoning.append(f"Behavior score contribution: {behavior_score * 0.30:.1f}")
38
+ reasoning.append(f"URL score contribution: {url_score * 0.15:.1f}")
39
+ reasoning.append(f"Attachment score contribution: {attachment_score * 0.10:.1f}")
40
+
41
+ # -------------------------
42
+ # AUTH OVERRIDES
43
+ # -------------------------
44
+ if auth_results.get("dmarc") == "fail":
45
+ final_score += 10
46
+ reasoning.append("DMARC failed +10 risk")
47
+
48
+ if auth_results.get("spf") == "fail":
49
+ final_score += 5
50
+ reasoning.append("SPF failed → +5 risk")
51
+
52
+ # -------------------------
53
+ # CORRELATION RULES
54
+ # -------------------------
55
+ if behavior_score >= 40 and header_score >= 20:
56
+ final_score += 10
57
+ reasoning.append("Behavior + Header correlation → +10")
58
+
59
+ if behavior_score >= 40 and url_score > 0:
60
+ final_score += 10
61
+ reasoning.append("Behavior + URL correlation → +10")
62
+
63
+ if behavior_score >= 50:
64
+ final_score += 15
65
+ reasoning.append("High-confidence behavioral attack +15")
66
+
67
+ # -------------------------
68
+ # CLAMP SCORE
69
+ # -------------------------
70
+ final_score = min(int(final_score), 100)
71
+
72
+ # -------------------------
73
+ # VERDICT
74
+ # -------------------------
75
+ if final_score >= 70:
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
  verdict = "🚨 Malicious"
77
+ elif final_score >= 40:
78
  verdict = "⚠️ Suspicious"
 
 
79
  else:
80
  verdict = "✅ Safe"
81
 
82
+ return final_score, verdict, reasoning