mirror of
https://github.com/momenbasel/keyFinder.git
synced 2026-04-23 21:16:00 +02:00
b73c2185b0
- Migrated to Chrome Manifest V3 with service worker architecture - 80+ secret detection patterns covering AWS, GCP, Azure, GitHub, GitLab, Stripe, Slack, Discord, OpenAI, and 30+ other providers - 10 scanning surfaces: inline scripts, external scripts, meta tags, hidden inputs, data attributes, HTML comments, URL params, web storage, cookies, and network response interception - Shannon entropy analysis for detecting undocumented secret formats - MAIN world interceptor for XHR/fetch response scanning and window globals - Professional dark-theme UI with filtering, search, and CSV/JSON export - Zero dependencies - removed jQuery, Bootstrap, font-awesome, popper - Proper XSS-safe DOM rendering throughout - Badge counter on extension icon showing finding count - All frames scanning including iframes
104 lines
3.3 KiB
JavaScript
104 lines
3.3 KiB
JavaScript
const KEYWORDS_KEY = "kf_keywords";
|
|
const FINDINGS_KEY = "kf_findings";
|
|
|
|
const DEFAULT_KEYWORDS = [
|
|
"key", "api_key", "apikey", "api-key", "secret", "token",
|
|
"access_token", "auth", "credential", "password",
|
|
"client_id", "client_secret"
|
|
];
|
|
|
|
chrome.runtime.onInstalled.addListener(async (details) => {
|
|
if (details.reason === "install") {
|
|
await chrome.storage.local.set({
|
|
[KEYWORDS_KEY]: DEFAULT_KEYWORDS,
|
|
[FINDINGS_KEY]: []
|
|
});
|
|
}
|
|
});
|
|
|
|
chrome.runtime.onMessage.addListener((request, sender, sendResponse) => {
|
|
if (request.type === "finding") {
|
|
saveFinding(request.data).then(() => sendResponse({ ok: true }));
|
|
return true;
|
|
}
|
|
if (request.type === "getKeywords") {
|
|
getKeywords().then((keywords) => sendResponse({ keywords }));
|
|
return true;
|
|
}
|
|
if (request.type === "getFindings") {
|
|
getFindings().then((findings) => sendResponse({ findings }));
|
|
return true;
|
|
}
|
|
if (request.type === "addKeyword") {
|
|
addKeyword(request.keyword).then((result) => sendResponse(result));
|
|
return true;
|
|
}
|
|
if (request.type === "removeKeyword") {
|
|
removeKeyword(request.keyword).then(() => sendResponse({ ok: true }));
|
|
return true;
|
|
}
|
|
if (request.type === "removeFinding") {
|
|
removeFinding(request.url).then(() => sendResponse({ ok: true }));
|
|
return true;
|
|
}
|
|
if (request.type === "clearFindings") {
|
|
clearFindings().then(() => sendResponse({ ok: true }));
|
|
return true;
|
|
}
|
|
if (request.type === "exportFindings") {
|
|
getFindings().then((findings) => sendResponse({ findings }));
|
|
return true;
|
|
}
|
|
});
|
|
|
|
async function getKeywords() {
|
|
const result = await chrome.storage.local.get(KEYWORDS_KEY);
|
|
return result[KEYWORDS_KEY] || DEFAULT_KEYWORDS;
|
|
}
|
|
|
|
async function addKeyword(keyword) {
|
|
const keywords = await getKeywords();
|
|
const normalized = keyword.trim().toLowerCase();
|
|
if (!normalized) return { ok: false, error: "Keyword cannot be empty." };
|
|
if (keywords.includes(normalized)) return { ok: false, error: "Keyword already exists." };
|
|
keywords.push(normalized);
|
|
await chrome.storage.local.set({ [KEYWORDS_KEY]: keywords });
|
|
return { ok: true };
|
|
}
|
|
|
|
async function removeKeyword(keyword) {
|
|
const keywords = await getKeywords();
|
|
await chrome.storage.local.set({ [KEYWORDS_KEY]: keywords.filter((k) => k !== keyword) });
|
|
}
|
|
|
|
async function getFindings() {
|
|
const result = await chrome.storage.local.get(FINDINGS_KEY);
|
|
return result[FINDINGS_KEY] || [];
|
|
}
|
|
|
|
async function saveFinding(finding) {
|
|
const findings = await getFindings();
|
|
const isDuplicate = findings.some(
|
|
(f) => f.url === finding.url && f.match === finding.match
|
|
);
|
|
if (isDuplicate) return;
|
|
findings.push(finding);
|
|
await chrome.storage.local.set({ [FINDINGS_KEY]: findings });
|
|
|
|
const badgeCount = findings.length;
|
|
chrome.action.setBadgeText({ text: badgeCount > 0 ? String(badgeCount) : "" });
|
|
chrome.action.setBadgeBackgroundColor({ color: "#e74c3c" });
|
|
}
|
|
|
|
async function removeFinding(url) {
|
|
const findings = await getFindings();
|
|
const updated = findings.filter((f) => f.url !== url);
|
|
await chrome.storage.local.set({ [FINDINGS_KEY]: updated });
|
|
chrome.action.setBadgeText({ text: updated.length > 0 ? String(updated.length) : "" });
|
|
}
|
|
|
|
async function clearFindings() {
|
|
await chrome.storage.local.set({ [FINDINGS_KEY]: [] });
|
|
chrome.action.setBadgeText({ text: "" });
|
|
}
|