clone

push a directory of html from the terminal and get a four-character url back. a deno cli on cloudflare

feat/site-feedback
nzip / worker / src / security / policy.ts
policy.ts 2.3K
1export interface WindowStats {2 bucket: number;3 addresses: number;4 scanners: number;5 misses: number;6 liveHits: number;7 rateLimited: number;8 topScannerAddresses: number;9 longestSequence: number;10 vaultMask: number;11 countries: string[];12 asns: number[];13}1415export interface IncidentRow {16 status: "open" | "closed";17 severity: number;18 opened_at: number;19 last_seen_at: number;20 last_alerted_at: number;21 quiet_windows: number;22 peak_addresses: number;23 total_addresses: number;24 total_live_hits: number;25 total_rate_limited: number;26 vault_mask: number;27}2829export type AlertAction = "open" | "escalate" | "summary" | "resolve" | null;3031export function signalSeverity(32 stats: WindowStats,33 incidentOpen = false,34): number {35 const distributed = stats.addresses >= 128 && stats.scanners >= 10 &&36 (stats.addresses === 0 || stats.misses / stats.addresses >= 0.9);37 const scannerSweep = stats.topScannerAddresses >= 20;38 const suspiciousLiveHit = stats.liveHits > 0 &&39 (incidentOpen || stats.topScannerAddresses >= 8 ||40 stats.longestSequence >= 8);41 if (stats.rateLimited > 0 || suspiciousLiveHit) return 2;42 if (scannerSweep || distributed) return 1;43 return 0;44}4546export function chooseAlertAction(47 incident: IncidentRow | null,48 stats: WindowStats,49 now: number,50): AlertAction {51 const severity = signalSeverity(stats, incident?.status === "open");52 if (!incident || incident.status === "closed") {53 return severity > 0 ? "open" : null;54 }55 if (severity === 0) return incident.quiet_windows >= 2 ? "resolve" : null;56 if (57 severity > incident.severity ||58 stats.addresses >= Math.max(20, incident.peak_addresses * 2) ||59 (stats.liveHits > 0 && incident.total_live_hits === 0)60 ) return "escalate";61 const reachedNewVault = (stats.vaultMask & ~incident.vault_mask) !== 0;62 if (reachedNewVault && now - incident.last_alerted_at >= 1800) {63 return "escalate";64 }65 if (now - incident.last_alerted_at >= 3600) return "summary";66 return null;67}6869export function longestAdjacentRun(addresses: number[]): number {70 if (addresses.length === 0) return 0;71 const sorted = [...new Set(addresses)].sort((a, b) => a - b);72 let longest = 1;73 let current = 1;74 for (let i = 1; i < sorted.length; i++) {75 current = sorted[i] === sorted[i - 1] + 1 ? current + 1 : 1;76 longest = Math.max(longest, current);77 }78 return longest;79}