From 2dcd2a1b94a170ce2a4ca705d4005d7aa9fc213f Mon Sep 17 00:00:00 2001 From: Alicja Date: Fri, 31 May 2024 22:49:37 +0200 Subject: [PATCH] Moving the project to the final repository --- backend/.idea/.gitignore | 3 + backend/.idea/.name | 1 + backend/.idea/backend.iml | 8 + .../inspectionProfiles/profiles_settings.xml | 6 + backend/.idea/misc.xml | 7 + backend/.idea/modules.xml | 8 + backend/backend.py | 202 ++++++++++++++++++ backend/safe_emails.json | 1 + extension/background.js | 51 +++++ extension/icon128.png | Bin 0 -> 13167 bytes extension/icon16.png | Bin 0 -> 537 bytes extension/icon48.png | Bin 0 -> 2639 bytes extension/manifest.json | 28 +++ extension/notification.html | 17 ++ extension/notification.js | 47 ++++ extension/popup.html | 21 ++ extension/popup.js | 92 ++++++++ 17 files changed, 492 insertions(+) create mode 100644 backend/.idea/.gitignore create mode 100644 backend/.idea/.name create mode 100644 backend/.idea/backend.iml create mode 100644 backend/.idea/inspectionProfiles/profiles_settings.xml create mode 100644 backend/.idea/misc.xml create mode 100644 backend/.idea/modules.xml create mode 100644 backend/backend.py create mode 100644 backend/safe_emails.json create mode 100644 extension/background.js create mode 100644 extension/icon128.png create mode 100644 extension/icon16.png create mode 100644 extension/icon48.png create mode 100644 extension/manifest.json create mode 100644 extension/notification.html create mode 100644 extension/notification.js create mode 100644 extension/popup.html create mode 100644 extension/popup.js diff --git a/backend/.idea/.gitignore b/backend/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/backend/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/backend/.idea/.name b/backend/.idea/.name new file mode 100644 index 0000000..5c7471e --- /dev/null +++ b/backend/.idea/.name @@ -0,0 +1 @@ +backend.py \ No newline at end of file diff --git a/backend/.idea/backend.iml b/backend/.idea/backend.iml new file mode 100644 index 0000000..d0876a7 --- /dev/null +++ b/backend/.idea/backend.iml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/backend/.idea/inspectionProfiles/profiles_settings.xml b/backend/.idea/inspectionProfiles/profiles_settings.xml new file mode 100644 index 0000000..105ce2d --- /dev/null +++ b/backend/.idea/inspectionProfiles/profiles_settings.xml @@ -0,0 +1,6 @@ + + + + \ No newline at end of file diff --git a/backend/.idea/misc.xml b/backend/.idea/misc.xml new file mode 100644 index 0000000..a377feb --- /dev/null +++ b/backend/.idea/misc.xml @@ -0,0 +1,7 @@ + + + + + + \ No newline at end of file diff --git a/backend/.idea/modules.xml b/backend/.idea/modules.xml new file mode 100644 index 0000000..e066844 --- /dev/null +++ b/backend/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/backend/backend.py b/backend/backend.py new file mode 100644 index 0000000..6d375c7 --- /dev/null +++ b/backend/backend.py @@ -0,0 +1,202 @@ +from flask import Flask, request, jsonify, session +from flask_cors import CORS +import imaplib +import email +from email.header import decode_header +from sklearn.feature_extraction.text import TfidfVectorizer +from sklearn.naive_bayes import MultinomialNB +import traceback +import json +import os + +app = Flask(__name__) +CORS(app) +app.secret_key = 'your_secret_key' + +SAFE_EMAILS_FILE = 'safe_emails.json' + +# Load safe emails from file +def load_safe_emails(): + if os.path.exists(SAFE_EMAILS_FILE): + with open(SAFE_EMAILS_FILE, 'r') as file: + return json.load(file) + return [] + +# Save safe emails to file +def save_safe_emails(safe_emails): + with open(SAFE_EMAILS_FILE, 'w') as file: + json.dump(safe_emails, file) + +safe_emails = load_safe_emails() + +# Dane treningowe +training_data = [ + ("Urgent account verification", "support@example.com", 1), + ("Meeting agenda", "boss@example.com", 0), + ("Password reset request", "no-reply@example.com", 1), + ("Team lunch schedule", "hr@example.com", 0), + ("Suspicious login attempt", "security@example.com", 1), + ("Project update", "colleague@example.com", 0), + ("Verify your email address", "verification@example.com", 1), + ("Weekly report", "manager@example.com", 0), + ("Your account has been suspended", "no-reply@example.com", 1), + ("Company policy update", "admin@example.com", 0), + ("Immediate action required", "alert@example.com", 1), + ("Holiday party invitation", "events@example.com", 0), + ("Important security update", "security@example.com", 1), + ("Monthly performance review", "boss@example.com", 0), + ("Claim your prize now", "lottery@example.com", 1), + ("Training session details", "training@example.com", 0), + ("Unauthorized access detected", "alert@example.com", 1), + ("Office relocation notice", "admin@example.com", 0), + ("Confirm your subscription", "newsletter@example.com", 1), + ("Sales team meeting", "sales@example.com", 0), + ("Your payment is overdue", "billing@example.com", 1), + ("Client feedback", "client@example.com", 0), + ("Update your account details", "update@example.com", 1), + ("Social event invitation", "social@example.com", 0), + ("Action required: Update password", "security@example.com", 1), + ("New project assignment", "manager@example.com", 0), + ("Notice of data breach", "security@example.com", 1), + ("Weekly newsletter", "newsletter@example.com", 0), + ("Re: Your recent purchase", "support@example.com", 1), + ("Performance appraisal meeting", "hr@example.com", 0), + ("Important account notice", "no-reply@example.com", 1), + ("Quarterly earnings report", "finance@example.com", 0), + ("Urgent: Verify your identity", "security@example.com", 1), + ("Birthday celebration", "events@example.com", 0), +] + +subjects = [x[0] for x in training_data] +senders = [x[1] for x in training_data] +labels = [x[2] for x in training_data] + +# Połączenie tytułów i nadawców +combined_features = [s + ' ' + senders[i] for i, s in enumerate(subjects)] +vectorizer = TfidfVectorizer() +X = vectorizer.fit_transform(combined_features) +y = labels + +model = MultinomialNB() +model.fit(X, y) + +@app.route('/login', methods=['POST']) +def login(): + data = request.get_json() + username = data.get('username') + password = data.get('password') + + try: + mail = imaplib.IMAP4_SSL('imap.wp.pl') + mail.login(username, password) + session['username'] = username + session['password'] = password + return jsonify({'message': 'Login successful'}), 200 + except imaplib.IMAP4.error as e: + print(f'Login failed: {e}') + return jsonify({'message': 'Login failed'}), 401 + except Exception as e: + print('Error during login:', e) + traceback.print_exc() + return jsonify({'message': 'Internal server error'}), 500 + +@app.route('/check_mail', methods=['GET']) +def check_mail(): + if 'username' not in session or 'password' not in session: + return jsonify({'message': 'Not logged in'}), 401 + + username = session['username'] + password = session['password'] + + try: + mail = imaplib.IMAP4_SSL('imap.wp.pl') + mail.login(username, password) + mail.select('INBOX') + result, data = mail.search(None, 'ALL') + email_ids = data[0].split()[-10:] # Pobierz ostatnie 10 e-maili + emails = [] + + for e_id in email_ids: + result, email_data = mail.fetch(e_id, '(RFC822)') + raw_email = email_data[0][1] + msg = email.message_from_bytes(raw_email) + subject = decode_header_value(msg['subject']) + sender = decode_header_value(msg['from']) + is_phishing = detect_phishing(subject, sender, e_id.decode()) + emails.append({'subject': subject, 'from': sender, 'is_phishing': is_phishing, 'id': e_id.decode()}) + + return jsonify(emails), 200 + except Exception as e: + print('Error during email check:', e) + traceback.print_exc() + return jsonify({'message': 'Internal server error'}), 500 + +@app.route('/logout', methods=['POST']) +def logout(): + try: + session.pop('username', None) + session.pop('password', None) + return jsonify({'message': 'Logged out'}), 200 + except Exception as e: + print('Error during logout:', e) + traceback.print_exc() + return jsonify({'message': 'Internal server error'}), 500 + +@app.route('/mark_safe/', methods=['POST']) +def mark_safe(email_id): + global safe_emails + safe_emails.append(email_id) + save_safe_emails(safe_emails) + print(f'Email {email_id} marked as safe') + return jsonify({"message": f"Email {email_id} marked as safe"}), 200 + +@app.route('/move_trash/', methods=['POST']) +def move_trash(email_id): + if 'username' not in session or 'password' not in session: + return jsonify({'message': 'Not logged in'}), 401 + + username = session['username'] + password = session['password'] + + try: + mail = imaplib.IMAP4_SSL('imap.wp.pl') + mail.login(username, password) + mail.select('INBOX') + print(f'Trying to move email ID {email_id} to Trash') # Logging email ID + mail.store(email_id, '+FLAGS', '\\Deleted') + mail.expunge() + print(f'Email {email_id} deleted') # Logging deletion + return jsonify({"message": f"Email {email_id} deleted"}), 200 + except Exception as e: + print(f'Error during moving email to trash: {e}') + traceback.print_exc() + return jsonify({'message': 'Internal server error'}), 500 + +def decode_header_value(value): + parts = decode_header(value) + header_parts = [] + for part, encoding in parts: + if isinstance(part, bytes): + try: + if encoding: + header_parts.append(part.decode(encoding)) + else: + header_parts.append(part.decode('utf-8')) + except (LookupError, UnicodeDecodeError): + header_parts.append(part.decode('utf-8', errors='ignore')) + else: + header_parts.append(part) + return ''.join(header_parts) + +def detect_phishing(subject, sender, email_id): + if email_id in safe_emails: + return False # If email is marked as safe, it's not phishing + + phishing_keywords = ['urgent', 'verify', 'account', 'suspend', 'login'] + phishing_senders = ['support@example.com', 'no-reply@example.com'] + if any(keyword in subject.lower() for keyword in phishing_keywords) or sender.lower() in phishing_senders: + return True + return False + +if __name__ == '__main__': + app.run(port=5000) diff --git a/backend/safe_emails.json b/backend/safe_emails.json new file mode 100644 index 0000000..5c46c44 --- /dev/null +++ b/backend/safe_emails.json @@ -0,0 +1 @@ +["3", "13", "14", "15"] \ No newline at end of file diff --git a/extension/background.js b/extension/background.js new file mode 100644 index 0000000..540f1cd --- /dev/null +++ b/extension/background.js @@ -0,0 +1,51 @@ +chrome.runtime.onMessage.addListener((message, sender, sendResponse) => { + if (message.type === 'phishing-detected') { + const emails = message.emails; + let notificationTitle = 'You are safe!'; + let notificationMessage = 'No phishing emails detected.'; + + const phishingEmails = emails.filter(email => email.is_phishing); + if (phishingEmails.length > 0) { + notificationTitle = 'You are in danger!'; + notificationMessage = `Email from ${phishingEmails[0].from} titled "${phishingEmails[0].subject}" has been identified as phishing.`; + + chrome.windows.create({ + url: 'notification.html', + type: 'popup', + width: 300, + height: 200 + }, function(window) { + chrome.storage.local.set({ + notificationTitle: notificationTitle, + notificationMessage: notificationMessage, + emailId: phishingEmails[0].id + }); + }); + } else { + chrome.windows.create({ + url: 'notification.html', + type: 'popup', + width: 300, + height: 200 + }, function(window) { + chrome.storage.local.set({ + notificationTitle: notificationTitle, + notificationMessage: notificationMessage, + emailId: null + }); + }); + } + } else if (message.type === 'mark-safe') { + fetch(`http://localhost:5000/mark_safe/${message.emailId}`, { + method: 'POST' + }).then(response => response.json()) + .then(data => console.log(data)) + .catch(error => console.error('Error:', error)); + } else if (message.type === 'move-trash') { + fetch(`http://localhost:5000/move_trash/${message.emailId}`, { + method: 'POST' + }).then(response => response.json()) + .then(data => console.log(data)) + .catch(error => console.error('Error:', error)); + } +}); diff --git a/extension/icon128.png b/extension/icon128.png new file mode 100644 index 0000000000000000000000000000000000000000..650f0ec15cd9040dc73d860eaef592f6e0de48e6 GIT binary patch literal 13167 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 bCe8f=-5a=#Qa`gB00000NkvXXu0mjf>9zs@ literal 0 HcmV?d00001 diff --git a/extension/icon48.png b/extension/icon48.png new file mode 100644 index 0000000000000000000000000000000000000000..7a38d413913858dd1edce4c7d74b5592941fc7ff GIT binary patch literal 2639 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 + + + + + Notification + + + +
+

