From 8cb5df350f1c9a267ff3788d937d47d397839e0b Mon Sep 17 00:00:00 2001 From: Ayaanshaikh12243 Date: Thu, 5 Mar 2026 23:01:11 +0530 Subject: [PATCH 1/3] ISSUE-994 --- federated/client.js | 84 ++++++++++++++++++++++++++++++++ federated/compliance.js | 31 ++++++++++++ federated/config.js | 11 +++++ federated/crypto.js | 71 +++++++++++++++++++++++++++ federated/model.js | 45 +++++++++++++++++ federated/privacy.js | 40 ++++++++++++++++ federated/server.js | 104 ++++++++++++++++++++++++++++++++++++++++ 7 files changed, 386 insertions(+) create mode 100644 federated/client.js create mode 100644 federated/compliance.js create mode 100644 federated/config.js create mode 100644 federated/crypto.js create mode 100644 federated/model.js create mode 100644 federated/privacy.js create mode 100644 federated/server.js diff --git a/federated/client.js b/federated/client.js new file mode 100644 index 00000000..990cba8b --- /dev/null +++ b/federated/client.js @@ -0,0 +1,84 @@ +// Federated Learning Client +// Handles local training, secure communication with server + +const net = require('net'); +const crypto = require('./crypto'); +const privacy = require('./privacy'); +const model = require('./model'); +const compliance = require('./compliance'); +const config = require('./config'); + +class FederatedClient { + constructor(options) { + this.serverHost = options.serverHost || 'localhost'; + this.serverPort = options.serverPort || 9000; + this.clientId = options.clientId || crypto.generateClientId(); + this.localModel = model.createModel(); + this.socket = null; + this.auditLog = []; + } + + connect() { + this.socket = net.createConnection({ host: this.serverHost, port: this.serverPort }, () => { + compliance.log('Connected to server', { serverHost: this.serverHost, serverPort: this.serverPort }); + crypto.authenticateServer(this.socket, this.clientId); + }); + this.socket.on('data', (data) => this.handleServerMessage(data)); + this.socket.on('end', () => compliance.log('Disconnected from server', {})); + } + + handleServerMessage(data) { + let message; + try { + message = crypto.decryptMessage(data); + } catch (e) { + compliance.log('Decryption failed', { error: e.message }); + return; + } + switch (message.type) { + case 'globalModel': + this.updateLocalModel(message.model); + break; + default: + compliance.log('Unknown message type', { type: message.type }); + } + } + + updateLocalModel(globalModel) { + this.localModel = model.update(this.localModel, globalModel); + compliance.log('Local model updated', {}); + } + + trainLocalModel(data) { + // Train model on local data + this.localModel = model.train(this.localModel, data); + compliance.log('Local model trained', {}); + } + + sendModelUpdate() { + // Apply privacy mechanisms + const privateModel = privacy.applyDifferentialPrivacy(this.localModel); + const encrypted = crypto.encryptMessage({ + type: 'modelUpdate', + clientId: this.clientId, + model: privateModel + }); + this.socket.write(encrypted); + compliance.log('Model update sent', {}); + } +} + +module.exports = FederatedClient; + +// If run directly, start the client +if (require.main === module) { + const client = new FederatedClient({ + serverHost: config.serverHost, + serverPort: config.serverPort, + clientId: config.clientId + }); + client.connect(); + // Example: train and send update + // client.trainLocalModel(localData); + // client.sendModelUpdate(); +} diff --git a/federated/compliance.js b/federated/compliance.js new file mode 100644 index 00000000..b0c16071 --- /dev/null +++ b/federated/compliance.js @@ -0,0 +1,31 @@ +// Compliance Logging and Audit Trail +// Tracks data access, model updates, user actions + +const fs = require('fs'); +const path = require('path'); +const LOG_FILE = path.join(__dirname, 'audit.log'); + +function log(action, details) { + const entry = { + timestamp: new Date().toISOString(), + action, + details + }; + fs.appendFileSync(LOG_FILE, JSON.stringify(entry) + '\n'); +} + +function getLogs() { + if (!fs.existsSync(LOG_FILE)) return []; + const lines = fs.readFileSync(LOG_FILE, 'utf8').split('\n').filter(Boolean); + return lines.map(line => JSON.parse(line)); +} + +function queryLogs(filterFn) { + return getLogs().filter(filterFn); +} + +module.exports = { + log, + getLogs, + queryLogs +}; diff --git a/federated/config.js b/federated/config.js new file mode 100644 index 00000000..2d604f81 --- /dev/null +++ b/federated/config.js @@ -0,0 +1,11 @@ +// Configuration and Setup Scripts +// Server/client config, environment variables + +const dotenv = require('dotenv'); +dotenv.config(); + +module.exports = { + serverPort: process.env.SERVER_PORT || 9000, + serverHost: process.env.SERVER_HOST || 'localhost', + clientId: process.env.CLIENT_ID || null +}; diff --git a/federated/crypto.js b/federated/crypto.js new file mode 100644 index 00000000..2690f788 --- /dev/null +++ b/federated/crypto.js @@ -0,0 +1,71 @@ +// Secure Communication Utilities +// Encryption, authentication, key management + +const crypto = require('crypto'); + +const ALGORITHM = 'aes-256-gcm'; +const KEY_LENGTH = 32; +const IV_LENGTH = 12; +const TAG_LENGTH = 16; + +let serverKey = crypto.randomBytes(KEY_LENGTH); +let clientKeys = new Map(); // clientId -> key + +function generateClientId() { + return crypto.randomBytes(8).toString('hex'); +} + +function generateKey() { + return crypto.randomBytes(KEY_LENGTH); +} + +function encryptMessage(message, key = serverKey) { + const iv = crypto.randomBytes(IV_LENGTH); + const cipher = crypto.createCipheriv(ALGORITHM, key, iv); + let encrypted = cipher.update(JSON.stringify(message), 'utf8'); + encrypted = Buffer.concat([encrypted, cipher.final()]); + const tag = cipher.getAuthTag(); + return Buffer.concat([iv, tag, encrypted]); +} + +function decryptMessage(buffer, key = serverKey) { + const iv = buffer.slice(0, IV_LENGTH); + const tag = buffer.slice(IV_LENGTH, IV_LENGTH + TAG_LENGTH); + const encrypted = buffer.slice(IV_LENGTH + TAG_LENGTH); + const decipher = crypto.createDecipheriv(ALGORITHM, key, iv); + decipher.setAuthTag(tag); + let decrypted = decipher.update(encrypted); + decrypted = Buffer.concat([decrypted, decipher.final()]); + return JSON.parse(decrypted.toString('utf8')); +} + +function authenticateClient(socket, callback) { + // Simple handshake: client sends ID, server stores key + socket.once('data', (data) => { + const clientId = data.toString('utf8'); + const key = generateKey(); + clientKeys.set(clientId, key); + socket.write(key); + callback(clientId); + }); +} + +function authenticateServer(socket, clientId) { + // Client sends ID, receives key + socket.write(clientId); + socket.once('data', (data) => { + // Store received key for future communication + clientKeys.set(clientId, data); + }); +} + +module.exports = { + generateClientId, + generateKey, + encryptMessage, + decryptMessage, + authenticateClient, + authenticateServer, + clientKeys, + serverKey +}; diff --git a/federated/model.js b/federated/model.js new file mode 100644 index 00000000..e76c123a --- /dev/null +++ b/federated/model.js @@ -0,0 +1,45 @@ +// Model Definition and Training Logic +// Financial analytics model, local training, serialization + +function createModel() { + // Simple linear regression model: weights and bias + return { + weight: Math.random(), + bias: Math.random() + }; +} + +function train(model, data) { + // Dummy training: update weights based on data + // data: [{x, y}, ...] + let lr = 0.01; + for (const point of data) { + let pred = model.weight * point.x + model.bias; + let error = point.y - pred; + model.weight += lr * error * point.x; + model.bias += lr * error; + } + return model; +} + +function aggregate(globalModel, clientModel) { + // Simple averaging + return { + weight: (globalModel.weight + clientModel.weight) / 2, + bias: (globalModel.bias + clientModel.bias) / 2 + }; +} + +function update(localModel, globalModel) { + // Update local model with global model + localModel.weight = globalModel.weight; + localModel.bias = globalModel.bias; + return localModel; +} + +module.exports = { + createModel, + train, + aggregate, + update +}; diff --git a/federated/privacy.js b/federated/privacy.js new file mode 100644 index 00000000..3b83e54c --- /dev/null +++ b/federated/privacy.js @@ -0,0 +1,40 @@ +// Privacy-Preserving Mechanisms +// Differential privacy, secure aggregation + +function applyDifferentialPrivacy(model) { + // Add Gaussian noise to model weights for privacy + const noiseLevel = 0.01; + let noisyModel = {}; + for (const key in model) { + if (typeof model[key] === 'number') { + noisyModel[key] = model[key] + gaussianNoise(0, noiseLevel); + } else { + noisyModel[key] = model[key]; + } + } + return noisyModel; +} + +function gaussianNoise(mean, std) { + // Box-Muller transform + let u = 0, v = 0; + while(u === 0) u = Math.random(); + while(v === 0) v = Math.random(); + return std * Math.sqrt(-2.0 * Math.log(u)) * Math.cos(2.0 * Math.PI * v) + mean; +} + +function secureAggregate(models) { + // Simple averaging for demonstration + if (models.length === 0) return {}; + let agg = {}; + let keys = Object.keys(models[0]); + for (const key of keys) { + agg[key] = models.reduce((sum, m) => sum + (m[key] || 0), 0) / models.length; + } + return agg; +} + +module.exports = { + applyDifferentialPrivacy, + secureAggregate +}; diff --git a/federated/server.js b/federated/server.js new file mode 100644 index 00000000..d4feb176 --- /dev/null +++ b/federated/server.js @@ -0,0 +1,104 @@ +// Federated Learning Server +// Orchestrates rounds, aggregates models, manages clients + +const net = require('net'); +const crypto = require('./crypto'); +const privacy = require('./privacy'); +const model = require('./model'); +const compliance = require('./compliance'); +const config = require('./config'); + +class FederatedServer { + constructor(options) { + this.port = options.port || 9000; + this.clients = new Map(); // clientId -> socket + this.globalModel = model.createModel(); + this.round = 0; + this.auditLog = []; + this.server = net.createServer(this.handleConnection.bind(this)); + } + + start() { + this.server.listen(this.port, () => { + console.log(`Federated server listening on port ${this.port}`); + compliance.log('Server started', { port: this.port }); + }); + } + + handleConnection(socket) { + socket.on('data', (data) => this.handleClientMessage(socket, data)); + socket.on('end', () => this.handleClientDisconnect(socket)); + // Authentication handshake + crypto.authenticateClient(socket, (clientId) => { + this.clients.set(clientId, socket); + compliance.log('Client connected', { clientId }); + }); + } + + handleClientMessage(socket, data) { + // Decrypt and parse message + let message; + try { + message = crypto.decryptMessage(data); + } catch (e) { + compliance.log('Decryption failed', { error: e.message }); + return; + } + // Handle message types: model update, request global model, etc. + switch (message.type) { + case 'modelUpdate': + this.handleModelUpdate(socket, message); + break; + case 'requestGlobalModel': + this.sendGlobalModel(socket); + break; + default: + compliance.log('Unknown message type', { type: message.type }); + } + } + + handleModelUpdate(socket, message) { + // Apply privacy-preserving aggregation + const clientModel = privacy.applyDifferentialPrivacy(message.model); + this.aggregateModel(clientModel); + compliance.log('Model update received', { clientId: message.clientId }); + // Optionally send updated global model back + this.sendGlobalModel(socket); + } + + aggregateModel(clientModel) { + // Aggregate client model into global model + this.globalModel = model.aggregate(this.globalModel, clientModel); + this.round++; + compliance.log('Model aggregated', { round: this.round }); + } + + sendGlobalModel(socket) { + const encrypted = crypto.encryptMessage({ + type: 'globalModel', + model: this.globalModel, + round: this.round + }); + socket.write(encrypted); + compliance.log('Global model sent', {}); + } + + handleClientDisconnect(socket) { + // Remove client from map + for (const [clientId, s] of this.clients.entries()) { + if (s === socket) { + this.clients.delete(clientId); + compliance.log('Client disconnected', { clientId }); + break; + } + } + } +} + +module.exports = FederatedServer; + +// If run directly, start the server +if (require.main === module) { + const server = new FederatedServer({ port: config.serverPort }); + server.start(); +} From b619a024b6f203d30b53f7b16be4ddb71a09ba52 Mon Sep 17 00:00:00 2001 From: Ayaanshaikh12243 Date: Thu, 5 Mar 2026 23:09:23 +0530 Subject: [PATCH 2/3] ISSUE-995done --- adaptive-rate-limit.js | 65 ++++++++++++++++++++++++++++++++++++++++ adaptive/README.md | 40 +++++++++++++++++++++++++ adaptive/README_API.md | 34 +++++++++++++++++++++ adaptive/admin.js | 36 ++++++++++++++++++++++ adaptive/alerts.js | 24 +++++++++++++++ adaptive/analytics.js | 62 ++++++++++++++++++++++++++++++++++++++ adaptive/api.js | 26 ++++++++++++++++ adaptive/config.js | 7 +++++ adaptive/dashboard.js | 29 ++++++++++++++++++ adaptive/docs.md | 40 +++++++++++++++++++++++++ adaptive/examples.js | 19 ++++++++++++ adaptive/logger.js | 29 ++++++++++++++++++ adaptive/ml-models.js | 21 +++++++++++++ adaptive/ml-risk.js | 35 ++++++++++++++++++++++ adaptive/monitor.js | 24 +++++++++++++++ adaptive/quota.js | 28 +++++++++++++++++ adaptive/rate-limiter.js | 41 +++++++++++++++++++++++++ adaptive/report.js | 23 ++++++++++++++ adaptive/stats.js | 32 ++++++++++++++++++++ adaptive/test.js | 32 ++++++++++++++++++++ adaptive/types.d.ts | 29 ++++++++++++++++++ routes/compliance.js | 15 ++++++++++ 22 files changed, 691 insertions(+) create mode 100644 adaptive-rate-limit.js create mode 100644 adaptive/README.md create mode 100644 adaptive/README_API.md create mode 100644 adaptive/admin.js create mode 100644 adaptive/alerts.js create mode 100644 adaptive/analytics.js create mode 100644 adaptive/api.js create mode 100644 adaptive/config.js create mode 100644 adaptive/dashboard.js create mode 100644 adaptive/docs.md create mode 100644 adaptive/examples.js create mode 100644 adaptive/logger.js create mode 100644 adaptive/ml-models.js create mode 100644 adaptive/ml-risk.js create mode 100644 adaptive/monitor.js create mode 100644 adaptive/quota.js create mode 100644 adaptive/rate-limiter.js create mode 100644 adaptive/report.js create mode 100644 adaptive/stats.js create mode 100644 adaptive/test.js create mode 100644 adaptive/types.d.ts diff --git a/adaptive-rate-limit.js b/adaptive-rate-limit.js new file mode 100644 index 00000000..bf94ff46 --- /dev/null +++ b/adaptive-rate-limit.js @@ -0,0 +1,65 @@ +// Adaptive Rate Limiting for API Abuse Prevention +// Issue #995 +// Dynamically adjusts quotas using real-time analytics and ML risk scoring + +const analytics = require('./analytics-dashboard'); // Example analytics module +const anomalyDetector = require('./anomaly-detector'); // Example ML module + +class AdaptiveRateLimiter { + constructor(options = {}) { + this.defaultLimit = options.defaultLimit || 1000; // requests per hour + this.userLimits = new Map(); // userId -> limit + this.usage = new Map(); // userId -> [timestamps] + this.riskScores = new Map(); // userId -> score + } + + recordRequest(userId) { + const now = Date.now(); + if (!this.usage.has(userId)) { + this.usage.set(userId, []); + } + this.usage.get(userId).push(now); + this.updateRiskScore(userId); + this.adjustLimit(userId); + } + + isAllowed(userId) { + const limit = this.userLimits.get(userId) || this.defaultLimit; + const windowMs = 60 * 60 * 1000; // 1 hour + const now = Date.now(); + const timestamps = (this.usage.get(userId) || []).filter(ts => now - ts < windowMs); + this.usage.set(userId, timestamps); + return timestamps.length < limit; + } + + updateRiskScore(userId) { + // Use analytics and ML to score risk + const usageStats = analytics.getUserStats(userId); + const anomaly = anomalyDetector.detect(usageStats); + let score = 0; + if (anomaly.isAnomalous) score += 50; + score += usageStats.failedLogins * 2; + score += usageStats.requestsPerMinute; + this.riskScores.set(userId, score); + } + + adjustLimit(userId) { + // Lower limit for high risk, raise for low risk + const score = this.riskScores.get(userId) || 0; + let limit = this.defaultLimit; + if (score > 80) limit = Math.max(100, this.defaultLimit * 0.1); + else if (score > 50) limit = Math.max(300, this.defaultLimit * 0.3); + else if (score < 10) limit = this.defaultLimit * 2; + this.userLimits.set(userId, Math.floor(limit)); + } + + getUserLimit(userId) { + return this.userLimits.get(userId) || this.defaultLimit; + } + + getUserRiskScore(userId) { + return this.riskScores.get(userId) || 0; + } +} + +module.exports = AdaptiveRateLimiter; diff --git a/adaptive/README.md b/adaptive/README.md new file mode 100644 index 00000000..9179fd34 --- /dev/null +++ b/adaptive/README.md @@ -0,0 +1,40 @@ +# Adaptive Rate Limiting System + +This module implements adaptive rate limiting for API abuse prevention using real-time analytics and machine learning risk scoring. It dynamically adjusts user quotas based on behavior and risk profiles. + +## Features +- Real-time analytics for API usage +- ML-based risk scoring +- Dynamic quota adjustment +- Logging and monitoring +- Easy integration with Express API routes + +## File Structure +- `analytics.js`: Tracks requests, user actions, endpoint stats +- `ml-risk.js`: Scores user risk using ML/anomaly detection +- `quota.js`: Adjusts user quotas based on risk +- `logger.js`: Logs rate limiting events and statistics +- `rate-limiter.js`: Orchestrates all modules for adaptive rate limiting + +## Usage Example +```js +const rateLimiter = require('./adaptive/rate-limiter'); + +function rateLimitMiddleware(req, res, next) { + const userId = req.body.userId || req.ip; + const endpoint = req.path; + rateLimiter.recordRequest(userId, endpoint, 'success'); + if (!rateLimiter.isAllowed(userId)) { + return res.status(429).json({ success: false, error: 'Rate limit exceeded', limit: rateLimiter.getUserLimit(userId), riskScore: rateLimiter.getUserRiskScore(userId) }); + } + next(); +} +``` + +## Extensibility +- Add more sophisticated ML models in `ml-risk.js` +- Integrate with external monitoring tools via `logger.js` +- Customize quota logic in `quota.js` + +## Compliance +All events are logged for audit and compliance purposes. diff --git a/adaptive/README_API.md b/adaptive/README_API.md new file mode 100644 index 00000000..e8d18be9 --- /dev/null +++ b/adaptive/README_API.md @@ -0,0 +1,34 @@ +# Adaptive Rate Limiting API Reference + +## Endpoints + +### POST /test +- Description: Test endpoint for rate limiting +- Request Body: `{ "userId": "string" }` +- Response: `{ success: true, message: "Request allowed!" }` or `{ success: false, error: "Rate limit exceeded", limit, riskScore }` + +## Middleware +```js +const rateLimiter = require('./adaptive/rate-limiter'); +function rateLimitMiddleware(req, res, next) { + const userId = req.body.userId || req.ip; + const endpoint = req.path; + rateLimiter.recordRequest(userId, endpoint, 'success'); + if (!rateLimiter.isAllowed(userId)) { + return res.status(429).json({ success: false, error: 'Rate limit exceeded', limit: rateLimiter.getUserLimit(userId), riskScore: rateLimiter.getUserRiskScore(userId) }); + } + next(); +} +``` + +## Dashboard +- Run `dashboard.js` to view stats + +## Alerts +- High risk users trigger alerts in `monitor.js` and `alerts.js` + +## Admin +- Use `admin.js` for manual overrides + +## Compliance +- All events logged in `rate-limit.log` for audit diff --git a/adaptive/admin.js b/adaptive/admin.js new file mode 100644 index 00000000..f1044ba8 --- /dev/null +++ b/adaptive/admin.js @@ -0,0 +1,36 @@ +// Admin utility for Adaptive Rate Limiting +// Allows manual override of quotas and risk scores + +const quota = require('./quota'); +const mlRisk = require('./ml-risk'); + +function setUserLimit(userId, limit) { + quota.userLimits.set(userId, limit); + console.log(`Set quota for ${userId} to ${limit}`); +} + +function setUserRiskScore(userId, score) { + mlRisk.userScores.set(userId, score); + console.log(`Set risk score for ${userId} to ${score}`); +} + +function printAllLimits() { + console.log('User Quotas:'); + for (const [userId, limit] of quota.getAllLimits()) { + console.log(`${userId}: ${limit}`); + } +} + +function printAllScores() { + console.log('User Risk Scores:'); + for (const [userId, score] of mlRisk.getAllScores()) { + console.log(`${userId}: ${score}`); + } +} + +module.exports = { + setUserLimit, + setUserRiskScore, + printAllLimits, + printAllScores +}; diff --git a/adaptive/alerts.js b/adaptive/alerts.js new file mode 100644 index 00000000..3c01f47f --- /dev/null +++ b/adaptive/alerts.js @@ -0,0 +1,24 @@ +// Alerting utility for Adaptive Rate Limiting +// Sends notifications for high risk events + +const logger = require('./logger'); +const config = require('./config'); + +function checkAlerts() { + const logs = logger.getLogs(); + logs.forEach(entry => { + if (entry.event === 'request' && entry.details.riskScore > config.alertRiskThreshold) { + sendAlert(entry.details); + } + }); +} + +function sendAlert(details) { + // Placeholder: send email, SMS, webhook, etc. + console.log('ALERT: High risk user detected!', details); +} + +module.exports = { + checkAlerts, + sendAlert +}; diff --git a/adaptive/analytics.js b/adaptive/analytics.js new file mode 100644 index 00000000..a2071e59 --- /dev/null +++ b/adaptive/analytics.js @@ -0,0 +1,62 @@ +// Real-Time Analytics for API Usage +// Tracks requests, user actions, endpoint stats + +class Analytics { + constructor() { + this.userStats = new Map(); // userId -> stats + this.endpointStats = new Map(); // endpoint -> stats + } + + recordRequest(userId, endpoint, status, timestamp = Date.now()) { + if (!this.userStats.has(userId)) { + this.userStats.set(userId, { + requests: 0, + failedLogins: 0, + requestsPerMinute: 0, + lastMinute: [], + endpoints: {} + }); + } + const stats = this.userStats.get(userId); + stats.requests++; + stats.lastMinute.push(timestamp); + stats.lastMinute = stats.lastMinute.filter(ts => timestamp - ts < 60000); + stats.requestsPerMinute = stats.lastMinute.length; + if (!stats.endpoints[endpoint]) stats.endpoints[endpoint] = 0; + stats.endpoints[endpoint]++; + if (status === 'fail') stats.failedLogins++; + this.userStats.set(userId, stats); + + // Endpoint stats + if (!this.endpointStats.has(endpoint)) { + this.endpointStats.set(endpoint, { requests: 0, users: new Set() }); + } + const epStats = this.endpointStats.get(endpoint); + epStats.requests++; + epStats.users.add(userId); + this.endpointStats.set(endpoint, epStats); + } + + getUserStats(userId) { + return this.userStats.get(userId) || { + requests: 0, + failedLogins: 0, + requestsPerMinute: 0, + endpoints: {} + }; + } + + getEndpointStats(endpoint) { + return this.endpointStats.get(endpoint) || { requests: 0, users: new Set() }; + } + + getAllUserStats() { + return Array.from(this.userStats.entries()); + } + + getAllEndpointStats() { + return Array.from(this.endpointStats.entries()); + } +} + +module.exports = new Analytics(); diff --git a/adaptive/api.js b/adaptive/api.js new file mode 100644 index 00000000..35c1e3cb --- /dev/null +++ b/adaptive/api.js @@ -0,0 +1,26 @@ +// Adaptive Rate Limiting API Integration Example +const express = require('express'); +const app = express(); +const rateLimiter = require('./rate-limiter'); + +app.use(express.json()); + +function rateLimitMiddleware(req, res, next) { + const userId = req.body.userId || req.ip; + const endpoint = req.path; + rateLimiter.recordRequest(userId, endpoint, 'success'); + if (!rateLimiter.isAllowed(userId)) { + return res.status(429).json({ success: false, error: 'Rate limit exceeded', limit: rateLimiter.getUserLimit(userId), riskScore: rateLimiter.getUserRiskScore(userId) }); + } + next(); +} + +app.use(rateLimitMiddleware); + +app.post('/test', (req, res) => { + res.json({ success: true, message: 'Request allowed!' }); +}); + +app.listen(4000, () => { + console.log('Adaptive Rate Limiting API running on port 4000'); +}); diff --git a/adaptive/config.js b/adaptive/config.js new file mode 100644 index 00000000..2b36e310 --- /dev/null +++ b/adaptive/config.js @@ -0,0 +1,7 @@ +// Configuration for Adaptive Rate Limiting +module.exports = { + defaultLimit: 1000, + alertRiskThreshold: 100, + logFile: 'rate-limit.log', + dashboardPort: 4001 +}; diff --git a/adaptive/dashboard.js b/adaptive/dashboard.js new file mode 100644 index 00000000..9d95ef87 --- /dev/null +++ b/adaptive/dashboard.js @@ -0,0 +1,29 @@ +// Adaptive Rate Limiting Dashboard (CLI) +// Displays user stats, risk scores, quotas, and logs + +const analytics = require('./analytics'); +const mlRisk = require('./ml-risk'); +const quota = require('./quota'); +const logger = require('./logger'); + +function printDashboard() { + console.log('--- Adaptive Rate Limiting Dashboard ---'); + console.log('User Stats:'); + for (const [userId, stats] of analytics.getAllUserStats()) { + console.log(`User: ${userId}`); + console.log(' Requests:', stats.requests); + console.log(' Requests/min:', stats.requestsPerMinute); + console.log(' Endpoints:', Object.keys(stats.endpoints)); + console.log(' Failed Logins:', stats.failedLogins); + console.log(' Risk Score:', mlRisk.getUserScore(userId)); + console.log(' Quota:', quota.getUserLimit(userId)); + console.log('---'); + } + console.log('Recent Logs:'); + const logs = logger.getLogs().slice(-10); + for (const log of logs) { + console.log(log); + } +} + +printDashboard(); diff --git a/adaptive/docs.md b/adaptive/docs.md new file mode 100644 index 00000000..6f72e181 --- /dev/null +++ b/adaptive/docs.md @@ -0,0 +1,40 @@ +# Adaptive Rate Limiting Documentation + +## Overview +Adaptive rate limiting prevents API abuse by dynamically adjusting quotas based on user behavior and risk profiles. It uses real-time analytics and machine learning to detect anomalies and enforce limits. + +## Modules +- **analytics.js**: Tracks API usage, user actions, endpoint stats +- **ml-risk.js**: Scores user risk using ML/anomaly detection +- **quota.js**: Adjusts quotas based on risk +- **logger.js**: Logs events for monitoring and compliance +- **rate-limiter.js**: Orchestrates all modules + +## Integration +Add the middleware to your Express routes: +```js +const rateLimiter = require('./adaptive/rate-limiter'); +function rateLimitMiddleware(req, res, next) { + const userId = req.body.userId || req.ip; + const endpoint = req.path; + rateLimiter.recordRequest(userId, endpoint, 'success'); + if (!rateLimiter.isAllowed(userId)) { + return res.status(429).json({ success: false, error: 'Rate limit exceeded', limit: rateLimiter.getUserLimit(userId), riskScore: rateLimiter.getUserRiskScore(userId) }); + } + next(); +} +``` + +## Dashboard +Run `dashboard.js` to view user stats, risk scores, quotas, and logs. + +## Testing +Run `test.js` for a basic test suite. + +## Extending +- Enhance ML logic in `ml-risk.js` +- Integrate external monitoring in `logger.js` +- Customize quota logic in `quota.js` + +## Compliance +All rate limiting events are logged for audit and compliance. diff --git a/adaptive/examples.js b/adaptive/examples.js new file mode 100644 index 00000000..4c6b6065 --- /dev/null +++ b/adaptive/examples.js @@ -0,0 +1,19 @@ +// Example usage scenarios for Adaptive Rate Limiting +const rateLimiter = require('./rate-limiter'); + +function simulateScenario(userId, endpoint, actions) { + actions.forEach(action => { + rateLimiter.recordRequest(userId, endpoint, action.status); + const allowed = rateLimiter.isAllowed(userId); + console.log(`User: ${userId}, Endpoint: ${endpoint}, Status: ${action.status}, Allowed: ${allowed}, Limit: ${rateLimiter.getUserLimit(userId)}, Risk: ${rateLimiter.getUserRiskScore(userId)}`); + }); +} + +// Scenario 1: Normal user +simulateScenario('normalUser', '/gdpr', Array(20).fill({ status: 'success' })); + +// Scenario 2: Abusive user +simulateScenario('abuser', '/pci-dss', Array(1200).fill({ status: 'success' })); + +// Scenario 3: User with failed logins +simulateScenario('suspiciousUser', '/sox', Array(10).fill({ status: 'fail' })); diff --git a/adaptive/logger.js b/adaptive/logger.js new file mode 100644 index 00000000..cb332a0e --- /dev/null +++ b/adaptive/logger.js @@ -0,0 +1,29 @@ +// Logging and Monitoring for Rate Limiting +// Tracks events, alerts, and statistics + +const fs = require('fs'); +const path = require('path'); +const LOG_FILE = path.join(__dirname, 'rate-limit.log'); + +class RateLimitLogger { + log(event, details) { + const entry = { + timestamp: new Date().toISOString(), + event, + details + }; + fs.appendFileSync(LOG_FILE, JSON.stringify(entry) + '\n'); + } + + getLogs() { + if (!fs.existsSync(LOG_FILE)) return []; + const lines = fs.readFileSync(LOG_FILE, 'utf8').split('\n').filter(Boolean); + return lines.map(line => JSON.parse(line)); + } + + queryLogs(filterFn) { + return this.getLogs().filter(filterFn); + } +} + +module.exports = new RateLimitLogger(); diff --git a/adaptive/ml-models.js b/adaptive/ml-models.js new file mode 100644 index 00000000..be23ebb2 --- /dev/null +++ b/adaptive/ml-models.js @@ -0,0 +1,21 @@ +// Placeholder for advanced ML models for risk scoring +// Extend with real anomaly detection, clustering, etc. + +class AdvancedMLModels { + static anomalyDetection(userStats) { + // Example: Z-score anomaly detection + const mean = 100; + const std = 20; + const z = (userStats.requests - mean) / std; + return Math.abs(z) > 2; + } + + static clustering(userStats) { + // Example: Dummy cluster assignment + if (userStats.requestsPerMinute > 50) return 'abuser'; + if (userStats.failedLogins > 10) return 'suspicious'; + return 'normal'; + } +} + +module.exports = AdvancedMLModels; diff --git a/adaptive/ml-risk.js b/adaptive/ml-risk.js new file mode 100644 index 00000000..1999dcc4 --- /dev/null +++ b/adaptive/ml-risk.js @@ -0,0 +1,35 @@ +// ML-Based Risk Scoring for API Abuse +// Uses simple anomaly detection and scoring + +class MLRiskScorer { + constructor() { + this.userScores = new Map(); // userId -> score + } + + scoreUser(userStats) { + // Example: basic scoring logic + let score = 0; + score += userStats.failedLogins * 5; + score += userStats.requestsPerMinute * 2; + score += Object.keys(userStats.endpoints).length; + if (userStats.requests > 1000) score += 20; + if (userStats.requestsPerMinute > 50) score += 50; + return score; + } + + updateUserScore(userId, userStats) { + const score = this.scoreUser(userStats); + this.userScores.set(userId, score); + return score; + } + + getUserScore(userId) { + return this.userScores.get(userId) || 0; + } + + getAllScores() { + return Array.from(this.userScores.entries()); + } +} + +module.exports = new MLRiskScorer(); diff --git a/adaptive/monitor.js b/adaptive/monitor.js new file mode 100644 index 00000000..3a3fbbc9 --- /dev/null +++ b/adaptive/monitor.js @@ -0,0 +1,24 @@ +// Monitoring utility for Adaptive Rate Limiting +// Watches log file for alerts and anomalies + +const fs = require('fs'); +const path = require('path'); +const LOG_FILE = path.join(__dirname, 'rate-limit.log'); + +function watchLogs() { + fs.watchFile(LOG_FILE, { interval: 1000 }, (curr, prev) => { + if (curr.mtime !== prev.mtime) { + const logs = fs.readFileSync(LOG_FILE, 'utf8').split('\n').filter(Boolean); + const lastLog = logs[logs.length - 1]; + if (lastLog) { + const entry = JSON.parse(lastLog); + if (entry.event === 'request' && entry.details.riskScore > 100) { + console.log('ALERT: High risk user detected:', entry.details); + } + } + } + }); + console.log('Monitoring rate-limit.log for alerts...'); +} + +watchLogs(); diff --git a/adaptive/quota.js b/adaptive/quota.js new file mode 100644 index 00000000..2574f8aa --- /dev/null +++ b/adaptive/quota.js @@ -0,0 +1,28 @@ +// Dynamic Quota Adjustment +// Adjusts user quotas based on risk score + +class QuotaManager { + constructor(defaultLimit = 1000) { + this.defaultLimit = defaultLimit; + this.userLimits = new Map(); // userId -> limit + } + + adjustLimit(userId, riskScore) { + let limit = this.defaultLimit; + if (riskScore > 100) limit = Math.max(50, this.defaultLimit * 0.05); + else if (riskScore > 50) limit = Math.max(200, this.defaultLimit * 0.2); + else if (riskScore < 10) limit = this.defaultLimit * 2; + this.userLimits.set(userId, Math.floor(limit)); + return limit; + } + + getUserLimit(userId) { + return this.userLimits.get(userId) || this.defaultLimit; + } + + getAllLimits() { + return Array.from(this.userLimits.entries()); + } +} + +module.exports = new QuotaManager(); diff --git a/adaptive/rate-limiter.js b/adaptive/rate-limiter.js new file mode 100644 index 00000000..7ed4aba8 --- /dev/null +++ b/adaptive/rate-limiter.js @@ -0,0 +1,41 @@ +// Adaptive Rate Limiter Orchestrator +// Integrates analytics, ML risk scoring, quota management, and logging + +const analytics = require('./analytics'); +const mlRisk = require('./ml-risk'); +const quota = require('./quota'); +const logger = require('./logger'); + +class AdaptiveRateLimiter { + constructor(options = {}) { + this.defaultLimit = options.defaultLimit || 1000; + } + + recordRequest(userId, endpoint, status = 'success') { + analytics.recordRequest(userId, endpoint, status); + const userStats = analytics.getUserStats(userId); + const riskScore = mlRisk.updateUserScore(userId, userStats); + quota.adjustLimit(userId, riskScore); + logger.log('request', { userId, endpoint, status, riskScore, limit: quota.getUserLimit(userId) }); + } + + isAllowed(userId) { + const limit = quota.getUserLimit(userId); + const userStats = analytics.getUserStats(userId); + return userStats.requests < limit; + } + + getUserLimit(userId) { + return quota.getUserLimit(userId); + } + + getUserRiskScore(userId) { + return mlRisk.getUserScore(userId); + } + + getLogs() { + return logger.getLogs(); + } +} + +module.exports = new AdaptiveRateLimiter(); diff --git a/adaptive/report.js b/adaptive/report.js new file mode 100644 index 00000000..b343210d --- /dev/null +++ b/adaptive/report.js @@ -0,0 +1,23 @@ +// Report generator for Adaptive Rate Limiting +// Creates usage, risk, and quota reports for compliance + +const stats = require('./stats'); +const logger = require('./logger'); +const fs = require('fs'); +const path = require('path'); + +function generateReport(filePath = 'adaptive-rate-report.json') { + const summary = stats.getSummary(); + const logs = logger.getLogs(); + const report = { + generatedAt: new Date().toISOString(), + summary, + logs + }; + fs.writeFileSync(path.join(__dirname, filePath), JSON.stringify(report, null, 2)); + console.log('Report generated:', filePath); +} + +module.exports = { + generateReport +}; diff --git a/adaptive/stats.js b/adaptive/stats.js new file mode 100644 index 00000000..d6568ab2 --- /dev/null +++ b/adaptive/stats.js @@ -0,0 +1,32 @@ +// Statistics utility for Adaptive Rate Limiting +// Aggregates and reports usage, risk, and quota stats + +const analytics = require('./analytics'); +const mlRisk = require('./ml-risk'); +const quota = require('./quota'); + +function getSummary() { + const users = analytics.getAllUserStats().map(([userId, stats]) => ({ + userId, + requests: stats.requests, + requestsPerMinute: stats.requestsPerMinute, + failedLogins: stats.failedLogins, + endpoints: Object.keys(stats.endpoints), + riskScore: mlRisk.getUserScore(userId), + quota: quota.getUserLimit(userId) + })); + return users; +} + +function printSummary() { + const summary = getSummary(); + console.log('--- Adaptive Rate Limiting Summary ---'); + summary.forEach(user => { + console.log(user); + }); +} + +module.exports = { + getSummary, + printSummary +}; diff --git a/adaptive/test.js b/adaptive/test.js new file mode 100644 index 00000000..a91588e5 --- /dev/null +++ b/adaptive/test.js @@ -0,0 +1,32 @@ +// Test suite for Adaptive Rate Limiting +const rateLimiter = require('./rate-limiter'); + +function simulateRequests(userId, endpoint, count) { + for (let i = 0; i < count; i++) { + rateLimiter.recordRequest(userId, endpoint, 'success'); + } + return rateLimiter.isAllowed(userId); +} + +function runTests() { + console.log('Test: Low risk user should have high quota'); + simulateRequests('user1', '/gdpr', 10); + console.log('Limit:', rateLimiter.getUserLimit('user1')); + console.log('Risk:', rateLimiter.getUserRiskScore('user1')); + + console.log('Test: High risk user should have low quota'); + for (let i = 0; i < 2000; i++) { + rateLimiter.recordRequest('user2', '/pci-dss', 'success'); + } + console.log('Limit:', rateLimiter.getUserLimit('user2')); + console.log('Risk:', rateLimiter.getUserRiskScore('user2')); + + console.log('Test: Rate limiting enforcement'); + let allowed = simulateRequests('user2', '/pci-dss', 100); + console.log('Allowed after 100 more:', allowed); + + console.log('Test: Logging output'); + console.log(rateLimiter.getLogs().slice(-5)); +} + +runTests(); diff --git a/adaptive/types.d.ts b/adaptive/types.d.ts new file mode 100644 index 00000000..e3b29072 --- /dev/null +++ b/adaptive/types.d.ts @@ -0,0 +1,29 @@ +// Type definitions for Adaptive Rate Limiting + +/** + * User statistics tracked by analytics + */ +interface UserStats { + requests: number; + failedLogins: number; + requestsPerMinute: number; + endpoints: { [endpoint: string]: number }; + lastMinute: number[]; +} + +/** + * Endpoint statistics + */ +interface EndpointStats { + requests: number; + users: Set; +} + +/** + * Log entry for rate limiting events + */ +interface RateLimitLogEntry { + timestamp: string; + event: string; + details: any; +} diff --git a/routes/compliance.js b/routes/compliance.js index f31fe377..5c5af8ae 100644 --- a/routes/compliance.js +++ b/routes/compliance.js @@ -4,6 +4,21 @@ const router = express.Router(); const reportGenerator = require('../compliance/reportGenerator'); const scheduler = require('../compliance/scheduler'); const submissionService = require('../compliance/submissionService'); +const rateLimiter = require('../adaptive/rate-limiter'); + +function rateLimitMiddleware(req, res, next) { + const userId = req.body.userId || req.ip; + const endpoint = req.path; + // Assume status is success for initial request, can be extended for error handling + rateLimiter.recordRequest(userId, endpoint, 'success'); + if (!rateLimiter.isAllowed(userId)) { + return res.status(429).json({ success: false, error: 'Rate limit exceeded', limit: rateLimiter.getUserLimit(userId), riskScore: rateLimiter.getUserRiskScore(userId) }); + } + next(); +} + +// Apply rate limiting to all compliance routes +router.use(rateLimitMiddleware); // Generate GDPR report router.post('/gdpr', async (req, res) => { From 05b52da33b25868d72f81405d8d5cbcf0d1af575 Mon Sep 17 00:00:00 2001 From: Ayaanshaikh12243 Date: Thu, 5 Mar 2026 23:18:18 +0530 Subject: [PATCH 3/3] done --- insider/README.md | 37 ++++++++++++++++ insider/activity-monitor.js | 49 +++++++++++++++++++++ insider/alert.js | 36 ++++++++++++++++ insider/api.js | 26 ++++++++++++ insider/config.js | 6 +++ insider/containment.js | 26 ++++++++++++ insider/dashboard.js | 22 ++++++++++ insider/docs.md | 36 ++++++++++++++++ insider/examples.js | 24 +++++++++++ insider/insider-orchestrator.js | 57 +++++++++++++++++++++++++ insider/suspicious-detector.js | 75 +++++++++++++++++++++++++++++++++ insider/test.js | 33 +++++++++++++++ insider/types.d.ts | 23 ++++++++++ 13 files changed, 450 insertions(+) create mode 100644 insider/README.md create mode 100644 insider/activity-monitor.js create mode 100644 insider/alert.js create mode 100644 insider/api.js create mode 100644 insider/config.js create mode 100644 insider/containment.js create mode 100644 insider/dashboard.js create mode 100644 insider/docs.md create mode 100644 insider/examples.js create mode 100644 insider/insider-orchestrator.js create mode 100644 insider/suspicious-detector.js create mode 100644 insider/test.js create mode 100644 insider/types.d.ts diff --git a/insider/README.md b/insider/README.md new file mode 100644 index 00000000..bfbfe0bb --- /dev/null +++ b/insider/README.md @@ -0,0 +1,37 @@ +# Real-Time Insider Threat Detection & Response + +## Overview +This module monitors user behavior, flags suspicious activities, and triggers automated containment actions to mitigate insider threats in real time. + +## Features +- Real-time user activity monitoring +- Suspicious activity detection (rules-based) +- Automated containment (account lock, session termination, resource isolation) +- Alerting and reporting (log, notification, report generation) +- Orchestrator for integration and workflow + +## File Structure +- `activity-monitor.js`: Tracks user actions, sessions, resource access +- `suspicious-detector.js`: Flags suspicious activities using rules +- `containment.js`: Executes automated containment actions +- `alert.js`: Logs alerts, sends notifications, generates reports +- `insider-orchestrator.js`: Integrates all modules for detection and response + +## Usage Example +```js +const orchestrator = require('./insider/insider-orchestrator'); + +// Monitor user activity +orchestrator.monitorUser('user123', { type: 'login', status: 'fail', sessionId: 'sess1' }); + +// Generate report +orchestrator.generateReport('insider-threat-report.json'); +``` + +## Extending +- Add more detection rules in `suspicious-detector.js` +- Integrate with external alerting systems in `alert.js` +- Customize containment logic in `containment.js` + +## Compliance +All alerts and actions are logged for audit and compliance. diff --git a/insider/activity-monitor.js b/insider/activity-monitor.js new file mode 100644 index 00000000..bb322258 --- /dev/null +++ b/insider/activity-monitor.js @@ -0,0 +1,49 @@ +// Real-Time User Activity Monitor +// Tracks user actions, session events, and resource access + +class ActivityMonitor { + constructor() { + this.userActivities = new Map(); // userId -> [activity] + this.sessionEvents = new Map(); // sessionId -> [event] + this.resourceAccess = new Map(); // resourceId -> [userId] + } + + recordActivity(userId, activity) { + if (!this.userActivities.has(userId)) { + this.userActivities.set(userId, []); + } + this.userActivities.get(userId).push({ ...activity, timestamp: Date.now() }); + } + + recordSessionEvent(sessionId, event) { + if (!this.sessionEvents.has(sessionId)) { + this.sessionEvents.set(sessionId, []); + } + this.sessionEvents.get(sessionId).push({ ...event, timestamp: Date.now() }); + } + + recordResourceAccess(resourceId, userId) { + if (!this.resourceAccess.has(resourceId)) { + this.resourceAccess.set(resourceId, []); + } + this.resourceAccess.get(resourceId).push({ userId, timestamp: Date.now() }); + } + + getUserActivities(userId) { + return this.userActivities.get(userId) || []; + } + + getSessionEvents(sessionId) { + return this.sessionEvents.get(sessionId) || []; + } + + getResourceAccess(resourceId) { + return this.resourceAccess.get(resourceId) || []; + } + + getAllActivities() { + return Array.from(this.userActivities.entries()); + } +} + +module.exports = new ActivityMonitor(); diff --git a/insider/alert.js b/insider/alert.js new file mode 100644 index 00000000..fcfafa38 --- /dev/null +++ b/insider/alert.js @@ -0,0 +1,36 @@ +// Alerting and Reporting for Insider Threats +// Logs alerts, sends notifications, and generates reports + +const fs = require('fs'); +const path = require('path'); +const ALERT_FILE = path.join(__dirname, 'alerts.log'); + +class AlertManager { + logAlert(alert) { + const entry = { ...alert, timestamp: new Date().toISOString() }; + fs.appendFileSync(ALERT_FILE, JSON.stringify(entry) + '\n'); + } + + getAlerts() { + if (!fs.existsSync(ALERT_FILE)) return []; + const lines = fs.readFileSync(ALERT_FILE, 'utf8').split('\n').filter(Boolean); + return lines.map(line => JSON.parse(line)); + } + + sendNotification(alert) { + // Placeholder: send email, SMS, webhook, etc. + console.log('NOTIFICATION:', alert); + } + + generateReport(filePath = 'insider-threat-report.json') { + const alerts = this.getAlerts(); + const report = { + generatedAt: new Date().toISOString(), + alerts + }; + fs.writeFileSync(path.join(__dirname, filePath), JSON.stringify(report, null, 2)); + console.log('Report generated:', filePath); + } +} + +module.exports = new AlertManager(); diff --git a/insider/api.js b/insider/api.js new file mode 100644 index 00000000..1c34fab6 --- /dev/null +++ b/insider/api.js @@ -0,0 +1,26 @@ +// Insider Threat Detection API Integration Example +const express = require('express'); +const app = express(); +const orchestrator = require('./insider-orchestrator'); + +app.use(express.json()); + +app.post('/activity', (req, res) => { + const { userId, activity } = req.body; + orchestrator.monitorUser(userId, activity); + res.json({ success: true }); +}); + +app.get('/alerts', (req, res) => { + res.json({ alerts: orchestrator.getAlerts() }); +}); + +app.post('/report', (req, res) => { + const { filePath } = req.body; + orchestrator.generateReport(filePath || 'insider-threat-report.json'); + res.json({ success: true, filePath: filePath || 'insider-threat-report.json' }); +}); + +app.listen(4002, () => { + console.log('Insider Threat Detection API running on port 4002'); +}); diff --git a/insider/config.js b/insider/config.js new file mode 100644 index 00000000..07ba8c2f --- /dev/null +++ b/insider/config.js @@ -0,0 +1,6 @@ +// Configuration for Insider Threat Detection +module.exports = { + alertFile: 'alerts.log', + reportFile: 'insider-threat-report.json', + dashboardPort: 4003 +}; diff --git a/insider/containment.js b/insider/containment.js new file mode 100644 index 00000000..8325d1d2 --- /dev/null +++ b/insider/containment.js @@ -0,0 +1,26 @@ +// Automated Containment Actions +// Triggers account lock, session termination, alerting, and resource isolation + +class Containment { + lockAccount(userId) { + // Placeholder: lock user account in DB + console.log(`Account locked for user: ${userId}`); + } + + terminateSession(sessionId) { + // Placeholder: terminate session + console.log(`Session terminated: ${sessionId}`); + } + + isolateResource(resourceId) { + // Placeholder: restrict access to resource + console.log(`Resource isolated: ${resourceId}`); + } + + sendAlert(alert) { + // Placeholder: send alert to security team + console.log('ALERT:', alert); + } +} + +module.exports = new Containment(); diff --git a/insider/dashboard.js b/insider/dashboard.js new file mode 100644 index 00000000..86730a16 --- /dev/null +++ b/insider/dashboard.js @@ -0,0 +1,22 @@ +// Insider Threat Detection Dashboard (CLI) +// Displays user activities, alerts, and containment actions + +const activityMonitor = require('./activity-monitor'); +const alertManager = require('./alert'); + +function printDashboard() { + console.log('--- Insider Threat Detection Dashboard ---'); + console.log('User Activities:'); + for (const [userId, activities] of activityMonitor.getAllActivities()) { + console.log(`User: ${userId}`); + activities.forEach(a => console.log(' ', a)); + console.log('---'); + } + console.log('Recent Alerts:'); + const alerts = alertManager.getAlerts().slice(-10); + for (const alert of alerts) { + console.log(alert); + } +} + +printDashboard(); diff --git a/insider/docs.md b/insider/docs.md new file mode 100644 index 00000000..ffdd707c --- /dev/null +++ b/insider/docs.md @@ -0,0 +1,36 @@ +# Insider Threat Detection & Response Documentation + +## Overview +This module provides real-time monitoring, detection, and response for insider threats. It tracks user activities, flags suspicious behavior, and automates containment actions. + +## Modules +- **activity-monitor.js**: Tracks user actions, sessions, resource access +- **suspicious-detector.js**: Detects suspicious activities using rules +- **containment.js**: Executes containment actions +- **alert.js**: Logs alerts, sends notifications, generates reports +- **insider-orchestrator.js**: Orchestrates detection and response + +## Integration +Add activity monitoring to your API: +```js +const orchestrator = require('./insider/insider-orchestrator'); +app.post('/activity', (req, res) => { + const { userId, activity } = req.body; + orchestrator.monitorUser(userId, activity); + res.json({ success: true }); +}); +``` + +## Dashboard +Run `dashboard.js` to view activities and alerts. + +## Testing +Run `test.js` for a basic test suite. + +## Extending +- Add more detection rules in `suspicious-detector.js` +- Integrate external alerting in `alert.js` +- Customize containment logic in `containment.js` + +## Compliance +All alerts and actions are logged for audit and compliance. diff --git a/insider/examples.js b/insider/examples.js new file mode 100644 index 00000000..ae0fa648 --- /dev/null +++ b/insider/examples.js @@ -0,0 +1,24 @@ +// Example usage scenarios for Insider Threat Detection +const orchestrator = require('./insider-orchestrator'); + +function simulateScenario(userId, activities) { + activities.forEach(activity => { + orchestrator.monitorUser(userId, activity); + console.log(`User: ${userId}, Activity: ${JSON.stringify(activity)}`); + }); +} + +// Scenario 1: High volume access +simulateScenario('userA', Array(120).fill({ type: 'access', resource: { id: 'fileX', sensitive: false } })); + +// Scenario 2: Off-hours access +simulateScenario('userB', [{ type: 'access', resource: { id: 'fileY', sensitive: false }, timestamp: new Date('2026-03-05T03:00:00Z').getTime() }]); + +// Scenario 3: Sensitive resource access +simulateScenario('userC', [{ type: 'access', resource: { id: 'fileZ', sensitive: true } }]); + +// Scenario 4: Failed login attempts +simulateScenario('userD', Array(7).fill({ type: 'login', status: 'fail', sessionId: 'sessD' })); + +// Scenario 5: Unusual session duration +simulateScenario('userE', [{ type: 'session', duration: 9 * 3600 * 1000, sessionId: 'sessE' }]); diff --git a/insider/insider-orchestrator.js b/insider/insider-orchestrator.js new file mode 100644 index 00000000..663527c7 --- /dev/null +++ b/insider/insider-orchestrator.js @@ -0,0 +1,57 @@ +// Insider Threat Detection Orchestrator +// Integrates monitoring, detection, containment, and alerting + +const activityMonitor = require('./activity-monitor'); +const suspiciousDetector = require('./suspicious-detector'); +const containment = require('./containment'); +const alertManager = require('./alert'); + +class InsiderThreatOrchestrator { + monitorUser(userId, activity) { + activityMonitor.recordActivity(userId, activity); + const activities = activityMonitor.getUserActivities(userId); + const alerts = suspiciousDetector.analyzeActivity(userId, activities); + alerts.forEach(alert => { + alertManager.logAlert(alert); + alertManager.sendNotification(alert); + this.handleAlert(alert, userId, activity); + }); + } + + handleAlert(alert, userId, activity) { + switch (alert.type) { + case 'HighVolumeAccess': + containment.lockAccount(userId); + containment.sendAlert(alert); + break; + case 'OffHoursAccess': + containment.terminateSession(activity.sessionId); + containment.sendAlert(alert); + break; + case 'SensitiveResourceAccess': + containment.isolateResource(alert.resource); + containment.sendAlert(alert); + break; + case 'FailedLoginAttempts': + containment.lockAccount(userId); + containment.sendAlert(alert); + break; + case 'UnusualSessionDuration': + containment.terminateSession(activity.sessionId); + containment.sendAlert(alert); + break; + default: + containment.sendAlert(alert); + } + } + + generateReport(filePath) { + alertManager.generateReport(filePath); + } + + getAlerts() { + return alertManager.getAlerts(); + } +} + +module.exports = new InsiderThreatOrchestrator(); diff --git a/insider/suspicious-detector.js b/insider/suspicious-detector.js new file mode 100644 index 00000000..f10df95e --- /dev/null +++ b/insider/suspicious-detector.js @@ -0,0 +1,75 @@ +// Suspicious Activity Detection Logic +// Flags anomalous, risky, or policy-violating actions + +class SuspiciousDetector { + constructor() { + this.rules = [ + this.ruleHighVolumeAccess, + this.ruleOffHoursAccess, + this.ruleSensitiveResourceAccess, + this.ruleFailedLoginAttempts, + this.ruleUnusualSessionDuration + ]; + } + + analyzeActivity(userId, activities) { + let alerts = []; + for (const rule of this.rules) { + const result = rule(userId, activities); + if (result) alerts.push(result); + } + return alerts; + } + + ruleHighVolumeAccess(userId, activities) { + // Flag if user accesses >100 resources in 1 hour + const now = Date.now(); + const recent = activities.filter(a => now - a.timestamp < 3600000); + if (recent.length > 100) { + return { type: 'HighVolumeAccess', userId, count: recent.length }; + } + return null; + } + + ruleOffHoursAccess(userId, activities) { + // Flag access between 12am-5am + for (const a of activities) { + const hour = new Date(a.timestamp).getHours(); + if (hour >= 0 && hour < 5) { + return { type: 'OffHoursAccess', userId, timestamp: a.timestamp }; + } + } + return null; + } + + ruleSensitiveResourceAccess(userId, activities) { + // Flag access to resources marked 'sensitive' + for (const a of activities) { + if (a.resource && a.resource.sensitive) { + return { type: 'SensitiveResourceAccess', userId, resource: a.resource.id }; + } + } + return null; + } + + ruleFailedLoginAttempts(userId, activities) { + // Flag >5 failed logins in 10 minutes + const now = Date.now(); + const failed = activities.filter(a => a.type === 'login' && a.status === 'fail' && now - a.timestamp < 600000); + if (failed.length > 5) { + return { type: 'FailedLoginAttempts', userId, count: failed.length }; + } + return null; + } + + ruleUnusualSessionDuration(userId, activities) { + // Flag sessions longer than 8 hours + const sessions = activities.filter(a => a.type === 'session' && a.duration > 8 * 3600 * 1000); + if (sessions.length > 0) { + return { type: 'UnusualSessionDuration', userId, sessions: sessions.length }; + } + return null; + } +} + +module.exports = new SuspiciousDetector(); diff --git a/insider/test.js b/insider/test.js new file mode 100644 index 00000000..cceff6fd --- /dev/null +++ b/insider/test.js @@ -0,0 +1,33 @@ +// Test suite for Insider Threat Detection +const orchestrator = require('./insider-orchestrator'); + +function runTests() { + console.log('Test: High volume access'); + for (let i = 0; i < 120; i++) { + orchestrator.monitorUser('user1', { type: 'access', resource: { id: 'fileA', sensitive: false } }); + } + console.log('Alerts:', orchestrator.getAlerts().slice(-2)); + + console.log('Test: Off-hours access'); + orchestrator.monitorUser('user2', { type: 'access', resource: { id: 'fileB', sensitive: false }, timestamp: new Date('2026-03-05T02:00:00Z').getTime() }); + console.log('Alerts:', orchestrator.getAlerts().slice(-1)); + + console.log('Test: Sensitive resource access'); + orchestrator.monitorUser('user3', { type: 'access', resource: { id: 'fileC', sensitive: true } }); + console.log('Alerts:', orchestrator.getAlerts().slice(-1)); + + console.log('Test: Failed login attempts'); + for (let i = 0; i < 7; i++) { + orchestrator.monitorUser('user4', { type: 'login', status: 'fail', sessionId: 'sess2' }); + } + console.log('Alerts:', orchestrator.getAlerts().slice(-1)); + + console.log('Test: Unusual session duration'); + orchestrator.monitorUser('user5', { type: 'session', duration: 9 * 3600 * 1000, sessionId: 'sess3' }); + console.log('Alerts:', orchestrator.getAlerts().slice(-1)); + + // Generate report + orchestrator.generateReport('test-insider-report.json'); +} + +runTests(); diff --git a/insider/types.d.ts b/insider/types.d.ts new file mode 100644 index 00000000..0c7eedd4 --- /dev/null +++ b/insider/types.d.ts @@ -0,0 +1,23 @@ +// Type definitions for Insider Threat Detection + +/** + * User activity event + */ +interface UserActivity { + type: string; + status?: string; + resource?: { id: string; sensitive: boolean }; + sessionId?: string; + duration?: number; + timestamp?: number; +} + +/** + * Alert entry + */ +interface AlertEntry { + type: string; + userId: string; + timestamp: string; + [key: string]: any; +}