ahmedumeraziz commited on
Commit
f0b6a41
Β·
verified Β·
1 Parent(s): 225940c

Create app.py

Browse files
Files changed (1) hide show
  1. app.py +124 -0
app.py ADDED
@@ -0,0 +1,124 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import os
2
+ import re
3
+ import streamlit as st
4
+ import requests
5
+ import dns.resolver
6
+ import whois
7
+ from validators import email as validate_email
8
+ from urllib.parse import urlparse
9
+ from datetime import datetime
10
+
11
+ # --- Config ---
12
+ GROQ_API_KEY = os.getenv("GROQ_API_KEY") or st.secrets.get("GROQ_API_KEY", "")
13
+ GOOD_DOMAINS = {"google.com", "microsoft.com", "github.com"} # expand as needed
14
+ BLACKLISTED_DOMAINS= {"bad-domain.com", "malicious.org"} # expand as needed
15
+
16
+ st.set_page_config(page_title="AI Phishing Detector", layout="centered")
17
+ st.title("πŸ“§ AI-Powered Phishing Detector & Responder")
18
+
19
+ # --- Inputs ---
20
+ sender_email = st.text_input("Sender Email Address:")
21
+ email_input = st.text_area("Email / Message Content:", height=250)
22
+
23
+ if st.button("Analyze for Phishing"):
24
+ # --- Basic Validation ---
25
+ if not GROQ_API_KEY:
26
+ st.error("πŸ”‘ Missing GROQ_API_KEY; set it in env or Streamlit secrets.")
27
+ st.stop()
28
+ if not validate_email(sender_email or ""):
29
+ st.error("❌ Please enter a valid sender email address.")
30
+ st.stop()
31
+ if not email_input.strip():
32
+ st.warning("βœ‰οΈ Paste the email content to analyze.")
33
+ st.stop()
34
+
35
+ # --- Sender Domain Checks ---
36
+ domain = sender_email.split("@")[-1].lower()
37
+ st.markdown("### πŸ“¨ Sender Domain Verification")
38
+ # MX lookup
39
+ try:
40
+ dns.resolver.resolve(domain, 'MX')
41
+ st.success(f"βœ… MX record found for `{domain}`")
42
+ except Exception as e:
43
+ st.error(f"❌ No MX record for `{domain}`: {e}")
44
+
45
+ # Whitelist / Blacklist
46
+ if domain in GOOD_DOMAINS:
47
+ st.info(f"βœ… Domain `{domain}` is in our **whitelist**.")
48
+ if domain in BLACKLISTED_DOMAINS:
49
+ st.error(f"⚠️ Domain `{domain}` is in our **blacklist**.")
50
+
51
+ # --- Link Extraction & Heuristic Checks ---
52
+ st.markdown("### 🌐 URL Heuristics")
53
+ urls = set(re.findall(r'(https?://[^\s]+)', email_input))
54
+ if not urls:
55
+ st.info("πŸ” No URLs detected in the message.")
56
+ else:
57
+ for url in urls:
58
+ parsed = urlparse(url)
59
+ netloc = parsed.netloc.lower()
60
+
61
+ # 1) Reachability & HTTPS
62
+ try:
63
+ resp = requests.head(url, timeout=5, allow_redirects=True)
64
+ code = resp.status_code
65
+ proto = parsed.scheme.upper()
66
+ if code < 400 and proto == "HTTPS":
67
+ st.success(f"🟒 {url} β†’ reachable ({code}), uses HTTPS")
68
+ elif code < 400:
69
+ st.warning(f"🟑 {url} β†’ reachable ({code}), but not HTTPS")
70
+ else:
71
+ st.error(f"πŸ”΄ {url} β†’ HTTP {code}")
72
+ except Exception as e:
73
+ st.error(f"❌ {url} β†’ not reachable: {e}")
74
+
75
+ # 2) Domain Age via WHOIS
76
+ try:
77
+ info = whois.whois(netloc)
78
+ creation = info.creation_date
79
+ if isinstance(creation, list):
80
+ creation = creation[0]
81
+ if creation:
82
+ age_days = (datetime.utcnow() - creation).days
83
+ if age_days < 30:
84
+ st.warning(f"⚠️ `{netloc}` registered {age_days} days ago (new domain)")
85
+ else:
86
+ st.info(f"βœ… `{netloc}` age: {age_days:,} days")
87
+ else:
88
+ st.info(f"ℹ️ No creation date for `{netloc}`")
89
+ except Exception as e:
90
+ st.warning(f"❔ WHOIS lookup failed for `{netloc}`: {e}")
91
+
92
+ # --- Build Prompt & Call GROQ ---
93
+ prompt = f"""
94
+ You are an AI cybersecurity assistant. Analyze the following email for phishing threats.
95
+
96
+ Sender: {sender_email}
97
+ Message:
98
+ \"\"\"{email_input}\"\"\"
99
+
100
+ Respond in this format:
101
+ 1. Phishing Risk Level: (High / Medium / Low)
102
+ 2. Reason: (Why you classified it so)
103
+ 3. Recommended Action
104
+ 4. Suggested Safe Response (if applicable)
105
+ """
106
+ st.markdown("### πŸ” AI Threat Analysis")
107
+ with st.spinner("Calling GROQ API…"):
108
+ headers = {
109
+ "Authorization": f"Bearer {GROQ_API_KEY}",
110
+ "Content-Type": "application/json"
111
+ }
112
+ data = {
113
+ "model": "llama3-8b-8192",
114
+ "messages": [
115
+ {"role": "system", "content": "You are a cybersecurity analyst."},
116
+ {"role": "user", "content": prompt}
117
+ ]
118
+ }
119
+ r = requests.post("https://api.groq.com/openai/v1/chat/completions", headers=headers, json=data)
120
+
121
+ if r.status_code == 200:
122
+ st.markdown(r.json()["choices"][0]["message"]["content"])
123
+ else:
124
+ st.error(f"Error {r.status_code}: {r.text}")