@q32/signal-scanner 0.1.0 → 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (75) hide show
  1. package/dist/dynamic.d.ts +43 -0
  2. package/dist/dynamic.d.ts.map +1 -0
  3. package/{src/dynamic.ts → dist/dynamic.js} +133 -156
  4. package/dist/dynamic.js.map +1 -0
  5. package/dist/feeds.d.ts +66 -0
  6. package/dist/feeds.d.ts.map +1 -0
  7. package/dist/feeds.js +259 -0
  8. package/dist/feeds.js.map +1 -0
  9. package/dist/index.d.ts +110 -0
  10. package/dist/index.d.ts.map +1 -0
  11. package/dist/index.js +1251 -0
  12. package/dist/index.js.map +1 -0
  13. package/dist/intel.d.ts +72 -0
  14. package/dist/intel.d.ts.map +1 -0
  15. package/dist/intel.js +480 -0
  16. package/dist/intel.js.map +1 -0
  17. package/dist/node-tls.d.ts +8 -0
  18. package/dist/node-tls.d.ts.map +1 -0
  19. package/dist/node-tls.js +48 -0
  20. package/dist/node-tls.js.map +1 -0
  21. package/dist/render.d.ts +26 -0
  22. package/dist/render.d.ts.map +1 -0
  23. package/dist/render.js +248 -0
  24. package/dist/render.js.map +1 -0
  25. package/dist/rules/packs/binary.d.ts +4 -0
  26. package/dist/rules/packs/binary.d.ts.map +1 -0
  27. package/dist/rules/packs/binary.js +101 -0
  28. package/dist/rules/packs/binary.js.map +1 -0
  29. package/dist/rules/packs/css.d.ts +3 -0
  30. package/dist/rules/packs/css.d.ts.map +1 -0
  31. package/dist/rules/packs/css.js +43 -0
  32. package/dist/rules/packs/css.js.map +1 -0
  33. package/dist/rules/packs/decoders.d.ts +3 -0
  34. package/dist/rules/packs/decoders.d.ts.map +1 -0
  35. package/dist/rules/packs/decoders.js +46 -0
  36. package/dist/rules/packs/decoders.js.map +1 -0
  37. package/dist/rules/packs/html.d.ts +4 -0
  38. package/dist/rules/packs/html.d.ts.map +1 -0
  39. package/dist/rules/packs/html.js +227 -0
  40. package/dist/rules/packs/html.js.map +1 -0
  41. package/dist/rules/packs/index.d.ts +24 -0
  42. package/dist/rules/packs/index.d.ts.map +1 -0
  43. package/dist/rules/packs/index.js +75 -0
  44. package/dist/rules/packs/index.js.map +1 -0
  45. package/dist/rules/packs/script-risk.d.ts +4 -0
  46. package/dist/rules/packs/script-risk.d.ts.map +1 -0
  47. package/dist/rules/packs/script-risk.js +231 -0
  48. package/dist/rules/packs/script-risk.js.map +1 -0
  49. package/dist/rules/packs/source-code.d.ts +3 -0
  50. package/dist/rules/packs/source-code.d.ts.map +1 -0
  51. package/dist/rules/packs/source-code.js +179 -0
  52. package/dist/rules/packs/source-code.js.map +1 -0
  53. package/dist/rules/packs/urls.d.ts +3 -0
  54. package/dist/rules/packs/urls.d.ts.map +1 -0
  55. package/dist/rules/packs/urls.js +123 -0
  56. package/dist/rules/packs/urls.js.map +1 -0
  57. package/dist/rules/types.d.ts +34 -0
  58. package/dist/rules/types.d.ts.map +1 -0
  59. package/dist/rules/types.js +2 -0
  60. package/dist/rules/types.js.map +1 -0
  61. package/package.json +18 -14
  62. package/src/feeds.ts +0 -334
  63. package/src/index.ts +0 -1366
  64. package/src/intel.ts +0 -561
  65. package/src/node-tls.ts +0 -55
  66. package/src/render.ts +0 -233
  67. package/src/rules/packs/binary.ts +0 -103
  68. package/src/rules/packs/css.ts +0 -44
  69. package/src/rules/packs/decoders.ts +0 -47
  70. package/src/rules/packs/html.ts +0 -255
  71. package/src/rules/packs/index.ts +0 -76
  72. package/src/rules/packs/script-risk.ts +0 -236
  73. package/src/rules/packs/source-code.ts +0 -180
  74. package/src/rules/packs/urls.ts +0 -138
  75. package/src/rules/types.ts +0 -56
