first commit
This commit is contained in:
commit
ff482ebe23
251 files changed
+19126
No files matched your search
@@ -0,0 +1,56 @@
|
||||
import {createRequire} from 'node:module';
|
||||
import {spawn} from 'node:child_process';
|
||||
import fs from 'node:fs/promises';
|
||||
import path from 'node:path';
|
||||
import os from 'node:os';
|
||||
import assert from 'node:assert/strict';
|
||||
const require=createRequire(import.meta.url);
|
||||
const {startAgentControl}=require('../apps/browser/agent-control.cjs');
|
||||
const {startInspector}=require('../apps/browser/inspection.cjs');
|
||||
const root=path.resolve('dist/win-unpacked');
|
||||
if(process.platform!=='win32')throw Error('Windows package verification requires Windows');
|
||||
const {extractFile}=require('@electron/asar');
|
||||
for(const file of ['apps/browser/policy-assignment.cjs','packages/core/policy-groups.mjs','apps/browser/tab-registry.cjs','apps/browser/agent-adapters.cjs','apps/browser/agent-control.cjs','apps/browser/password-fill.cjs','apps/browser/diagnostics.cjs','packages/core/diagnostics.mjs','packages/core/security.mjs'])assert.deepEqual(extractFile(path.join(root,'resources/app.asar'),path.normalize(file)),await fs.readFile(file),`Packaged device/session policy source is stale: ${file}`);
|
||||
for(const file of ['apps/browser/main.cjs','apps/browser/preload.cjs','apps/browser/site-preload.cjs','apps/browser/clipboard-deny.cjs','apps/browser/clipboard-guard.cjs','apps/browser/clipboard-dom.cjs','apps/browser/page-clipboard-guard.cjs','apps/browser/startup-security.cjs','apps/browser/visual-capture.cjs','apps/browser/renderer.js','apps/browser/index.html','apps/browser/style.css','packages/core/clipboard.mjs']){
|
||||
assert.deepEqual(extractFile(path.join(root,'resources/app.asar'),path.normalize(file)),await fs.readFile(file),`Packaged source is stale: ${file}`);
|
||||
}
|
||||
for(const file of ['apps/browser/inspection.cjs','apps/browser/managed-settings.cjs','apps/browser/management-channel.cjs','apps/browser/enterprise-inspection.cjs','apps/browser/icap-client.cjs','apps/browser/network-posture.cjs','apps/browser/download-gate.cjs','packages/core/enterprise.mjs','packages/core/semantic.mjs','packages/core/managed-settings.mjs','packages/core/policy-channel.cjs','packages/core/policy.mjs'])assert.ok(extractFile(path.join(root,'resources/app.asar'),path.normalize(file)).equals(await fs.readFile(file)),`Packaged source is stale: ${file}`);
|
||||
for(const file of ['semantic.py','engine.py','server.py','windows_containment.py','windows_appcontainer.py','sandbox_worker.py','provision_runtime_acl.py'])assert.deepEqual(await fs.readFile(path.join(root,'resources/inspector',file)),await fs.readFile(path.join('apps/inspector',file)),`Packaged inspector is stale: ${file}`);
|
||||
const temporary=await fs.mkdtemp(path.join(os.tmpdir(),'safetynet-package-'));
|
||||
for(const file of ['apps/browser/bookmarks.cjs','packages/core/bookmarks.mjs'])assert.ok(extractFile(path.join(root,'resources/app.asar'),path.normalize(file)).equals(await fs.readFile(file)),`Packaged bookmark source is stale: ${file}`);
|
||||
function run(executable,args,input,timeoutMs=15000){return new Promise((resolve,reject)=>{
|
||||
const child=spawn(executable,args,{stdio:['pipe','pipe','pipe'],windowsHide:true,env:{...process.env,PYTHONDONTWRITEBYTECODE:'1'}});let output='',errors='';
|
||||
const timer=setTimeout(()=>{child.kill();reject(Error('Package verification timed out'));},timeoutMs);
|
||||
child.on('error',reject);child.stdout.on('data',data=>output+=data);child.stderr.on('data',data=>errors+=data);
|
||||
child.on('close',code=>{clearTimeout(timer);resolve({code,output,errors});});child.stdin.end(input);
|
||||
});}
|
||||
let service;
|
||||
try{
|
||||
const inspectorBytecode=path.join(root,'resources/inspector/__pycache__');
|
||||
const bytecodeExists=()=>fs.stat(inspectorBytecode).then(()=>true,error=>{if(error.code==='ENOENT')return false;throw error;});
|
||||
assert.equal(await bytecodeExists(),false,'Package must start with no inspector bytecode cache');
|
||||
const packagedInspector=startInspector(path.join(root,'resources'),true);
|
||||
assert.ok(packagedInspector,'Packaged inspector runtime is missing');
|
||||
try{
|
||||
const verdict=await packagedInspector.inspect(Buffer.from('Public package verification text'),{dlp:{maxBytes:1048576,rules:[],semantic:{enabled:false}}});
|
||||
assert.equal(verdict.decision,'allow','Packaged contained inspector failed');
|
||||
assert.equal(verdict.coverage.complete,true);
|
||||
}finally{packagedInspector.stop();}
|
||||
const semanticPath=path.join(root,'resources/semantic');
|
||||
const actual=await run(path.join(root,'resources/python/python.exe'),['-c','import sys; sys.path.insert(0,sys.argv[1]); from semantic import NativeSemanticModel; m=NativeSemanticModel(sys.argv[2],sys.argv[3]); vectors=m.text_vectors("Public information about weather forecasting."); assert len(vectors)>=1 and len(vectors[0])==768; m.close(); print("Offline packaged semantic CPU inference verified.")',path.join(root,'resources/inspector'),path.join(semanticPath,'models'),path.join(semanticPath,'searchi-gemma-worker.exe')],undefined,45000);
|
||||
assert.equal(actual.code,0,'Packaged offline semantic inference failed');assert.ok(actual.output.includes('Offline packaged semantic CPU inference verified.'));
|
||||
service=await startAgentControl({authorize:async()=>({allowed:true,role:'agent',scopes:['sessions:list']}),audit:async()=>{},actions:{sessions:async()=>[{id:'managed',url:'https://example.test/'}]}});
|
||||
const encrypted=await run(path.join(root,'resources/python/python.exe'),[path.join(root,'resources/inspector/dpapi.py'),'protect'],JSON.stringify({address:service.address,token:service.token}));
|
||||
assert.equal(encrypted.code,0,'Packaged DPAPI failed');
|
||||
const connection=path.join(temporary,'connection.json'),request=path.join(temporary,'request.json');
|
||||
await fs.writeFile(connection,JSON.stringify({format:'windows-dpapi-v1',protectedConnection:encrypted.output}));
|
||||
await fs.writeFile(request,JSON.stringify({action:'sessions'}));
|
||||
const result=await run(path.join(root,'SafetyNet.exe'),[`--agent-connection=${connection}`,`--agent-action=${request}`]);
|
||||
assert.equal(result.code,0,'Packaged agent helper failed');assert.equal(JSON.parse(result.output).result[0].id,'managed');assert.equal(result.output.includes(service.token),false);
|
||||
assert.equal(await bytecodeExists(),false,'Cold packaged startup must not create inspector bytecode files');
|
||||
console.log('Packaged security sources, Windows-contained inspector, offline EmbeddingGemma 2 CPU inference, Windows agent helper and bundled DPAPI runtime passed.');
|
||||
}finally{
|
||||
await service?.close();
|
||||
if(!temporary.startsWith(path.join(os.tmpdir(),'safetynet-package-')))throw Error('Unexpected temporary directory');
|
||||
await fs.rm(temporary,{recursive:true,force:true});
|
||||
}
|
||||
Reference in new issue
Block a user