// Content script - Runs on every page console.log('Phishing Detector: Content script loaded'); // Extract page-level features from DOM function extractPageFeatures() { const features = {}; try { // Favicon analysis const favicon = document.querySelector('link[rel*="icon"]'); const currentDomain = window.location.hostname; if (favicon) { const faviconUrl = new URL(favicon.href, window.location.href); features.Favicon = faviconUrl.hostname !== currentDomain ? 1 : -1; } else { features.Favicon = 1; // No favicon is suspicious } // Request_URL - Check if objects loaded from different domain const images = document.querySelectorAll('img, video, audio'); let externalResources = 0; images.forEach(img => { try { const imgUrl = new URL(img.src, window.location.href); if (imgUrl.hostname !== currentDomain) externalResources++; } catch (e) {} }); const externalRatio = images.length > 0 ? externalResources / images.length : 0; features.Request_URL = externalRatio > 0.22 ? 1 : (externalRatio > 0.61 ? 0 : -1); // URL_of_Anchor - Check anchor tags const anchors = document.querySelectorAll('a'); let suspiciousAnchors = 0; anchors.forEach(a => { const href = a.getAttribute('href'); if (!href || href === '#' || href.startsWith('javascript:')) { suspiciousAnchors++; } else { try { const anchorUrl = new URL(href, window.location.href); if (anchorUrl.hostname !== currentDomain) suspiciousAnchors++; } catch (e) {} } }); const anchorRatio = anchors.length > 0 ? suspiciousAnchors / anchors.length : 0; features.URL_of_Anchor = anchorRatio > 0.31 ? 1 : (anchorRatio > 0.67 ? 0 : -1); // Links_in_tags - Check meta, script, link tags const metaLinks = document.querySelectorAll('meta, script[src], link[href]'); let externalMetaLinks = 0; metaLinks.forEach(tag => { const src = tag.getAttribute('src') || tag.getAttribute('href') || tag.content; if (src) { try { const url = new URL(src, window.location.href); if (url.hostname !== currentDomain) externalMetaLinks++; } catch (e) {} } }); const metaRatio = metaLinks.length > 0 ? externalMetaLinks / metaLinks.length : 0; features.Links_in_tags = metaRatio > 0.17 ? 1 : (metaRatio > 0.81 ? 0 : -1); // SFH - Server Form Handler const forms = document.querySelectorAll('form'); let suspiciousForms = 0; forms.forEach(form => { const action = form.getAttribute('action'); if (!action || action === '' || action === 'about:blank') { suspiciousForms++; } else { try { const formUrl = new URL(action, window.location.href); if (formUrl.hostname !== currentDomain) suspiciousForms++; } catch (e) { suspiciousForms++; } } }); features.SFH = forms.length > 0 && suspiciousForms > 0 ? 1 : -1; // Submitting_to_email - Check if form submits to email let hasEmailSubmit = false; forms.forEach(form => { const action = form.getAttribute('action'); if (action && action.startsWith('mailto:')) hasEmailSubmit = true; }); features.Submitting_to_email = hasEmailSubmit ? 1 : -1; // Redirect - Count meta redirects const metaRefresh = document.querySelector('meta[http-equiv="refresh"]'); features.Redirect = metaRefresh ? 1 : -1; // on_mouseover - Check for mouseover events that change status bar let hasMouseoverStatusChange = false; anchors.forEach(a => { const mouseover = a.getAttribute('onmouseover') || a.getAttribute('onmouseout'); if (mouseover && (mouseover.includes('window.status') || mouseover.includes('location'))) { hasMouseoverStatusChange = true; } }); features.on_mouseover = hasMouseoverStatusChange ? 1 : -1; // RightClick - Check if right-click is disabled const hasRightClickDisable = document.body.getAttribute('oncontextmenu') === 'return false' || document.oncontextmenu === null; features.RightClick = hasRightClickDisable ? 1 : -1; // popUpWidnow - Check for popup windows const scripts = document.querySelectorAll('script'); let hasPopup = false; scripts.forEach(script => { if (script.textContent.includes('window.open') || script.textContent.includes('popup')) { hasPopup = true; } }); features.popUpWidnow = hasPopup ? 1 : -1; // Iframe - Check for iframes const iframes = document.querySelectorAll('iframe'); features.Iframe = iframes.length > 0 ? 1 : -1; return features; } catch (error) { console.error('Error extracting page features:', error); return null; } } // Listen for messages from popup or background chrome.runtime.onMessage.addListener((request, sender, sendResponse) => { if (request.action === 'getCurrentURL') { sendResponse({ url: window.location.href }); } if (request.action === 'getPageFeatures') { const features = extractPageFeatures(); sendResponse({ features: features }); } if (request.action === 'showWarning') { showPhishingWarning(); } return true; }); // Show warning banner on page function showPhishingWarning() { // Check if warning already exists if (document.getElementById('phishing-warning-banner')) { return; } const banner = document.createElement('div'); banner.id = 'phishing-warning-banner'; banner.style.cssText = ` position: fixed; top: 0; left: 0; right: 0; background: linear-gradient(135deg, #ff6b6b 0%, #c92a2a 100%); color: white; padding: 15px; text-align: center; font-family: Arial, sans-serif; font-size: 16px; font-weight: bold; z-index: 999999; box-shadow: 0 2px 10px rgba(0,0,0,0.3); animation: slideDown 0.5s ease; `; banner.innerHTML = `