package/dist/feeds.js ADDED
@@ -0,0 +1,259 @@
1
+ // Cached blocklist-feed index for the signal scanner.
2
+ //
3
+ // Runtime-agnostic: all persistence goes through an injected `IntelStorage`
4
+ // (R2 in a Worker, the filesystem in a CLI, an in-memory map in tests). The
5
+ // scanner never knows where bytes live.
6
+ //
7
+ // Feeds can be millions of entries, far too large to hold in a Worker, so the
8
+ // index is sharded by a stable host bucket (`shardOf`) into small files. The
9
+ // match path fetches only the few shards a scan actually needs.
10
+ //
11
+ // Evidence strength is a numeric score (the lib's native currency), decided at
12
+ // ingest and encoded by which score-band shard family a host lands in — so
13
+ // shard files stay compact host arrays. Recent/active/evidence-backed entries
14
+ // get a high score; aged/weak entries a lower one. Matching returns the highest
15
+ // band a host appears in; the caller turns that score into a finding severity
16
+ // via the usual scoring helpers.
17
+ /** Default score bands. Callers may use any integer band; these are conventions. */
18
+ export const FEED_SCORE_ACTIVE = 90; // live / recent / evidence-backed
19
+ export const FEED_SCORE_AGED = 55; // historical / weak / unverified
20
+ const ROOT = "feeds";
21
+ const GLOBAL_MANIFEST_KEY = `${ROOT}/manifest.json`;
22
+ const encoder = new TextEncoder();
23
+ const decoder = new TextDecoder();
24
+ /** All 256 shard prefixes ("00".."ff"); a staged build finalizes one per job. */
25
+ export const SHARD_PREFIXES = Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, "0"));
26
+ /** Stable, synchronous host -> shard bucket. FNV-1a low byte; loader and matcher must agree. */
27
+ export function shardOf(host) {
28
+ let hash = 0x811c9dc5;
29
+ const lower = host.toLowerCase();
30
+ for (let i = 0; i < lower.length; i++) {
31
+ hash ^= lower.charCodeAt(i);
32
+ hash = Math.imul(hash, 0x01000193);
33
+ }
34
+ return ((hash >>> 0) & 0xff).toString(16).padStart(2, "0");
35
+ }
36
+ /** Score a feed entry from its evidence: active/recent => high, else aged/weak. */
37
+ export function scoreFor(input) {
38
+ const recencyDays = input.recencyDays ?? 90;
39
+ const now = input.now ?? Date.parse(new Date().toISOString());
40
+ const recent = input.addedAt ? now - Date.parse(input.addedAt) <= recencyDays * 86_400_000 : true;
41
+ return input.active !== false && recent ? input.activeScore ?? FEED_SCORE_ACTIVE : input.agedScore ?? FEED_SCORE_AGED;
42
+ }
43
+ // ---- Small feeds: full rebuild in one pass --------------------------------
44
+ /** Rebuild a feed's shard index from a complete entry set (feeds that fit in memory). */
45
+ export async function rebuildFeed(storage, feedId, version, entries, meta = {}) {
46
+ const buckets = bucketEntries(dedupeEntries(entries));
47
+ const bands = {};
48
+ for (const [band, prefixes] of buckets) {
49
+ for (const [prefix, hosts] of prefixes) {
50
+ await putJson(storage, shardKey(feedId, version, band, prefix), [...hosts]);
51
+ bands[band] = (bands[band] ?? 0) + hosts.size;
52
+ }
53
+ }
54
+ return finalizeFeed(storage, feedId, version, bands, meta);
55
+ }
56
+ // ---- Huge feeds: staged chunk + per-shard merge ---------------------------
57
+ /** Write one download chunk's parsed entries to staging. Safe to run many in parallel. */
58
+ export async function writeFeedChunk(storage, feedId, version, chunkId, entries) {
59
+ const buckets = bucketEntries(entries);
60
+ for (const [band, prefixes] of buckets) {
61
+ for (const [prefix, hosts] of prefixes) {
62
+ await putJson(storage, stagingKey(feedId, version, chunkId, band, prefix), [...hosts]);
63
+ }
64
+ }
65
+ }
66
+ /** Merge every chunk's partials for one (band, prefix) into the final shard. One job per shard. */
67
+ export async function finalizeFeedShard(storage, feedId, version, band, prefix) {
68
+ // Staging is keyed band/prefix/chunk, so this lists only the chunks for this
69
+ // one shard rather than scanning the whole staging tree.
70
+ const shardStaging = `${ROOT}/${feedId}/${version}/staging/${band}/${prefix}/`;
71
+ const merged = new Set();
72
+ for (const key of await storage.list(shardStaging)) {
73
+ for (const host of await readArray(storage, key))
74
+ merged.add(host);
75
+ }
76
+ if (merged.size)
77
+ await putJson(storage, shardKey(feedId, version, String(band), prefix), [...merged]);
78
+ return merged.size;
79
+ }
80
+ /** Publish the feed: write its manifest, register it globally, and sweep staging + old versions. */
81
+ export async function finalizeFeed(storage, feedId, version, bands, meta = {}) {
82
+ const record = {
83
+ version,
84
+ bands,
85
+ source: meta.source,
86
+ generatedAt: meta.generatedAt ?? new Date().toISOString()
87
+ };
88
+ await putJson(storage, `${ROOT}/${feedId}/${version}/manifest.json`, record);
89
+ const manifest = (await readJson(storage, GLOBAL_MANIFEST_KEY)) ?? { feeds: {} };
90
+ const previous = manifest.feeds[feedId]?.version;
91
+ manifest.feeds[feedId] = record;
92
+ await putJson(storage, GLOBAL_MANIFEST_KEY, manifest);
93
+ await sweep(storage, `${ROOT}/${feedId}/${version}/staging/`);
94
+ if (previous && previous !== version)
95
+ await sweep(storage, `${ROOT}/${feedId}/${previous}/`);
96
+ return record;
97
+ }
98
+ // ---- Match path -----------------------------------------------------------
99
+ /** Match candidate hosts against all published feeds, returning the highest score band per hit. */
100
+ export async function matchCachedFeeds(storage, hosts) {
101
+ const manifest = await readJson(storage, GLOBAL_MANIFEST_KEY);
102
+ if (!manifest)
103
+ return [];
104
+ const uniqueHosts = [...new Set(hosts.map((host) => host.toLowerCase()).filter(Boolean))];
105
+ const shardCache = new Map();
106
+ const matches = [];
107
+ for (const [feedId, record] of Object.entries(manifest.feeds)) {
108
+ const bands = Object.keys(record.bands)
109
+ .map(Number)
110
+ .sort((a, b) => b - a); // highest score first
111
+ for (const host of uniqueHosts) {
112
+ const prefix = shardOf(host);
113
+ for (const band of bands) {
114
+ const key = shardKey(feedId, record.version, String(band), prefix);
115
+ let set = shardCache.get(key);
116
+ if (!set) {
117
+ set = new Set(await readArray(storage, key));
118
+ shardCache.set(key, set);
119
+ }
120
+ if (set.has(host)) {
121
+ matches.push({ feedId, host, score: band, source: record.source });
122
+ break; // strongest band wins for this host
123
+ }
124
+ }
125
+ }
126
+ }
127
+ return matches;
128
+ }
129
+ // ---- Parsers (lib owns the format; the app handles byte/line chunking) -----
130
+ /** Extract a lowercase host from a URL or bare host line; null for comments/blanks. */
131
+ export function hostFromLine(line) {
132
+ const trimmed = line.trim();
133
+ if (!trimmed || trimmed.startsWith("#") || trimmed.startsWith("!"))
134
+ return null;
135
+ const candidate = trimmed.includes("://") ? trimmed : `http://${trimmed.split(/\s+/)[0]}`;
136
+ try {
137
+ const host = new URL(candidate).hostname.toLowerCase();
138
+ // Real domains/IPv4 always contain a dot; reject single-label junk lines.
139
+ return host && host.includes(".") ? host : null;
140
+ }
141
+ catch {
142
+ return null;
143
+ }
144
+ }
145
+ /** OpenPhish community feed: one active phishing URL per line. */
146
+ export function parseOpenPhishFeed(text, score = FEED_SCORE_ACTIVE) {
147
+ return dedupeEntries(linesOf(text).map(hostFromLine).filter(isHost).map((host) => ({ host, score })));
148
+ }
149
+ /** A bare domain/host blocklist (e.g. Phishing.Database lists) at a caller-chosen score. */
150
+ export function parseHostList(text, score) {
151
+ return dedupeEntries(linesOf(text).map(hostFromLine).filter(isHost).map((host) => ({ host, score })));
152
+ }
153
+ /** URLhaus CSV (id,dateadded,url,url_status,...): online+recent scores high, else aged. */
154
+ export function parseUrlhausCsv(text, opts = {}) {
155
+ const entries = [];
156
+ for (const line of linesOf(text)) {
157
+ if (!line || line.startsWith("#"))
158
+ continue;
159
+ const cols = parseCsvRow(line);
160
+ if (cols.length < 4)
161
+ continue;
162
+ const host = hostFromLine(cols[2]);
163
+ if (!host)
164
+ continue;
165
+ entries.push({ host, score: scoreFor({ active: cols[3] === "online", addedAt: cols[1], recencyDays: opts.recencyDays, now: opts.now }) });
166
+ }
167
+ return dedupeEntries(entries);
168
+ }
169
+ // ---- internals ------------------------------------------------------------
170
+ function shardKey(feedId, version, band, prefix) {
171
+ return `${ROOT}/${feedId}/${version}/${band}/${prefix}.json`;
172
+ }
173
+ function stagingKey(feedId, version, chunkId, band, prefix) {
174
+ // band/prefix first so a single shard's chunks share a narrow list prefix.
175
+ return `${ROOT}/${feedId}/${version}/staging/${band}/${prefix}/${chunkId}.json`;
176
+ }
177
+ // score band (string) -> shard prefix -> hosts
178
+ function bucketEntries(entries) {
179
+ const buckets = new Map();
180
+ for (const entry of entries) {
181
+ const host = entry.host.toLowerCase();
182
+ if (!host)
183
+ continue;
184
+ const band = String(entry.score);
185
+ let prefixes = buckets.get(band);
186
+ if (!prefixes)
187
+ buckets.set(band, (prefixes = new Map()));
188
+ const prefix = shardOf(host);
189
+ let set = prefixes.get(prefix);
190
+ if (!set)
191
+ prefixes.set(prefix, (set = new Set()));
192
+ set.add(host);
193
+ }
194
+ return buckets;
195
+ }
196
+ function dedupeEntries(entries) {
197
+ // Keep the strongest score when a host appears more than once.
198
+ const scoreByHost = new Map();
199
+ for (const { host, score } of entries) {
200
+ scoreByHost.set(host, Math.max(scoreByHost.get(host) ?? 0, score));
201
+ }
202
+ return [...scoreByHost].map(([host, score]) => ({ host, score }));
203
+ }
204
+ function isHost(value) {
205
+ return typeof value === "string" && value.length > 0;
206
+ }
207
+ function linesOf(text) {
208
+ return text.split(/\r?\n/);
209
+ }
210
+ function parseCsvRow(line) {
211
+ const cols = [];
212
+ let current = "";
213
+ let inQuotes = false;
214
+ for (let i = 0; i < line.length; i++) {
215
+ const char = line[i];
216
+ if (char === '"') {
217
+ if (inQuotes && line[i + 1] === '"') {
218
+ current += '"';
219
+ i++;
220
+ }
221
+ else
222
+ inQuotes = !inQuotes;
223
+ }
224
+ else if (char === "," && !inQuotes) {
225
+ cols.push(current);
226
+ current = "";
227
+ }
228
+ else {
229
+ current += char;
230
+ }
231
+ }
232
+ cols.push(current);
233
+ return cols;
234
+ }
235
+ async function putJson(storage, key, value) {
236
+ await storage.put(key, encoder.encode(JSON.stringify(value)));
237
+ }
238
+ async function readJson(storage, key) {
239
+ const bytes = await storage.get(key);
240
+ if (!bytes)
241
+ return null;
242
+ try {
243
+ return JSON.parse(decoder.decode(bytes));
244
+ }
245
+ catch {
246
+ return null;
247
+ }
248
+ }
249
+ async function readArray(storage, key) {
250
+ const value = await readJson(storage, key);
251
+ return Array.isArray(value) ? value : [];
252
+ }
253
+ async function sweep(storage, prefix) {
254
+ if (!storage.delete)
255
+ return;
256
+ for (const key of await storage.list(prefix))
257
+ await storage.delete(key);
258
+ }
259
+ //# sourceMappingURL=feeds.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"feeds.js","sourceRoot":"","sources":["../src/feeds.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,110 @@
1
+ import type { RuleScoreModel } from "./rules/types.js";
2
+ export type ContentKind = "html" | "javascript" | "css" | "json" | "svg" | "text" | "unknown" | "archive" | "executable";
3
+ export type Severity = "info" | "low" | "medium" | "high" | "critical";
4
+ export type Confidence = "low" | "medium" | "high";
5
+ export type Disposition = "allow" | "warn" | "review" | "block";
6
+ export interface FetchRecord {
7
+ url: string;
8
+ finalUrl: string;
9
+ status: number;
10
+ contentType: string;
11
+ contentLength: number | null;
12
+ redirectChain: string[];
13
+ tls?: {
14
+ protocol?: string;
15
+ issuer?: string;
16
+ subject?: string;
17
+ validFrom?: string;
18
+ validTo?: string;
19
+ };
20
+ }
21
+ export interface ScannerSource {
22
+ url?: string;
23
+ finalUrl?: string;
24
+ filename?: string;
25
+ contentType?: string | null;
26
+ originUrl?: string;
27
+ tls?: TlsMetadata;
28
+ }
29
+ export interface TlsMetadata {
30
+ authorized?: boolean;
31
+ authorizationError?: string | null;
32
+ issuer?: string;
33
+ subject?: string;
34
+ validFrom?: string;
35
+ validTo?: string;
36
+ fingerprint256?: string;
37
+ serialNumber?: string;
38
+ }
39
+ export interface ArtifactRecord {
40
+ source: string;
41
+ artifactType: string;
42
+ parentOffset: number;
43
+ depth: number;
44
+ sha256?: string;
45
+ text: string;
46
+ }
47
+ export interface Finding {
48
+ id: string;
49
+ severity: Severity;
50
+ confidence: Confidence;
51
+ score: number;
52
+ scoreModel: RuleScoreModel;
53
+ title: string;
54
+ description: string;
55
+ locationType: "url" | "html" | "javascript" | "css" | "source" | "binary" | "decoded_artifact" | "aggregate";
56
+ locationValue: string;
57
+ ruleId: string;
58
+ metadata: Record<string, unknown>;
59
+ }
60
+ export interface ExtractedUrl {
61
+ raw: string;
62
+ normalized: string;
63
+ registrableDomain: string | null;
64
+ relation: "same-origin" | "same-site" | "subdomain" | "off-site" | "unknown";
65
+ scheme: string;
66
+ destinationType: "http" | "https" | "ip" | "private" | "localhost" | "url-shortener" | "other";
67
+ flags: string[];
68
+ }
69
+ export interface ScannerReport {
70
+ contentKind: ContentKind;
71
+ findings: Finding[];
72
+ urls: ExtractedUrl[];
73
+ artifacts: ArtifactRecord[];
74
+ score: number;
75
+ disposition: Disposition;
76
+ counters: Record<string, number>;
77
+ }
78
+ export interface Scanner {
79
+ feed(chunk: Uint8Array): Finding[];
80
+ finish(): ScannerReport;
81
+ }
82
+ interface ScannerOptions {
83
+ source?: ScannerSource;
84
+ maxWindowChars?: number;
85
+ maxDecodedBytes?: number;
86
+ maxDecodeDepth?: number;
87
+ }
88
+ export declare function createScanner(options?: ScannerOptions): Scanner;
89
+ export declare function detectContentKind(input: {
90
+ contentType?: string | null;
91
+ filename?: string | null;
92
+ firstBytes?: Uint8Array;
93
+ }): ContentKind;
94
+ export declare function normalizeUrl(raw: string, base?: string): ExtractedUrl | null;
95
+ export declare function scoreFindings(findings: Finding[]): number;
96
+ export declare function dispositionForScore(score: number): Disposition;
97
+ export declare function registrableDomainFor(host: string): string | null;
98
+ export declare function isAdOrAnalyticsHost(normalizedUrl: string): boolean;
99
+ export interface RedirectAssessment {
100
+ /** The redirect crossed to a different registrable domain (not just a subdomain hop). */
101
+ offSite: boolean;
102
+ /** The destination host itself looks suspicious (shortener, suspicious TLD, punycode, IP, shared/generated host). */
103
+ destinationSuspicious: boolean;
104
+ requestedRegistrable: string;
105
+ finalRegistrable: string;
106
+ destinationFlags: string[];
107
+ }
108
+ export declare function assessRedirect(requestedUrl: string, finalUrl: string): RedirectAssessment | null;
109
+ export {};
110
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}