38 lines
3.3 KiB
JavaScript
38 lines
3.3 KiB
JavaScript
import test from 'node:test';
|
|
import assert from 'node:assert/strict';
|
|
import { generateKeyPairSync, createHash } from 'node:crypto';
|
|
import {defaultPolicy,PolicySchema,signPolicy,verifyPolicy,inspect,destinationAllowed,hostMatches} from '../packages/core/policy.mjs';
|
|
test('signed policies reject tampering, rollback and expiry',()=>{
|
|
const keys=generateKeyPairSync('ed25519');const privateKey=keys.privateKey.export({type:'pkcs8',format:'pem'}),publicKey=keys.publicKey.export({type:'spki',format:'pem'});
|
|
const p=defaultPolicy(),envelope=signPolicy(p,privateKey);assert.deepEqual(verifyPolicy(envelope,publicKey),p);
|
|
assert.throws(()=>verifyPolicy({...envelope,payload:envelope.payload+'A'},publicKey),/signature/);
|
|
assert.throws(()=>verifyPolicy(envelope,publicKey,2),/rollback/);
|
|
p.expiresAt=new Date(0).toISOString();assert.throws(()=>verifyPolicy(signPolicy(p,privateKey),publicKey),/expired/);
|
|
});
|
|
test('hostname policies resist suffix confusion and enforce block precedence',()=>{
|
|
assert.equal(hostMatches('a.corp.example','*.corp.example'),true);assert.equal(hostMatches('corp.example','*.corp.example'),false);
|
|
assert.equal(hostMatches('evilcorp.example','*.corp.example'),false);
|
|
const p=defaultPolicy();p.browser.allowedHosts=['*.corp.example'];p.browser.blockedHosts=['blocked.corp.example'];
|
|
assert.equal(destinationAllowed('https://ok.corp.example/',p),true);assert.equal(destinationAllowed('https://blocked.corp.example/',p),false);
|
|
assert.equal(destinationAllowed('https://ok.corp.example.evil.test/',p),false);assert.equal(destinationAllowed('file:///secret',p),false);
|
|
assert.equal(destinationAllowed('https://user:[email protected]/',p),false);
|
|
});
|
|
test('DLP blocks credentials, encoded phrases, binary and oversized payloads',()=>{
|
|
const p=defaultPolicy();p.dlp.rules=[{id:'project',label:'Secret project',kind:'literal',value:'Project Orion',action:'block'}];
|
|
for(const input of ['Project Orion','project%20orion','prompt=project+orion','{"prompt":"Project \\u004frion"}'])assert.equal(inspect(Buffer.from(input),p).decision,'block');
|
|
assert.equal(inspect(Buffer.from('-----BEGIN PRIVATE KEY-----'),p).ruleId,'private-key');
|
|
assert.equal(inspect(Buffer.from([255,254]),p).ruleId,'uninspectable');
|
|
assert.equal(inspect(Buffer.from('a\0b'),p).ruleId,'uninspectable');
|
|
assert.equal(inspect(Buffer.alloc(p.dlp.maxBytes+1),p).ruleId,'size-limit');
|
|
assert.equal(inspect(Buffer.from('Public information'),p).decision,'allow');
|
|
});
|
|
test('exact fingerprints detect registered bytes',()=>{
|
|
const p=defaultPolicy(),data=Buffer.from('confidential sample');p.dlp.rules=[{id:'file',label:'Reference',kind:'sha256',value:createHash('sha256').update(data).digest('hex'),action:'block'}];
|
|
assert.equal(inspect(data,p).ruleId,'file');assert.equal(inspect(Buffer.from('different sample'),p).decision,'allow');
|
|
});
|
|
test('invalid proxy, duplicate IDs and unsafe home schemes are rejected',()=>{
|
|
const p=defaultPolicy();p.proxy={mode:'pac_script',pacUrl:'http://example.com/pac'};assert.equal(PolicySchema.safeParse(p).success,false);
|
|
p.proxy={mode:'system'};p.browser.homeUrl='file:///secret';assert.equal(PolicySchema.safeParse(p).success,false);
|
|
p.browser.homeUrl='https://example.com';const r={id:'duplicate',label:'Secret',kind:'literal',value:'x',action:'block'};p.dlp.rules=[r,r];assert.equal(PolicySchema.safeParse(p).success,false);
|
|
});
|