techprotrade's picture
Deploy ATOM FastAPI command center runtime (part 6)
383cb38 verified
Raw
History Blame Contribute Delete
5.89 kB
#!/usr/bin/env node
/**
* Proof of Concept: Verify Command Injection Fix (Issue #525)
*
* This script demonstrates that the vulnerability has been fixed.
* Original PoC: curl -X POST http://127.0.0.1:3003/sys/install \
* -H "Content-Type: application/json" \
* -d '{"packageName": "express; touch /tmp/pwned #"}'
*
* Expected behavior AFTER fix:
* - Request is rejected with 400 Bad Request (invalid package name)
* - No command execution occurs
*/
import http from 'http';
const HOST = '127.0.0.1';
const PORT = 3003;
// Test cases
const tests = [
{
name: 'Valid package name (with auth)',
path: '/sys/install',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'test-api-key'
},
body: JSON.stringify({ packageName: '@activepieces/piece-github' }),
expectedStatus: 200, // Should proceed to npm install
description: 'Should allow valid package with authentication'
},
{
name: 'Command injection: semicolon (without auth)',
path: '/sys/install',
method: 'POST',
headers: {
'Content-Type': 'application/json'
},
body: JSON.stringify({ packageName: 'express; touch /tmp/pwned #' }),
expectedStatus: 401,
description: 'Should reject without authentication'
},
{
name: 'Command injection: semicolon (with auth)',
path: '/sys/install',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'test-api-key'
},
body: JSON.stringify({ packageName: 'express; touch /tmp/pwned #' }),
expectedStatus: 400,
description: 'Should reject invalid package name even with auth'
},
{
name: 'Command injection: pipe (with auth)',
path: '/sys/install',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'test-api-key'
},
body: JSON.stringify({ packageName: 'express | cat /etc/passwd' }),
expectedStatus: 400,
description: 'Should reject pipe injection'
},
{
name: 'Command injection: backticks (with auth)',
path: '/sys/install',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'test-api-key'
},
body: JSON.stringify({ packageName: 'express`rm -rf /`' }),
expectedStatus: 400,
description: 'Should reject backtick injection'
},
{
name: 'Command injection: command substitution (with auth)',
path: '/sys/install',
method: 'POST',
headers: {
'Content-Type': 'application/json',
'X-API-Key': 'test-api-key'
},
body: JSON.stringify({ packageName: 'express$(whoami)' }),
expectedStatus: 400,
description: 'Should reject $() command substitution'
},
{
name: 'Health check (no auth required)',
path: '/health',
method: 'GET',
headers: {},
body: null,
expectedStatus: 200,
description: 'Health check should work without authentication'
}
];
async function makeRequest(test) {
return new Promise((resolve) => {
const options = {
hostname: HOST,
port: PORT,
path: test.path,
method: test.method,
headers: test.headers
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => { data += chunk; });
res.on('end', () => {
resolve({
status: res.statusCode,
body: data
});
});
});
req.on('error', (error) => {
resolve({
status: 'ERROR',
error: error.message
});
});
if (test.body) {
req.write(test.body);
}
req.end();
});
}
async function runTests() {
console.log('╔══════════════════════════════════════════════════════════════╗');
console.log('║ Security Fix Verification: Command Injection (Issue #525) ║');
console.log('╚══════════════════════════════════════════════════════════════╝\n');
console.log(`Target: http://${HOST}:${PORT}`);
console.log('Starting tests...\n');
let passed = 0;
let failed = 0;
for (const test of tests) {
const result = await makeRequest(test);
const statusMatch = result.status === test.expectedStatus;
if (statusMatch) {
passed++;
console.log(`✅ PASS: ${test.name}`);
console.log(` Expected: ${test.expectedStatus}, Got: ${result.status}`);
console.log(` ${test.description}\n`);
} else {
failed++;
console.log(`❌ FAIL: ${test.name}`);
console.log(` Expected: ${test.expectedStatus}, Got: ${result.status}`);
console.log(` ${test.description}`);
if (result.error) {
console.log(` Error: ${result.error}`);
} else {
console.log(` Response: ${result.body.substring(0, 100)}`);
}
console.log();
}
}
console.log('╔══════════════════════════════════════════════════════════════╗');
console.log(`║ Results: ${passed} passed, ${failed} failed out of ${tests.length} tests ║`);
console.log('╚══════════════════════════════════════════════════════════════╝');
if (failed === 0) {
console.log('\n✅ All security tests passed! The vulnerability has been fixed.');
process.exit(0);
} else {
console.log('\n❌ Some tests failed. The vulnerability may not be fully fixed.');
process.exit(1);
}
}
// Run tests
runTests().catch(console.error);