princemaxp commited on
Commit
06e04c9
·
verified ·
1 Parent(s): b4bbffc

Create scoring_engine.py

Browse files
Files changed (1) hide show
  1. scoring_engine.py +115 -0
scoring_engine.py ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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