Skip to main content
Glama

MCP Shamash

security-scanning.test.ts8.35 kB
import { spawn } from 'child_process'; import * as path from 'path'; import * as fs from 'fs/promises'; import * as os from 'os'; describe('End-to-End Security Scanning', () => { let testProjectPath: string; beforeAll(async () => { // Create a temporary test project testProjectPath = await fs.mkdtemp(path.join(os.tmpdir(), 'shamash-test-')); // Create test files with known vulnerabilities await createTestProject(testProjectPath); }); afterAll(async () => { // Clean up test project if (testProjectPath) { await fs.rm(testProjectPath, { recursive: true, force: true }); } }); describe('Project Boundary Detection', () => { it('should detect Docker Compose configuration', async () => { // Docker compose file was created in test project const composePath = path.join(testProjectPath, 'docker-compose.yml'); const exists = await fs.access(composePath).then(() => true).catch(() => false); expect(exists).toBe(true); }); it('should detect package.json', async () => { const packagePath = path.join(testProjectPath, 'package.json'); const exists = await fs.access(packagePath).then(() => true).catch(() => false); expect(exists).toBe(true); }); }); describe('Container Isolation', () => { it('should run scanners in isolated containers', async () => { const result = await runDockerCommand([ 'run', '--rm', '--network=shamash_sandbox', '--security-opt=no-new-privileges:true', '--cap-drop=ALL', '--read-only', 'alpine:latest', 'sh', '-c', 'ping -c 1 8.8.8.8 || echo "BLOCKED"' ]); expect(result.stdout).toContain('BLOCKED'); }); it('should enforce resource limits', async () => { const result = await runDockerCommand([ 'run', '--rm', '--memory=512m', '--cpus=0.5', '--pids-limit=50', 'alpine:latest', 'sh', '-c', 'cat /sys/fs/cgroup/memory/memory.limit_in_bytes' ]); const memoryLimit = parseInt(result.stdout.trim()); expect(memoryLimit).toBeLessThanOrEqual(536870912); // 512MB }); }); describe('Security Tool Integration', () => { it('should run Semgrep SAST scan', async () => { // Build Semgrep container await runDockerCommand([ 'build', '-f', 'containers/Dockerfile.semgrep', '-t', 'shamash-semgrep', '.' ], process.cwd()); // Run scan const result = await runDockerCommand([ 'run', '--rm', '-v', `${testProjectPath}:/scan/target:ro`, '-e', 'SHAMASH_TARGET_PATH=/scan/target', '-e', 'SHAMASH_SEMGREP_CONFIG=auto', 'shamash-semgrep' ]); expect(result.exitCode).toBe(0); expect(result.stdout).toContain('Semgrep scan completed'); }, 60000); it('should run Trivy dependency scan', async () => { const result = await runDockerCommand([ 'run', '--rm', '-v', `${testProjectPath}:/scan/target:ro`, 'aquasec/trivy:latest', 'fs', '--format', 'json', '/scan/target' ]); expect(result.exitCode).toBe(0); // Parse JSON output const scanResults = JSON.parse(result.stdout); expect(scanResults.Results).toBeDefined(); }, 60000); it('should run Gitleaks secret scan', async () => { const result = await runDockerCommand([ 'run', '--rm', '-v', `${testProjectPath}:/scan/target:ro`, 'zricethezav/gitleaks:latest', 'detect', '--source', '/scan/target', '--format', 'json', '--no-git' ]); // Gitleaks exits with 1 if secrets found, 0 if none expect([0, 1]).toContain(result.exitCode); }, 60000); }); describe('Network Scanning', () => { it('should scan localhost services', async () => { // Start a test web server const server = spawn('python3', ['-m', 'http.server', '8999'], { cwd: testProjectPath, stdio: 'pipe' }); // Wait for server to start await new Promise(resolve => setTimeout(resolve, 2000)); try { const result = await runDockerCommand([ 'run', '--rm', '--network=host', 'instrumentisto/nmap:latest', '-sT', '-p', '8999', '127.0.0.1' ]); expect(result.stdout).toContain('8999/tcp open'); } finally { server.kill(); } }, 30000); it('should block external network access from scanners', async () => { const result = await runDockerCommand([ 'run', '--rm', '--network=shamash_sandbox', 'alpine:latest', 'sh', '-c', 'nc -z -w1 8.8.8.8 53 && echo "ALLOWED" || echo "BLOCKED"' ]); expect(result.stdout).toContain('BLOCKED'); }); }); describe('Audit Logging', () => { it('should create audit logs', async () => { // Run a scan operation // (This would normally be done through MCP server) const auditLogPath = path.join(testProjectPath, 'audit.log'); // Create a mock audit entry const auditEntry = { timestamp: new Date().toISOString(), operation: { type: 'test_scan', target: testProjectPath }, boundaries: { validated: true }, sessionId: 'test_session' }; await fs.writeFile(auditLogPath, JSON.stringify(auditEntry) + '\n'); const auditContent = await fs.readFile(auditLogPath, 'utf-8'); const entries = auditContent.trim().split('\n').map(line => JSON.parse(line)); expect(entries).toHaveLength(1); expect(entries[0].operation.type).toBe('test_scan'); expect(entries[0].boundaries.validated).toBe(true); }); }); }); // Helper functions async function createTestProject(projectPath: string): Promise<void> { // Create package.json with vulnerable dependency const packageJson = { name: 'test-project', version: '1.0.0', dependencies: { 'lodash': '4.17.20', // Known to have vulnerabilities in older versions 'express': '4.17.1' } }; await fs.writeFile( path.join(projectPath, 'package.json'), JSON.stringify(packageJson, null, 2) ); // Create docker-compose.yml const dockerCompose = ` version: '3.8' services: web: image: nginx:latest ports: - "8080:80" db: image: postgres:13 environment: POSTGRES_PASSWORD: password123 networks: default: driver: bridge `; await fs.writeFile( path.join(projectPath, 'docker-compose.yml'), dockerCompose ); // Create source file with security issues const sourceCode = ` // Test file with intentional security issues const express = require('express'); const app = express(); // Vulnerable: SQL injection app.get('/user/:id', (req, res) => { const query = "SELECT * FROM users WHERE id = " + req.params.id; // database.query(query); // This would be vulnerable res.send('User data'); }); // Vulnerable: XSS app.get('/search', (req, res) => { const results = "<h1>Results for: " + req.query.q + "</h1>"; res.send(results); }); // Secret in code const API_KEY = "sk_test_51234567890abcdef"; app.listen(3000); `; await fs.mkdir(path.join(projectPath, 'src'), { recursive: true }); await fs.writeFile( path.join(projectPath, 'src', 'app.js'), sourceCode ); // Create .env file with secrets const envFile = ` DATABASE_URL=postgres://user:password123@localhost:5432/db JWT_SECRET=super_secret_key_12345 API_KEY=sk_live_abcdef123456789 `; await fs.writeFile(path.join(projectPath, '.env'), envFile); } async function runDockerCommand(args: string[], cwd?: string): Promise<{ exitCode: number; stdout: string; stderr: string; }> { return new Promise((resolve, reject) => { const child = spawn('docker', args, { cwd: cwd || process.cwd(), stdio: 'pipe' }); let stdout = ''; let stderr = ''; child.stdout?.on('data', (data) => { stdout += data.toString(); }); child.stderr?.on('data', (data) => { stderr += data.toString(); }); child.on('close', (code) => { resolve({ exitCode: code || 0, stdout, stderr }); }); child.on('error', reject); }); }

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/NeoTecDigital/mcp_shamash'

If you have feedback or need assistance with the MCP directory API, please join our Discord server