+ + + +
+ + diff --git a/extension/notification.js b/extension/notification.js new file mode 100644 index 0000000..64a7bec --- /dev/null +++ b/extension/notification.js @@ -0,0 +1,47 @@ +document.addEventListener('DOMContentLoaded', function() { + const markSafeButton = document.getElementById('mark-safe'); + const moveTrashButton = document.getElementById('move-trash'); + const closeButton = document.getElementById('close'); + const notificationMessage = document.getElementById('notification-message'); + + chrome.storage.local.get(['notificationTitle', 'notificationMessage', 'emailId'], function(items) { + notificationMessage.textContent = items.notificationMessage; + + if (items.emailId) { + // Show action buttons if there's a phishing email + markSafeButton.style.display = 'inline-block'; + moveTrashButton.style.display = 'inline-block'; + } else { + // Hide action buttons if no phishing emails + markSafeButton.style.display = 'none'; + moveTrashButton.style.display = 'none'; + } + + markSafeButton.addEventListener('click', function() { + console.log('Mark Safe button clicked for emailId:', items.emailId); + chrome.runtime.sendMessage({ + type: 'mark-safe', + emailId: items.emailId + }, function(response) { + console.log('Mark safe response:', response); + }); + setTimeout(() => window.close(), 50); // Wait for 50ms before closing the window + }); + + moveTrashButton.addEventListener('click', function() { + console.log('Move to Trash button clicked for emailId:', items.emailId); + chrome.runtime.sendMessage({ + type: 'move-trash', + emailId: items.emailId + }, function(response) { + console.log('Move to trash response:', response); + }); + setTimeout(() => window.close(), 50); // Wait for 50ms before closing the window + }); + + closeButton.addEventListener('click', function() { + console.log('Close button clicked'); + window.close(); + }); + }); +}); diff --git a/extension/popup.html b/extension/popup.html new file mode 100644 index 0000000..5b7ad3b --- /dev/null +++ b/extension/popup.html @@ -0,0 +1,21 @@ + + + + + Phishing Email Detector + + + +
+

Login

+ + + +
+ +
+ + diff --git a/extension/popup.js b/extension/popup.js new file mode 100644 index 0000000..fa3fc67 --- /dev/null +++ b/extension/popup.js @@ -0,0 +1,92 @@ +document.addEventListener('DOMContentLoaded', function() { + const loginButton = document.getElementById('login'); + const checkMailButton = document.getElementById('check-mail'); + const logoutButton = document.getElementById('logout'); + const loginSection = document.getElementById('login-section'); + const controlSection = document.getElementById('control-section'); + + // Check if already logged in + chrome.storage.local.get(['username', 'password'], function(items) { + if (items.username && items.password) { + loginSection.style.display = 'none'; + controlSection.style.display = 'block'; + } else { + loginSection.style.display = 'block'; + controlSection.style.display = 'none'; + } + }); + + loginButton.addEventListener('click', function() { + const username = document.getElementById('username').value; + const password = document.getElementById('password').value; + + fetch('http://localhost:5000/login', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + body: JSON.stringify({ username, password }), + credentials: 'include' + }) + .then(response => response.json()) + .then(data => { + alert(data.message); + if (data.message === 'Login successful') { + chrome.storage.local.set({ 'username': username, 'password': password }, function() { + loginSection.style.display = 'none'; + controlSection.style.display = 'block'; + }); + } + }) + .catch(error => { + console.error('Error during login request:', error); + alert('An error occurred while logging in'); + }); + }); + + checkMailButton.addEventListener('click', function() { + fetch('http://localhost:5000/check_mail', { + method: 'GET', + headers: { + 'Content-Type': 'application/json' + }, + credentials: 'include' + }) + .then(response => response.json()) + .then(data => { + console.log('Check mail response:', data); + chrome.runtime.sendMessage({ + type: 'phishing-detected', + emails: data + }); + }) + .catch(error => { + console.error('Error during check mail request:', error); + alert('An error occurred while checking mail'); + }); + }); + + logoutButton.addEventListener('click', function() { + fetch('http://localhost:5000/logout', { + method: 'POST', + headers: { + 'Content-Type': 'application/json' + }, + credentials: 'include' + }) + .then(response => response.json()) + .then(data => { + alert(data.message); + if (data.message === 'Logged out') { + chrome.storage.local.remove(['username', 'password'], function() { + loginSection.style.display = 'block'; + controlSection.style.display = 'none'; + }); + } + }) + .catch(error => { + console.error('Error during logout request:', error); + alert('An error occurred while logging out'); + }); + }); +});