aimless-security
Version:
Enhanced Runtime Application Self-Protection (RASP) and API Fuzzing Engine with advanced threat detection, behavioral analysis, and intelligent response scoring for Node.js applications
263 lines ⢠9.2 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __exportStar = (this && this.__exportStar) || function(m, exports) {
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.Logger = exports.Aimless = void 0;
const rasp_1 = require("./rasp");
const fuzzing_1 = require("./fuzzing");
const logger_1 = require("./logger");
const express_1 = require("./middleware/express");
class Aimless {
constructor(config = {}) {
this.config = config;
this.logger = new logger_1.Logger(config.logging);
this.rasp = new rasp_1.RASP(config.rasp, this.logger);
this.fuzzer = new fuzzing_1.FuzzingEngine(config.fuzzing, this.logger);
}
/**
* Get Express middleware for RASP protection
*/
middleware() {
return (0, express_1.createMiddleware)(this.config);
}
/**
* Get CSRF protection middleware
*/
csrf() {
return (0, express_1.csrfProtection)(this.config);
}
/**
* Get loading screen middleware (place BEFORE main middleware)
*/
loading() {
return (0, express_1.loadingScreen)(this.config);
}
/**
* Analyze a request for security threats
*/
analyze(request) {
return this.rasp.analyze(request);
}
/**
* Generate a CSRF token for a session
*/
generateCSRFToken(sessionId) {
return this.rasp.generateCSRFToken(sessionId);
}
/**
* Sanitize output to prevent XSS
*/
sanitize(output) {
return this.rasp.sanitizeOutput(output);
}
/**
* Fuzz test an API endpoint
*/
async fuzz(target) {
return this.fuzzer.fuzz(target);
}
/**
* Get the logger instance
*/
getLogger() {
return this.logger;
}
/**
* Quick validation helper - check if input is safe
*/
isSafe(input, context) {
const threats = this.rasp.detectInjections(input, context);
return threats.length === 0;
}
/**
* Context-aware sanitization with multiple output contexts
*/
sanitizeFor(input, context = 'html') {
// Use XSS detector's enhanced sanitization
const xssDetector = this.rasp.xssDetector;
if (xssDetector && typeof xssDetector.sanitize === 'function') {
return xssDetector.sanitize(input, context);
}
return this.rasp.sanitizeOutput(input);
}
/**
* Validate and sanitize in one call
*/
validateAndSanitize(input, context) {
const threats = this.rasp.detectInjections(input, context);
const safe = threats.length === 0;
const sanitized = this.rasp.sanitizeOutput(input);
return { safe, sanitized, threats };
}
/**
* Get IP reputation score (0-100)
*/
getIPReputation(ip) {
const anomalyDetector = this.rasp.anomalyDetector;
if (anomalyDetector && typeof anomalyDetector.getReputationScore === 'function') {
return anomalyDetector.getReputationScore(ip);
}
return 100;
}
/**
* Block or unblock an IP address
*/
setIPBlocked(ip, blocked) {
const anomalyDetector = this.rasp.anomalyDetector;
if (anomalyDetector && typeof anomalyDetector.setIPBlocked === 'function') {
anomalyDetector.setIPBlocked(ip, blocked);
}
}
/**
* Get security statistics
*/
getStats() {
const anomalyDetector = this.rasp.anomalyDetector;
const stats = {
rasp: {}
};
if (anomalyDetector && typeof anomalyDetector.getStats === 'function') {
stats.rasp = anomalyDetector.getStats();
}
return stats;
}
/**
* Get security analytics (v1.3.4 feature)
*/
getAnalytics() {
// Placeholder - returns basic stats for now
// In a full implementation, this would use SecurityAnalyticsEngine
return {
totalRequests: 0,
threatsDetected: 0,
threatsBlocked: 0,
topAttackTypes: [],
topAttackIPs: [],
requestsByHour: [],
averageResponseTime: 0,
uptime: Date.now() - this.startTime || 0
};
}
/**
* Get analytics summary text (v1.3.4 feature)
*/
getAnalyticsSummary() {
const analytics = this.getAnalytics();
return `
š Security Analytics Summary
āāāāāāāāāāāāāāāāāāāāāāāāāāāāā
Total Requests: ${analytics.totalRequests.toLocaleString()}
Threats Detected: ${analytics.threatsDetected.toLocaleString()}
Threats Blocked: ${analytics.threatsBlocked.toLocaleString()}
Average Response Time: ${analytics.averageResponseTime.toFixed(2)}ms
āāāāāāāāāāāāāāāāāāāāāāāāāāāāā
`.trim();
}
/**
* Clear security history (for testing or privacy)
*/
clearHistory(ip) {
const anomalyDetector = this.rasp.anomalyDetector;
if (anomalyDetector && typeof anomalyDetector.clearHistory === 'function') {
anomalyDetector.clearHistory(ip);
}
}
/**
* Quick-start method: protect an Express app with sensible defaults
*/
static quickProtect(trustedOrigins) {
const aimless = new Aimless({
rasp: {
enabled: true,
blockMode: true,
trustedOrigins: trustedOrigins || []
},
logging: {
level: 'info'
}
});
return {
middleware: aimless.middleware(),
csrf: aimless.csrf(),
aimless
};
}
/**
* Create a validation chain for fluent API
*/
validate(input) {
const threats = [];
let sanitized = input;
return {
against: (checks) => {
try {
// Get injection threats (SQL, NoSQL, Command, Path, XXE, SSRF)
const injectionThreats = this.rasp.detectInjections(input);
// Get XSS threats separately - only for string inputs
const xssThreats = typeof input === 'string' ? this.rasp.getXSSDetector().detect(input) : [];
const allThreats = [...injectionThreats, ...xssThreats];
if (checks.includes('all')) {
threats.push(...allThreats);
}
else {
const typeMap = {
'sql': 'sql_injection',
'nosql': 'nosql_injection',
'xss': 'xss',
'command': 'command_injection',
'path': 'path_traversal',
'xxe': 'xxe',
'ssrf': 'ssrf'
};
checks.forEach(check => {
const filtered = allThreats.filter((t) => t.type === typeMap[check]);
threats.push(...filtered);
});
}
}
catch (error) {
this.logger.error('Validation error:', error);
// On error, assume safe to not break the app
}
return {
sanitize: () => {
try {
sanitized = typeof input === 'string' ? this.rasp.sanitizeOutput(input) : input;
}
catch (error) {
this.logger.error('Sanitization error:', error);
sanitized = input; // Return original if sanitization fails
}
return {
result: () => ({ safe: threats.length === 0, sanitized, threats })
};
},
result: () => ({ safe: threats.length === 0, input, threats })
};
}
};
}
}
exports.Aimless = Aimless;
// Export everything for direct access
__exportStar(require("./types"), exports);
__exportStar(require("./rasp"), exports);
__exportStar(require("./fuzzing"), exports);
__exportStar(require("./middleware/express"), exports);
var logger_2 = require("./logger");
Object.defineProperty(exports, "Logger", { enumerable: true, get: function () { return logger_2.Logger; } });
// Default export
exports.default = Aimless;
//# sourceMappingURL=index.js.map