diff --git a/background-script.js b/background-script.js index 2fb6884..717d6fd 100644 --- a/background-script.js +++ b/background-script.js @@ -26,7 +26,13 @@ function get_ios_id(uri) { } function update_color() { - chrome.browserAction.setIcon({ path: "res/images/FF_ext_icon_" + color + ".svg" }); + chrome.action.setIcon({ + path: { + "48": "res/images/FF_ext_icon_" + color + "-48.png", + "96": "res/images/FF_ext_icon_" + color + "-96.png", + "128": "res/images/FF_ext_icon_" + color + "-128.png" + } + }); } function getTab() { @@ -87,7 +93,13 @@ function get_domain_info(urlStr) { color = "orange" } - chrome.browserAction.setIcon({ path: "res/images/FF_ext_icon_" + color + ".svg" }); + chrome.action.setIcon({ + path: { + "48": "res/images/FF_ext_icon_" + color + "-48.png", + "96": "res/images/FF_ext_icon_" + color + "-96.png", + "128": "res/images/FF_ext_icon_" + color + "-128.png" + } + }); return { programs: programs, security_txt: security_txt, color: color, last_programs_update: CACHE.last_programs_update, lax: lax } } @@ -218,15 +230,35 @@ async function check_security_txt(urlStr, force_update) { for (let i = 0; i < SECURITY_TXT_PATHS.length; ++i) { const path = SECURITY_TXT_PATHS[i] const security_txt_url = `${protocol}//${hostname}${path}` - const content = await fetch(security_txt_url, { cache: 'no-cache', redirect: 'manual' }) - .then(r => r.status == 200 && r.text()) - .then(txt => txt && !txt.startsWith("<") && txt) - if (content) { - /* update and stop if found */ - CACHE.security_txt[hostname].content = content - CACHE.security_txt[hostname].url = security_txt_url - CACHE.security_txt[hostname].found = true - return + + try { + const response = await fetch(security_txt_url, { cache: 'no-cache', redirect: 'follow' }) + + if (response.ok) { + const content = await response.text() + + // Check if content looks like security.txt (not HTML) + if (content && content.trim().length > 0 && !content.trim().startsWith(" { getTab().then(tab => { - check_security_txt(tab.url, false).then(_ => { - get_domain_info(tab.url) - }) + if (tab && tab.url) { + check_security_txt(tab.url, false).then(_ => { + get_domain_info(tab.url) + }) + } }) }); chrome.tabs.onActivated.addListener(_ => { getTab().then(tab => { - check_security_txt(tab.url, false).then(_ => { - get_domain_info(tab.url) - }) + if (tab && tab.url) { + check_security_txt(tab.url, false).then(_ => { + get_domain_info(tab.url) + }) + } }) }); @@ -269,6 +305,31 @@ chrome.runtime.onMessage.addListener(function (request, sender, sendResponse) { case "GET_DOMAIN_INFO": sendResponse(get_domain_info(request.data)) break; + case "SECURITY_TXT_RESULT": + // Handle security.txt result from content script + if (request.data && request.data.hostname) { + CACHE.security_txt[request.data.hostname] = { + last_update: new Date(), + content: request.data.content || "", + url: request.data.url || "", + found: request.data.found || false + }; + console.log(`[VDP Finder] Security.txt cache updated for ${request.data.hostname}: ${request.data.found ? 'found' : 'not found'}`); + + // Update icon if this is the active tab + if (sender.tab) { + chrome.tabs.query({ active: true, currentWindow: true }, tabs => { + if (tabs[0] && tabs[0].id === sender.tab.id) { + get_domain_info(sender.tab.url); + } + }); + } + } + break; + case "CHECK_SECURITY_TXT": + // Request from content script (handled by content script itself) + sendResponse({ received: true }); + break; default: console.error(`Unhandled message "${request.msg}"`) break; diff --git a/content-script.js b/content-script.js new file mode 100644 index 0000000..02baf43 --- /dev/null +++ b/content-script.js @@ -0,0 +1,69 @@ +// Content script runs in page context and can bypass SSL warnings user has accepted + +const SECURITY_TXT_PATHS = ['/.well-known/security.txt', '/security.txt']; + +async function fetchSecurityTxt() { + const protocol = window.location.protocol; + const hostname = window.location.hostname; + + // Only check HTTP/HTTPS pages + if (!["http:", "https:"].includes(protocol)) { + return null; + } + + for (const path of SECURITY_TXT_PATHS) { + const security_txt_url = `${protocol}//${hostname}${path}`; + + try { + const response = await fetch(security_txt_url, { + cache: 'no-cache', + redirect: 'follow', + credentials: 'omit' // Don't send cookies for security.txt + }); + + if (response.ok) { + const content = await response.text(); + + // Check if content looks like security.txt (not HTML) + if (content && + content.trim().length > 0 && + !content.trim().startsWith(" { + if (request.msg === "CHECK_SECURITY_TXT") { + fetchSecurityTxt().then(sendResponse); + return true; // Will respond asynchronously + } +}); + +// Also check on page load and notify background +fetchSecurityTxt().then(result => { + if (result) { + chrome.runtime.sendMessage({ + msg: "SECURITY_TXT_RESULT", + data: result + }); + } +}); diff --git a/manifest.json b/manifest.json index ea1a526..97fcc19 100644 --- a/manifest.json +++ b/manifest.json @@ -1,30 +1,49 @@ { - "manifest_version": 2, + "manifest_version": 3, "name": "YesWeHack VDP Finder", - "version": "1.1.2", + "version": "1.1.6", "description": "This extension tells if visited sites have vulnerability disclosure programs", "homepage_url": "https://github.com/yeswehack/yeswehack_vdp_finder", "icons": { + "16": "res/images/icon-48.png", + "32": "res/images/icon-48.png", "48": "res/images/FF_ext_icon_red-48.png", - "96": "res/images/FF_ext_icon_red-96.png" + "96": "res/images/FF_ext_icon_red-96.png", + "128": "res/images/FF_ext_icon_red-128.png" }, - "browser_action": { + "action": { "default_title": "YesWeHack VDP Finder", "default_popup": "popup.html", "default_icon": { + "16": "res/images/icon-48.png", + "32": "res/images/icon-48.png", "48": "res/images/FF_ext_icon_gray-48.png", - "96": "res/images/FF_ext_icon_gray-96.png" + "96": "res/images/FF_ext_icon_gray-96.png", + "128": "res/images/FF_ext_icon_red-128.png" } }, "background": { - "scripts": ["background-script.js"] + "service_worker": "background-script.js" }, + "content_scripts": [{ + "matches": ["http://*/*", "https://*/*"], + "js": ["content-script.js"], + "run_at": "document_idle" + }], + "permissions": [ "tabs", - "" + "activeTab" + ], + + "host_permissions": [ + "https://firebounty.com/*", + "https://publicsuffix.org/*", + "https://*/*", + "http://*/*" ] } diff --git a/popup.js b/popup.js index 978fb06..c7f21b4 100644 --- a/popup.js +++ b/popup.js @@ -63,6 +63,11 @@ function update_content(domain_info) { document.addEventListener("DOMContentLoaded", _ => { getTab().then(tab => { + if (!tab || !tab.url) { + $("#domain-host").innerText = "N/A"; + return; + } + const url = new URL(tab.url) $("#domain-host").innerText = url.hostname; @@ -88,5 +93,7 @@ function getTab() { /* on open */ getTab().then(tab => { - chrome.runtime.sendMessage({ msg: "GET_DOMAIN_INFO", data: tab.url }, update_content); + if (tab && tab.url) { + chrome.runtime.sendMessage({ msg: "GET_DOMAIN_INFO", data: tab.url }, update_content); + } }) diff --git a/res/images/FF_ext_icon_green-128.png b/res/images/FF_ext_icon_green-128.png new file mode 100644 index 0000000..a15edba Binary files /dev/null and b/res/images/FF_ext_icon_green-128.png differ diff --git a/res/images/FF_ext_icon_green-48.png b/res/images/FF_ext_icon_green-48.png new file mode 100644 index 0000000..39735a8 Binary files /dev/null and b/res/images/FF_ext_icon_green-48.png differ diff --git a/res/images/FF_ext_icon_green-96.png b/res/images/FF_ext_icon_green-96.png new file mode 100644 index 0000000..40e83bf Binary files /dev/null and b/res/images/FF_ext_icon_green-96.png differ diff --git a/res/images/FF_ext_icon_orange-128.png b/res/images/FF_ext_icon_orange-128.png new file mode 100644 index 0000000..9cc6303 Binary files /dev/null and b/res/images/FF_ext_icon_orange-128.png differ diff --git a/res/images/FF_ext_icon_orange-48.png b/res/images/FF_ext_icon_orange-48.png new file mode 100644 index 0000000..f32a169 Binary files /dev/null and b/res/images/FF_ext_icon_orange-48.png differ diff --git a/res/images/FF_ext_icon_orange-96.png b/res/images/FF_ext_icon_orange-96.png new file mode 100644 index 0000000..2b6701e Binary files /dev/null and b/res/images/FF_ext_icon_orange-96.png differ diff --git a/res/images/FF_ext_icon_yellow-128.png b/res/images/FF_ext_icon_yellow-128.png new file mode 100644 index 0000000..9dcfd46 Binary files /dev/null and b/res/images/FF_ext_icon_yellow-128.png differ diff --git a/res/images/FF_ext_icon_yellow-48.png b/res/images/FF_ext_icon_yellow-48.png new file mode 100644 index 0000000..8c76f95 Binary files /dev/null and b/res/images/FF_ext_icon_yellow-48.png differ diff --git a/res/images/FF_ext_icon_yellow-96.png b/res/images/FF_ext_icon_yellow-96.png new file mode 100644 index 0000000..e16bc48 Binary files /dev/null and b/res/images/FF_ext_icon_yellow-96.png differ