-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcontent.js
More file actions
65 lines (61 loc) · 2.84 KB
/
content.js
File metadata and controls
65 lines (61 loc) · 2.84 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
// Content script - Extracts page resources and DOM hints for security analysis
// Runs on every page to collect: scripts, meta tags, favicon, HTML samples, and resource paths
(function(){
const abs = (u) => { try { return new URL(u, location.href).href; } catch { return null; } };
const state = { external: new Set(), inline: [], favicon: null, meta: {}, domHints: { paths: [] }, htmlSample: null, lastSent: 0 };
// Capture current page state: scripts, meta tags, links, favicon, and HTML sample
function snapshot(){
try {
document.querySelectorAll('script').forEach(s => {
if (s.src) { const u = abs(s.src); if (u) state.external.add(u); }
else if (s.textContent && s.textContent.length > 20) {
if (state.inline.length < 16) state.inline.push(s.textContent.slice(0, 20000));
}
});
const gen = document.querySelector('meta[name="generator"]');
const mcsp = document.querySelector('meta[http-equiv="Content-Security-Policy"]');
state.meta = {
generator: gen ? (gen.content || "").slice(0,160) : null,
metaCSP: mcsp ? (mcsp.content || "").slice(0,500) : null
};
const urls = [
...Array.from(document.querySelectorAll('link[href]')).map(x=>abs(x.getAttribute('href'))),
...Array.from(document.querySelectorAll('script[src]')).map(x=>abs(x.getAttribute('src')))
].filter(Boolean).slice(0,200);
state.domHints.paths = urls.map(u => { try { return new URL(u).pathname; } catch { return null; } }).filter(Boolean);
if (!state.favicon) {
const icon = document.querySelector('link[rel~="icon"]');
state.favicon = icon && icon.href ? abs(icon.href) : abs('/favicon.ico');
}
// Capture HTML sample for intel extraction (emails, comments, forms, etc.)
if (!state.htmlSample && document.documentElement) {
state.htmlSample = document.documentElement.outerHTML.slice(0, 100000); // 100KB limit
}
} catch {}
}
// Send page resources to service worker (throttled to avoid spam)
function send(throttleMs=500){
const now = Date.now();
if (now - state.lastSent < throttleMs) return;
state.lastSent = now;
chrome.runtime.sendMessage({
type: "pageResources",
url: location.href,
pageTitle: document.title || null,
externalScripts: Array.from(state.external).slice(0, 100),
inlineScripts: state.inline.slice(0, 16),
favicon: state.favicon,
meta: state.meta,
domHints: state.domHints,
htmlSample: state.htmlSample
});
}
try {
snapshot(); send(0);
const mo = new MutationObserver(() => { snapshot(); send(300); });
mo.observe(document.documentElement, { childList: true, subtree: true });
setTimeout(()=>mo.disconnect(), 10000);
} catch (e) {
chrome.runtime.sendMessage({ type: "pageResources", error: String(e) });
}
})();