stemedb/docs/demo/vulnbank/node/exec.js
jordan b3e8a9a058 feat: Multi-application expansion with chaos testing and community UI
Major additions:
- Community Next.js app (port 18187) for browsing claims with API docs
- stemedb-chaos crate: Fault injection, chaos testing, CRDT properties
- Latent ingestion system: Reddit/FDA ingesters with ADK-Go agents
- Disputed claims handling: Manual review workflows and validation
- Aphoria security scanner: New extractors (SQL injection, command
  injection, weak crypto, TLS version), policy-based ignores, UAT reports
- Docker infrastructure: Dockerfile, docker-compose.yml for full stack
- VulnBank demo: Intentionally vulnerable multi-language test corpus

SDK & API enhancements:
- Source registry handlers for tracking data provenance
- Metrics endpoint
- Skeptic filtering improvements

Code quality:
- Split 14 large files (>500 lines) into focused modules
- All files now under 500-line limit per project guidelines

Documentation:
- Chaos testing guide, circuit breakers, observability docs
- Phase 7 UAT documentation updates
- Martin Kleppmann technical writer agent

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-02-04 01:24:14 -07:00

92 lines
2.1 KiB
JavaScript

/**
* VulnBank - Command Execution with intentional vulnerabilities
*
* Vulnerabilities:
* - Command injection via exec()
* - Command injection via execSync()
*/
const { exec, execSync } = require('child_process');
/**
* VULNERABILITY: Command injection via exec()
* User input passed directly to shell command
*/
function listFiles(directory, callback) {
// BLOCK: exec with user input enables command injection
exec(`ls -la ${directory}`, (error, stdout, stderr) => {
if (error) {
callback(error, null);
return;
}
callback(null, stdout);
});
}
/**
* VULNERABILITY: Command injection via execSync()
* Synchronous command execution with user input
*/
function readFileHead(filename) {
try {
// BLOCK: execSync with user input enables command injection
const output = execSync(`head -10 ${filename}`);
return output.toString();
} catch (error) {
return null;
}
}
/**
* VULNERABILITY: Command injection in image processing
* User-controlled filename in shell command
*/
function resizeImage(inputPath, outputPath, size) {
// BLOCK: Command injection - user controls file paths
exec(`convert ${inputPath} -resize ${size} ${outputPath}`, (error) => {
if (error) {
console.error('Image resize failed:', error);
}
});
}
/**
* VULNERABILITY: Command injection in backup script
*/
function backupDatabase(backupName) {
// BLOCK: Command injection - user controls backup filename
const command = `pg_dump vulnbank > /backups/${backupName}.sql`;
return execSync(command);
}
/**
* Safe version for comparison - uses spawn with array arguments
*/
const { spawn } = require('child_process');
function listFilesSafe(directory, callback) {
// This is the correct approach - no shell, array of arguments
const ls = spawn('ls', ['-la', directory]);
let output = '';
ls.stdout.on('data', (data) => {
output += data;
});
ls.on('close', (code) => {
if (code !== 0) {
callback(new Error(`Process exited with code ${code}`), null);
return;
}
callback(null, output);
});
}
module.exports = {
listFiles,
readFileHead,
resizeImage,
backupDatabase,
listFilesSafe
};