MUHAMMADSAADAMIN commited on
Commit
7a50c62
Β·
verified Β·
1 Parent(s): bec7d28
Files changed (1) hide show
  1. app.py +32 -11
app.py CHANGED
@@ -93,6 +93,7 @@ def analyze_code(code: str, language: str):
93
  clean_conf = round(probs[0] * 100, 1)
94
  vuln_conf = round(probs[1] * 100, 1)
95
 
 
96
  findings, matched_categories = [], set()
97
  for pattern, message in VULN_RULES.get(language, []):
98
  if re.search(pattern, code, re.IGNORECASE):
@@ -111,26 +112,46 @@ def analyze_code(code: str, language: str):
111
  elif "shell" in message.lower() or "subprocess" in message.lower():
112
  matched_categories.add("command_injection")
113
 
 
 
114
  model_uncertain = abs(vuln_conf - clean_conf) < 15.0
115
- if model_uncertain and len(findings) == 0:
116
- score = 0.0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
117
  else:
118
- finding_penalty = min(len(findings) * 0.8, 4.0)
119
- base_score = (vuln_conf / 100) * 6.0 if not model_uncertain else 0.0
120
- score = round(min(base_score + finding_penalty, 10.0), 1)
121
 
122
- if score >= 7.0: risk, verdict = "critical", "VULNERABLE"
123
- elif score >= 4.5: risk, verdict = "high", "VULNERABLE"
124
- elif score >= 2.5: risk, verdict = "medium", "REVIEW NEEDED"
125
- elif score >= 1.0: risk, verdict = "low", "MOSTLY SAFE"
126
- else: risk, verdict = "safe", "CLEAN"
 
127
 
 
128
  tips = [SMART_TIPS[c] for c in matched_categories if c in SMART_TIPS]
129
  general = CODE_TIPS.get(language, ["Follow security best practices."])
130
  tips += random.sample(general, min(max(0, 3 - len(tips)), len(general)))
131
 
132
  return {
133
- "score": score,
 
134
  "risk": risk,
135
  "verdict": verdict,
136
  "clean_confidence": clean_conf,
 
93
  clean_conf = round(probs[0] * 100, 1)
94
  vuln_conf = round(probs[1] * 100, 1)
95
 
96
+ # ── Static rule scan ───────────────────────────────────
97
  findings, matched_categories = [], set()
98
  for pattern, message in VULN_RULES.get(language, []):
99
  if re.search(pattern, code, re.IGNORECASE):
 
112
  elif "shell" in message.lower() or "subprocess" in message.lower():
113
  matched_categories.add("command_injection")
114
 
115
+ # ── Code quality score (10 = perfect, 0 = critical) ───
116
+ # Start at 10, deduct for each issue found
117
  model_uncertain = abs(vuln_conf - clean_conf) < 15.0
118
+
119
+ # Deductions
120
+ model_penalty = (vuln_conf / 100) * 4.0 if not model_uncertain else 0.0
121
+ findings_penalty = min(len(findings) * 1.2, 6.0)
122
+ total_deduction = round(min(model_penalty + findings_penalty, 10.0), 1)
123
+
124
+ quality_score = round(max(10.0 - total_deduction, 0.0), 1)
125
+
126
+ # ── Grade label ────────────────────────────────────────
127
+ if quality_score >= 9.0:
128
+ grade, verdict = "A", "EXCELLENT"
129
+ elif quality_score >= 7.5:
130
+ grade, verdict = "B", "GOOD"
131
+ elif quality_score >= 6.0:
132
+ grade, verdict = "C", "FAIR"
133
+ elif quality_score >= 4.0:
134
+ grade, verdict = "D", "POOR"
135
+ elif quality_score >= 2.0:
136
+ grade, verdict = "F", "VULNERABLE"
137
  else:
138
+ grade, verdict = "F-", "CRITICAL"
 
 
139
 
140
+ # ── Risk label (kept for API compatibility) ────────────
141
+ if quality_score <= 3.0: risk = "critical"
142
+ elif quality_score <= 5.0: risk = "high"
143
+ elif quality_score <= 6.5: risk = "medium"
144
+ elif quality_score <= 8.5: risk = "low"
145
+ else: risk = "safe"
146
 
147
+ # ── Smart tips ─────────────────────────────────────────
148
  tips = [SMART_TIPS[c] for c in matched_categories if c in SMART_TIPS]
149
  general = CODE_TIPS.get(language, ["Follow security best practices."])
150
  tips += random.sample(general, min(max(0, 3 - len(tips)), len(general)))
151
 
152
  return {
153
+ "score": quality_score, # now 10 = best, 0 = worst
154
+ "grade": grade,
155
  "risk": risk,
156
  "verdict": verdict,
157
  "clean_confidence": clean_conf,