import test from 'node:test'; import assert from 'node:assert/strict'; import {createRequire} from 'node:module'; import {createHash} from 'node:crypto'; import {defaultPolicy,inspect} from '../packages/core/policy.mjs'; const {snapshotHeaders,inspectHeaders}=createRequire(import.meta.url)('../apps/browser/header-inspection.cjs'); function policy(){const p=defaultPolicy();p.dlp.rules=[{id:'roadmap',label:'Roadmap',kind:'literal',value:'Secret Roadmap',action:'block'}];return p;} async function check(headers,p=policy(),overrides={}){return inspectHeaders(snapshotHeaders(headers,p),{policy:p,inspect,isCurrent:()=>true,...overrides});} test('custom, credential and browser metadata header values obey the same central DLP',async()=>{ for(const name of ['X-Data','Cookie','Authorization','Proxy-Authorization','Referer','User-Agent'])assert.equal((await check({[name]:'Secret Roadmap'})).ruleId,'roadmap'); assert.equal((await check({'X-Data':'Secret%20Roadmap'})).ruleId,'roadmap'); assert.equal((await check({'X-First':'Secret ','X-Second':'Roadmap'})).ruleId,'roadmap'); assert.equal((await check({'Secret-Roadmap':'public'})).decision,'allow'); assert.equal((await check({Authorization:'Bearer sk-123456789012345678901234'})).ruleId,'api-secret'); assert.equal((await check({Authorization:'Bearer eyJhbGciOiJIUzI1NiJ9.opaque.signature',Cookie:'session=ordinaryOpaqueValue'})).decision,'allow'); }); test('per-header exact hashes and registered content phrases remain effective',async()=>{ const p=policy();p.dlp.rules=[{id:'reference',label:'Reference',kind:'sha256',value:createHash('sha256').update('known exact reference').digest('hex'),action:'block'}]; assert.equal((await check({'X-Data':'known exact reference'},p)).ruleId,'reference'); p.security.content.blockedPhrases=['Internal planning']; assert.equal((await check({Cookie:'x=Internal+planning'},p)).ruleId,'content-blocklist'); }); test('snapshot rejects malformed, inherited, accessor and oversized input without executing getters',()=>{ const p=policy();let getterCalled=false;const input={};Object.defineProperty(input,'X',{enumerable:true,get(){getterCalled=true;return 'public';}}); assert.throws(()=>snapshotHeaders(input,p),/uninspectable/);assert.equal(getterCalled,false); for(const malformed of [null,[],Object.create({X:'secret'}),{'Bad Header':'public'},{X:['public']},{X:'bad\r\nheader'},{X:'bad\0header'}])assert.throws(()=>snapshotHeaders(malformed,p),/uninspectable/); assert.throws(()=>snapshotHeaders(Object.fromEntries(Array.from({length:129},(_,i)=>[`X-${i}`,'ok'])),p),/size-limit/); assert.throws(()=>snapshotHeaders({X:'a'.repeat(65536)},p),/size-limit/); p.dlp.maxBytes=1024;assert.throws(()=>snapshotHeaders({X:'a'.repeat(1024)},p),/size-limit/); }); test('approved snapshot cannot be changed by input mutations or scanners; buffers wiped',async()=>{ const p=policy(),input={Cookie:'ordinary=session',X:'public'},snapshot=snapshotHeaders(input,p);input.X='Secret Roadmap'; let held;const result=await inspectHeaders(snapshot,{policy:p,inspect,isCurrent:()=>true,inspectEnterprise:async bytes=>{held=bytes;return {decision:'allow',coverage:{complete:true}};}}); assert.equal(result.decision,'allow');assert.equal(snapshot.headers.X,'public');assert.throws(()=>{snapshot.headers.X='Secret Roadmap';},TypeError);assert.ok(held.every(byte=>byte===0)); assert.deepEqual(Object.keys(result).sort(),['decision','ruleId']); }); test('local and enterprise inspection require complete allow and current policy',async()=>{ const p=policy();p.dlp.semantic.enabled=true; assert.equal((await check({X:'public'},p)).ruleId,'inspector-unavailable'); assert.equal((await check({X:'public'},p,{inspectLocal:async()=>({decision:'allow'})})).ruleId,'inspection-incomplete'); let enterpriseCalls=0; assert.equal((await check({X:'public'},p,{inspectLocal:async()=>({decision:'block',ruleId:'semantic-secret'}),inspectEnterprise:async()=>{enterpriseCalls++;}})).ruleId,'semantic-secret');assert.equal(enterpriseCalls,0); let current=true; assert.equal((await check({X:'public'},p,{isCurrent:()=>current,inspectLocal:async()=>{current=false;return {decision:'allow',coverage:{complete:true}};}})).ruleId,'policy-changed'); p.dlp.semantic.enabled=false; assert.equal((await check({X:'public'},p,{inspectEnterprise:async()=>({decision:'allow'})})).ruleId,'inspection-incomplete'); assert.equal((await check({X:'public'},p,{inspectEnterprise:async()=>({decision:'block',ruleId:'icap-malware'})})).ruleId,'icap-malware'); }); test('exceptions wipe full-header scan buffers and do not turn failure into allow',async()=>{ let held; await assert.rejects(check({Cookie:'ordinary=session'},policy(),{inspectEnterprise:async bytes=>{held=bytes;throw Error('fixture scanner unavailable');}}),/unavailable/); assert.ok(held.every(byte=>byte===0)); });