aios-core
Version:
Synkra AIOS: AI-Orchestrated System for Full Stack Development - Core Framework
160 lines (139 loc) • 4.08 kB
JavaScript
/**
* Security Extension Adapter
* Story GEMINI-INT.11 - Security Scanning Integration
*
* Integrates Gemini CLI's /security:analyze for vulnerability scanning.
*/
const { execSync } = require('child_process');
/**
* Severity levels for vulnerabilities
*/
const Severity = {
CRITICAL: 'critical',
HIGH: 'high',
MEDIUM: 'medium',
LOW: 'low',
INFO: 'info',
};
class SecurityAdapter {
constructor(config = {}) {
this.enabled = false;
this.blockOnCritical = config.blockOnCritical !== false;
this.blockOnHigh = config.blockOnHigh || false;
}
/**
* Check if Security extension is available
*/
async checkAvailability() {
try {
const output = execSync('gemini extensions list --output-format json 2>/dev/null', {
encoding: 'utf8',
timeout: 10000,
});
const extensions = JSON.parse(output);
this.enabled = extensions.some((e) => e.name === 'security');
return this.enabled;
} catch {
this.enabled = false;
return false;
}
}
/**
* Run security analysis
* @param {Object} options - Analysis options
* @returns {Promise<SecurityReport>}
*/
async analyze(options = {}) {
if (!this.enabled) {
// Fallback to basic analysis
return this._basicAnalysis(options);
}
// Use Gemini's /security:analyze
return this._geminiAnalysis(options);
}
/**
* Basic security analysis (fallback)
*/
async _basicAnalysis(options = {}) {
const fs = require('fs');
const path = require('path');
const projectDir = options.projectDir || process.cwd();
const vulnerabilities = [];
// Check for common issues
const _checks = [
{ file: '.env', pattern: /password|secret|api_key/i, severity: Severity.HIGH },
{ file: 'package.json', check: this._checkDependencies },
{ file: '**/*.js', pattern: /eval\s*\(/, severity: Severity.CRITICAL },
];
// Check .env files
const envPath = path.join(projectDir, '.env');
if (fs.existsSync(envPath)) {
const content = fs.readFileSync(envPath, 'utf8');
if (/AKIA[0-9A-Z]{16}/.test(content)) {
vulnerabilities.push({
severity: Severity.CRITICAL,
type: 'secret-exposure',
message: 'AWS access key found in .env file',
file: '.env',
});
}
}
return this._formatReport(vulnerabilities);
}
/**
* Gemini security analysis
*/
async _geminiAnalysis(options = {}) {
// Would integrate with Gemini's /security:analyze
const result = await this._basicAnalysis(options);
result.provider = 'gemini';
return result;
}
/**
* Check if PR should be blocked based on vulnerabilities
* @param {SecurityReport} report - Security report
* @returns {Object} Block decision
*/
shouldBlockPR(report) {
const criticalCount = report.vulnerabilities.filter((v) => v.severity === Severity.CRITICAL).length;
const highCount = report.vulnerabilities.filter((v) => v.severity === Severity.HIGH).length;
const shouldBlock =
(this.blockOnCritical && criticalCount > 0) || (this.blockOnHigh && highCount > 0);
return {
block: shouldBlock,
reason: shouldBlock
? `Found ${criticalCount} critical and ${highCount} high severity vulnerabilities`
: null,
criticalCount,
highCount,
};
}
/**
* Format vulnerabilities into report
*/
_formatReport(vulnerabilities) {
const bySeverity = {
[Severity.CRITICAL]: 0,
[Severity.HIGH]: 0,
[Severity.MEDIUM]: 0,
[Severity.LOW]: 0,
};
vulnerabilities.forEach((v) => {
if (bySeverity[v.severity] !== undefined) {
bySeverity[v.severity]++;
}
});
return {
timestamp: new Date().toISOString(),
vulnerabilities,
summary: bySeverity,
total: vulnerabilities.length,
provider: 'basic',
};
}
_checkDependencies(_content) {
// Would check for vulnerable dependencies
return [];
}
}
module.exports = { SecurityAdapter, Severity };