INDEX / modules /SecurityLogger.js
akra35567's picture
Update modules/SecurityLogger.js
486e814 verified
const fs = require('fs');
const path = require('path');
class SecurityLogger {
constructor(config = {}) {
this.config = config;
/**
* Detecta ambiente
* HF Spaces → filesystem root read-only
* Railway / Docker → usar volume persistente
*/
const isHF = !!process.env.SPACE_ID;
const basePath = isHF
? '/tmp/akira_data'
: process.env.DATA_PATH || path.resolve('data');
this.logsPath = path.join(basePath, 'security_logs');
this.alertsPath = path.join(this.logsPath, 'alerts.json');
this.opsPath = path.join(this.logsPath, 'operations.json');
try {
fs.mkdirSync(this.logsPath, { recursive: true });
console.log(`✅ SecurityLogger: Diretório ativo: ${this.logsPath}`);
} catch (err) {
console.error('❌ SecurityLogger: Falha ao criar diretório:', err.message);
this.logsPath = null;
}
this.operations = this.logsPath ? this._loadJSON(this.opsPath, []) : [];
this.alerts = this.logsPath ? this._loadJSON(this.alertsPath, []) : [];
console.log('✅ SecurityLogger inicializado');
}
logOperation(operacao) {
if (!this.logsPath) return;
try {
const entry = {
id: `${Date.now()}_${Math.random().toString(36).slice(2, 9)}`,
timestamp: new Date().toISOString(),
usuario: operacao.usuario || 'UNKNOWN',
tipoOperacao: operacao.tipo,
alvo: operacao.alvo,
resultado: operacao.resultado,
risco: operacao.risco || 'BAIXO',
detalhes: operacao.detalhes || {},
ipOrigem: operacao.ipOrigem || 'N/A',
duracao: operacao.duracao || 0
};
this.operations.push(entry);
this._saveJSON(this.opsPath, this.operations);
if (this._isSuspicious(entry)) {
this._createAlert(entry);
}
console.log(`📋 [SECURITY] ${entry.tipoOperacao}${entry.alvo}`);
return entry;
} catch (e) {
console.error('Erro ao logar operação:', e);
}
}
_createAlert(operacao) {
const alert = {
id: `alert_${Date.now()}`,
timestamp: new Date().toISOString(),
severidade: 'ALTO',
operacaoId: operacao.id,
usuario: operacao.usuario,
descricao: `Operação suspeita: ${operacao.tipoOperacao}`,
motivo: this._getSuspiciousReason(operacao),
status: 'NOVO'
};
this.alerts.push(alert);
this._saveJSON(this.alertsPath, this.alerts);
console.log(`🚨 [SECURITY ALERT] ${alert.descricao}`);
return alert;
}
_isSuspicious(operacao) {
const recentOps = this.operations.filter(o =>
new Date(operacao.timestamp) - new Date(o.timestamp) < 60000
);
if (recentOps.length > 5) return true;
if (operacao.tipoOperacao === 'NMAP_SCAN' && operacao.risco === 'ALTO') return true;
if (operacao.tipoOperacao === 'SQLMAP_TEST' && operacao.resultado === 'VULNERÁVEL') return true;
return false;
}
_getSuspiciousReason(operacao) {
const reasons = [];
if (operacao.tipoOperacao === 'NMAP_SCAN') reasons.push('Port scan');
if (operacao.tipoOperacao === 'SQLMAP_TEST') reasons.push('SQL Injection');
if (operacao.risco === 'CRÍTICO') reasons.push('Risco crítico');
return reasons.join(', ') || 'Atividade incomum';
}
_loadJSON(file, fallback) {
try {
if (fs.existsSync(file)) {
return JSON.parse(fs.readFileSync(file, 'utf8'));
}
} catch {}
return fallback;
}
_saveJSON(file, data) {
try {
fs.writeFileSync(file, JSON.stringify(data, null, 2));
} catch (e) {
console.error(`Erro ao salvar ${file}:`, e.message);
}
}
}
module.exports = SecurityLogger;