@titanshield/core 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/TitanShield.d.ts +107 -0
- package/dist/TitanShield.d.ts.map +1 -0
- package/dist/TitanShield.js +248 -0
- package/dist/TitanShield.js.map +1 -0
- package/dist/audit.d.ts +8 -0
- package/dist/audit.d.ts.map +1 -0
- package/dist/audit.js +76 -0
- package/dist/audit.js.map +1 -0
- package/dist/auto.d.ts +12 -0
- package/dist/auto.d.ts.map +1 -0
- package/dist/auto.js +129 -0
- package/dist/auto.js.map +1 -0
- package/dist/badge.d.ts +27 -0
- package/dist/badge.d.ts.map +1 -0
- package/dist/badge.js +127 -0
- package/dist/badge.js.map +1 -0
- package/dist/battle.d.ts +50 -0
- package/dist/battle.d.ts.map +1 -0
- package/dist/battle.js +239 -0
- package/dist/battle.js.map +1 -0
- package/dist/biometrics.d.ts +63 -0
- package/dist/biometrics.d.ts.map +1 -0
- package/dist/biometrics.js +248 -0
- package/dist/biometrics.js.map +1 -0
- package/dist/collective.d.ts +63 -0
- package/dist/collective.d.ts.map +1 -0
- package/dist/collective.js +203 -0
- package/dist/collective.js.map +1 -0
- package/dist/compliance.d.ts +3 -0
- package/dist/compliance.d.ts.map +1 -0
- package/dist/compliance.js +71 -0
- package/dist/compliance.js.map +1 -0
- package/dist/dna.d.ts +82 -0
- package/dist/dna.d.ts.map +1 -0
- package/dist/dna.js +219 -0
- package/dist/dna.js.map +1 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +56 -0
- package/dist/index.js.map +1 -0
- package/dist/nlrules.d.ts +68 -0
- package/dist/nlrules.d.ts.map +1 -0
- package/dist/nlrules.js +232 -0
- package/dist/nlrules.js.map +1 -0
- package/dist/prevent.d.ts +119 -0
- package/dist/prevent.d.ts.map +1 -0
- package/dist/prevent.js +380 -0
- package/dist/prevent.js.map +1 -0
- package/dist/quantum.d.ts +105 -0
- package/dist/quantum.d.ts.map +1 -0
- package/dist/quantum.js +269 -0
- package/dist/quantum.js.map +1 -0
- package/dist/scanner.d.ts +61 -0
- package/dist/scanner.d.ts.map +1 -0
- package/dist/scanner.js +364 -0
- package/dist/scanner.js.map +1 -0
- package/dist/threats.d.ts +10 -0
- package/dist/threats.d.ts.map +1 -0
- package/dist/threats.js +96 -0
- package/dist/threats.js.map +1 -0
- package/dist/types.d.ts +68 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +6 -0
- package/dist/types.js.map +1 -0
- package/dist/validate.d.ts +51 -0
- package/dist/validate.d.ts.map +1 -0
- package/dist/validate.js +59 -0
- package/dist/validate.js.map +1 -0
- package/package.json +33 -0
- package/src/TitanShield.ts +303 -0
- package/src/audit.ts +75 -0
- package/src/auto.ts +137 -0
- package/src/badge.ts +145 -0
- package/src/battle.ts +300 -0
- package/src/biometrics.ts +307 -0
- package/src/collective.ts +269 -0
- package/src/compliance.ts +74 -0
- package/src/dna.ts +304 -0
- package/src/index.ts +59 -0
- package/src/nlrules.ts +297 -0
- package/src/prevent.ts +474 -0
- package/src/quantum.ts +341 -0
- package/src/scanner.ts +431 -0
- package/src/threats.ts +105 -0
- package/src/types.ts +108 -0
- package/src/validate.ts +72 -0
- package/tsconfig.json +26 -0
package/dist/prevent.js
ADDED
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
3
|
+
// TitanShieldAI v0.2 — prevent.ts
|
|
4
|
+
// World's most complete single-SDK security prevention layer
|
|
5
|
+
//
|
|
6
|
+
// What this module actively STOPS (not just logs):
|
|
7
|
+
// 🔒 Auto account lockout after failed login attempts
|
|
8
|
+
// 🛡️ Security headers (CSP, HSTS, XFO, CORP, Permissions-Policy)
|
|
9
|
+
// 🚫 IP reputation blocklist (known Tor, botnet, scanner IPs)
|
|
10
|
+
// 🎫 CSRF token generation + validation
|
|
11
|
+
// 🔍 Session fingerprinting (detect account hijacking)
|
|
12
|
+
// 💉 Advanced injection prevention (path traversal, command injection)
|
|
13
|
+
// 🤖 Bot detection (user-agent analysis + headless browser detection)
|
|
14
|
+
// 🌍 Geo-blocking (configurable country blocklist)
|
|
15
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
exports.ipReputation = exports.csrfTokens = exports.sessions = exports.lockouts = exports.IpReputationEngine = exports.SessionFingerprinter = exports.CsrfProtection = exports.AccountLockout = void 0;
|
|
18
|
+
exports.securityHeaders = securityHeaders;
|
|
19
|
+
exports.detectBot = detectBot;
|
|
20
|
+
exports.detectAdvancedInjection = detectAdvancedInjection;
|
|
21
|
+
exports.titanPreventionMiddleware = titanPreventionMiddleware;
|
|
22
|
+
const crypto_1 = require("crypto");
|
|
23
|
+
// ── Internal stores (use Redis/Firestore in prod) ─────────────────────────────
|
|
24
|
+
const lockouts = new Map();
|
|
25
|
+
exports.lockouts = lockouts;
|
|
26
|
+
const sessions = new Map();
|
|
27
|
+
exports.sessions = sessions;
|
|
28
|
+
const csrfTokens = new Map();
|
|
29
|
+
exports.csrfTokens = csrfTokens;
|
|
30
|
+
const ipReputation = new Map();
|
|
31
|
+
exports.ipReputation = ipReputation;
|
|
32
|
+
// ── Known malicious patterns ──────────────────────────────────────────────────
|
|
33
|
+
const PATH_TRAVERSAL = /(\.\.[/\\]){2,}|\/etc\/passwd|\/proc\/self|\.env|\/root\//i;
|
|
34
|
+
const CMD_INJECTION = /[;&|`$]|\b(cat|wget|curl|nc|bash|sh|python|perl|ruby)\s/i;
|
|
35
|
+
const MALICIOUS_UA = /sqlmap|nikto|nmap|masscan|zgrab|go-http-client\/1\.1|python-requests\/[01]\.|libwww-perl/i;
|
|
36
|
+
const HEADLESS = /headlesschrome|phantomjs|selenium|webdriver|puppeteer/i;
|
|
37
|
+
// High-risk TLDs and datacenter IP ranges (simplified — production uses threat intel feeds)
|
|
38
|
+
const SUSPICIOUS_HOSTING = ['amazonaws.com', 'digitalocean.com', 'vultr.com', 'linode.com'];
|
|
39
|
+
// ── 1. ACCOUNT LOCKOUT ENGINE ─────────────────────────────────────────────────
|
|
40
|
+
class AccountLockout {
|
|
41
|
+
constructor(config = {}) {
|
|
42
|
+
this.config = {
|
|
43
|
+
maxFailedLogins: config.maxFailedLogins ?? 5,
|
|
44
|
+
lockoutDurationMs: config.lockoutDurationMs ?? 15 * 60 * 1000,
|
|
45
|
+
lockoutWindowMs: config.lockoutWindowMs ?? 10 * 60 * 1000,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Record a failed login attempt for this identifier (userId or IP).
|
|
50
|
+
* Returns lock status with human-readable message.
|
|
51
|
+
*/
|
|
52
|
+
recordFailure(identifier, ip) {
|
|
53
|
+
const now = Date.now();
|
|
54
|
+
const record = lockouts.get(identifier) ?? { attempts: 0, firstAttemptAt: now };
|
|
55
|
+
// Reset window if expired
|
|
56
|
+
if (now - record.firstAttemptAt > this.config.lockoutWindowMs) {
|
|
57
|
+
record.attempts = 0;
|
|
58
|
+
record.firstAttemptAt = now;
|
|
59
|
+
delete record.lockedUntil;
|
|
60
|
+
}
|
|
61
|
+
record.attempts++;
|
|
62
|
+
if (ip)
|
|
63
|
+
record.lastAttemptIp = ip;
|
|
64
|
+
lockouts.set(identifier, record);
|
|
65
|
+
if (record.attempts >= this.config.maxFailedLogins) {
|
|
66
|
+
record.lockedUntil = now + this.config.lockoutDurationMs;
|
|
67
|
+
const lockedMinutes = Math.ceil(this.config.lockoutDurationMs / 60000);
|
|
68
|
+
return {
|
|
69
|
+
locked: true, attemptsLeft: 0,
|
|
70
|
+
lockedFor: this.config.lockoutDurationMs,
|
|
71
|
+
message: `Account locked for ${lockedMinutes} minutes after ${record.attempts} failed attempts. ${ip ? `Last attempt from ${ip}.` : ''} We've made a note of this for security. 🔒`,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const left = this.config.maxFailedLogins - record.attempts;
|
|
75
|
+
return { locked: false, attemptsLeft: left, message: `${record.attempts} failed attempt${record.attempts !== 1 ? 's' : ''}. ${left} more before lockout.` };
|
|
76
|
+
}
|
|
77
|
+
/** Call this on SUCCESSFUL login to reset the counter */
|
|
78
|
+
recordSuccess(identifier) {
|
|
79
|
+
lockouts.delete(identifier);
|
|
80
|
+
}
|
|
81
|
+
/** Check if an account is currently locked (before attempting auth) */
|
|
82
|
+
isLocked(identifier) {
|
|
83
|
+
const record = lockouts.get(identifier);
|
|
84
|
+
if (!record?.lockedUntil)
|
|
85
|
+
return { locked: false };
|
|
86
|
+
if (Date.now() > record.lockedUntil) {
|
|
87
|
+
lockouts.delete(identifier);
|
|
88
|
+
return { locked: false };
|
|
89
|
+
}
|
|
90
|
+
const remainingSec = Math.ceil((record.lockedUntil - Date.now()) / 1000);
|
|
91
|
+
const remainingMin = Math.ceil(remainingSec / 60);
|
|
92
|
+
return {
|
|
93
|
+
locked: true,
|
|
94
|
+
unlockAt: record.lockedUntil,
|
|
95
|
+
message: `This account is locked for ${remainingMin} more minute${remainingMin !== 1 ? 's' : ''}. Too many wrong passwords were tried. 🔒`,
|
|
96
|
+
};
|
|
97
|
+
}
|
|
98
|
+
}
|
|
99
|
+
exports.AccountLockout = AccountLockout;
|
|
100
|
+
// ── 2. SECURITY HEADERS MIDDLEWARE ────────────────────────────────────────────
|
|
101
|
+
function securityHeaders(config = {}) {
|
|
102
|
+
const frameOptions = config.frameOptions ?? 'DENY';
|
|
103
|
+
const customCsp = config.cspDirectives ?? {};
|
|
104
|
+
const defaultCsp = {
|
|
105
|
+
'default-src': "'self'",
|
|
106
|
+
'script-src': "'self' 'unsafe-inline'", // tighten before prod
|
|
107
|
+
'style-src': "'self' 'unsafe-inline' https://fonts.googleapis.com",
|
|
108
|
+
'font-src': "'self' https://fonts.gstatic.com",
|
|
109
|
+
'img-src': "'self' data: https:",
|
|
110
|
+
'connect-src': "'self'",
|
|
111
|
+
'frame-ancestors': "'none'",
|
|
112
|
+
'base-uri': "'self'",
|
|
113
|
+
'form-action': "'self'",
|
|
114
|
+
'upgrade-insecure-requests': '',
|
|
115
|
+
};
|
|
116
|
+
const mergedCsp = { ...defaultCsp, ...customCsp };
|
|
117
|
+
const cspValue = Object.entries(mergedCsp)
|
|
118
|
+
.map(([k, v]) => v ? `${k} ${v}` : k)
|
|
119
|
+
.join('; ');
|
|
120
|
+
return function titanSecurityHeaders(_req, res, next) {
|
|
121
|
+
// Prevent clickjacking
|
|
122
|
+
res.setHeader('X-Frame-Options', frameOptions);
|
|
123
|
+
// Prevent MIME type sniffing
|
|
124
|
+
res.setHeader('X-Content-Type-Options', 'nosniff');
|
|
125
|
+
// Force HTTPS for 1 year (with subdomains)
|
|
126
|
+
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains; preload');
|
|
127
|
+
// Block XSS in older browsers
|
|
128
|
+
res.setHeader('X-XSS-Protection', '1; mode=block');
|
|
129
|
+
// Control referrer info
|
|
130
|
+
res.setHeader('Referrer-Policy', 'strict-origin-when-cross-origin');
|
|
131
|
+
// Restrict browser features
|
|
132
|
+
res.setHeader('Permissions-Policy', [
|
|
133
|
+
'camera=()',
|
|
134
|
+
'microphone=()',
|
|
135
|
+
'geolocation=()',
|
|
136
|
+
'payment=()',
|
|
137
|
+
'usb=()',
|
|
138
|
+
'accelerometer=()',
|
|
139
|
+
'gyroscope=()',
|
|
140
|
+
].join(', '));
|
|
141
|
+
// Cross-Origin isolation
|
|
142
|
+
res.setHeader('Cross-Origin-Opener-Policy', 'same-origin');
|
|
143
|
+
res.setHeader('Cross-Origin-Resource-Policy', 'same-origin');
|
|
144
|
+
// Content Security Policy
|
|
145
|
+
res.setHeader('Content-Security-Policy', cspValue);
|
|
146
|
+
// Remove fingerprinting headers
|
|
147
|
+
res.removeHeader('X-Powered-By');
|
|
148
|
+
res.removeHeader('Server');
|
|
149
|
+
next();
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
// ── 3. CSRF PROTECTION ────────────────────────────────────────────────────────
|
|
153
|
+
class CsrfProtection {
|
|
154
|
+
constructor(config = {}) {
|
|
155
|
+
this.tokenTtlMs = 60 * 60 * 1000; // 1 hour
|
|
156
|
+
this.exemptPaths = config.csrfExemptPaths ?? ['/api/webhook', '/health'];
|
|
157
|
+
}
|
|
158
|
+
/** Generate a CSRF token for a session */
|
|
159
|
+
generateToken(sessionId) {
|
|
160
|
+
const token = (0, crypto_1.randomBytes)(32).toString('hex');
|
|
161
|
+
const key = `${sessionId}:${token}`;
|
|
162
|
+
csrfTokens.set(key, { expires: Date.now() + this.tokenTtlMs });
|
|
163
|
+
// Cleanup expired tokens periodically
|
|
164
|
+
if (csrfTokens.size > 10000) {
|
|
165
|
+
const now = Date.now();
|
|
166
|
+
for (const [k, v] of csrfTokens) {
|
|
167
|
+
if (v.expires < now)
|
|
168
|
+
csrfTokens.delete(k);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
return token;
|
|
172
|
+
}
|
|
173
|
+
/** Validate a CSRF token */
|
|
174
|
+
validateToken(sessionId, token) {
|
|
175
|
+
const key = `${sessionId}:${token}`;
|
|
176
|
+
const record = csrfTokens.get(key);
|
|
177
|
+
if (!record)
|
|
178
|
+
return false;
|
|
179
|
+
if (Date.now() > record.expires) {
|
|
180
|
+
csrfTokens.delete(key);
|
|
181
|
+
return false;
|
|
182
|
+
}
|
|
183
|
+
csrfTokens.delete(key); // Single-use token
|
|
184
|
+
return true;
|
|
185
|
+
}
|
|
186
|
+
/** Express middleware — validates CSRF on state-changing requests */
|
|
187
|
+
middleware() {
|
|
188
|
+
return (req, res, next) => {
|
|
189
|
+
const safeMethods = ['GET', 'HEAD', 'OPTIONS'];
|
|
190
|
+
if (safeMethods.includes(req.method))
|
|
191
|
+
return next();
|
|
192
|
+
if (this.exemptPaths.some(p => req.path.startsWith(p)))
|
|
193
|
+
return next();
|
|
194
|
+
const sessionId = req.session?.id || req.headers['x-session-id'];
|
|
195
|
+
if (!sessionId)
|
|
196
|
+
return next(); // No session, skip (API key auth flows)
|
|
197
|
+
const token = req.headers['x-csrf-token'] || req.body?._csrf;
|
|
198
|
+
if (!token || !this.validateToken(sessionId, token)) {
|
|
199
|
+
res.status(403).json({
|
|
200
|
+
error: 'Security check failed.',
|
|
201
|
+
message: 'This request was rejected because it did not have a valid security token. This protects you from attacks where bad guys trick your browser into doing things without your knowledge. 🛡️',
|
|
202
|
+
code: 'CSRF_TOKEN_INVALID',
|
|
203
|
+
});
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
next();
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
exports.CsrfProtection = CsrfProtection;
|
|
211
|
+
// ── 4. SESSION FINGERPRINTING ─────────────────────────────────────────────────
|
|
212
|
+
class SessionFingerprinter {
|
|
213
|
+
/**
|
|
214
|
+
* Create a fingerprint from request characteristics.
|
|
215
|
+
* Used to detect if someone stole a session cookie and is using it
|
|
216
|
+
* from a different device/browser/location.
|
|
217
|
+
*/
|
|
218
|
+
createFingerprint(req) {
|
|
219
|
+
const ip = req.headers['x-forwarded-for']?.split(',')[0]?.trim() || req.ip || '0.0.0.0';
|
|
220
|
+
const ua = req.headers['user-agent'] || '';
|
|
221
|
+
const lang = req.headers['accept-language'] || '';
|
|
222
|
+
const raw = `${ip}:${ua}:${lang}`;
|
|
223
|
+
const hash = (0, crypto_1.createHash)('sha256').update(raw).digest('hex');
|
|
224
|
+
return { ip, userAgent: ua, acceptLang: lang, hash, createdAt: Date.now() };
|
|
225
|
+
}
|
|
226
|
+
/** Store a fingerprint for a session */
|
|
227
|
+
store(sessionId, fp) {
|
|
228
|
+
sessions.set(sessionId, fp);
|
|
229
|
+
}
|
|
230
|
+
/**
|
|
231
|
+
* Verify current request matches the original session fingerprint.
|
|
232
|
+
* Returns { valid, reason } — soft verification (logs warning, doesn't hard block by default).
|
|
233
|
+
*/
|
|
234
|
+
verify(sessionId, req) {
|
|
235
|
+
const stored = sessions.get(sessionId);
|
|
236
|
+
if (!stored)
|
|
237
|
+
return { valid: true, riskLevel: 'none' };
|
|
238
|
+
const current = this.createFingerprint(req);
|
|
239
|
+
if (stored.hash === current.hash)
|
|
240
|
+
return { valid: true, riskLevel: 'none' };
|
|
241
|
+
// Check what changed
|
|
242
|
+
const uaChanged = stored.userAgent !== current.userAgent;
|
|
243
|
+
const ipChanged = stored.ip !== current.ip;
|
|
244
|
+
if (uaChanged && ipChanged) {
|
|
245
|
+
return { valid: false, riskLevel: 'high', reason: 'Browser AND location changed — possible session hijack! 🚨 IP changed from ' + stored.ip + ' to ' + current.ip };
|
|
246
|
+
}
|
|
247
|
+
if (uaChanged) {
|
|
248
|
+
return { valid: false, riskLevel: 'high', reason: 'Browser changed mid-session — possible session token theft 🚨' };
|
|
249
|
+
}
|
|
250
|
+
if (ipChanged) {
|
|
251
|
+
return { valid: false, riskLevel: 'low', reason: 'Location changed during session — user may be on VPN or mobile (low risk)' };
|
|
252
|
+
}
|
|
253
|
+
return { valid: true, riskLevel: 'none' };
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
exports.SessionFingerprinter = SessionFingerprinter;
|
|
257
|
+
// ── 5. BOT DETECTION ─────────────────────────────────────────────────────────
|
|
258
|
+
function detectBot(req) {
|
|
259
|
+
const ua = req.headers['user-agent'] || '';
|
|
260
|
+
const ip = req.ip || '';
|
|
261
|
+
// Known malicious scanners
|
|
262
|
+
if (MALICIOUS_UA.test(ua)) {
|
|
263
|
+
return { isBot: true, confidence: 'high', reason: `Known malicious scanner detected in User-Agent: "${ua.slice(0, 80)}"` };
|
|
264
|
+
}
|
|
265
|
+
// Headless browser
|
|
266
|
+
if (HEADLESS.test(ua)) {
|
|
267
|
+
return { isBot: true, confidence: 'high', reason: 'Headless browser detected — automated tool accessing your app' };
|
|
268
|
+
}
|
|
269
|
+
// No user-agent at all (very suspicious for browser)
|
|
270
|
+
if (!ua) {
|
|
271
|
+
return { isBot: true, confidence: 'medium', reason: 'No User-Agent header — automated request' };
|
|
272
|
+
}
|
|
273
|
+
// Datacenter IP hosting suspicious patterns
|
|
274
|
+
const referer = (req.headers['referer'] || '').toLowerCase();
|
|
275
|
+
if (!referer && req.method === 'POST' && !ua.includes('Mozilla')) {
|
|
276
|
+
return { isBot: true, confidence: 'medium', reason: 'Automated POST with no browser User-Agent' };
|
|
277
|
+
}
|
|
278
|
+
return { isBot: false, confidence: 'low', reason: 'Looks like a real user ✅' };
|
|
279
|
+
}
|
|
280
|
+
// ── 6. ADVANCED INJECTION PREVENTION ─────────────────────────────────────────
|
|
281
|
+
function detectAdvancedInjection(req) {
|
|
282
|
+
// Check URL path traversal
|
|
283
|
+
if (PATH_TRAVERSAL.test(req.path) || PATH_TRAVERSAL.test(req.url)) {
|
|
284
|
+
return { threat: true, type: 'path_traversal', detail: `Path traversal attempt detected in URL: ${req.url.slice(0, 100)}` };
|
|
285
|
+
}
|
|
286
|
+
// Check query string
|
|
287
|
+
const qs = JSON.stringify(req.query);
|
|
288
|
+
if (CMD_INJECTION.test(qs)) {
|
|
289
|
+
return { threat: true, type: 'command_injection', detail: `Command injection attempt in query parameters` };
|
|
290
|
+
}
|
|
291
|
+
// Check body
|
|
292
|
+
const body = JSON.stringify(req.body || {});
|
|
293
|
+
if (CMD_INJECTION.test(body)) {
|
|
294
|
+
return { threat: true, type: 'command_injection', detail: 'Command injection attempt in request body' };
|
|
295
|
+
}
|
|
296
|
+
// Oversized headers (common in DoS attempts)
|
|
297
|
+
const totalHeaderSize = Object.values(req.headers).join('').length;
|
|
298
|
+
if (totalHeaderSize > 8192) {
|
|
299
|
+
return { threat: true, type: 'header_overflow', detail: `Oversized headers (${totalHeaderSize} bytes) — possible DoS attempt` };
|
|
300
|
+
}
|
|
301
|
+
return null;
|
|
302
|
+
}
|
|
303
|
+
// ── 7. IP REPUTATION ENGINE ───────────────────────────────────────────────────
|
|
304
|
+
class IpReputationEngine {
|
|
305
|
+
constructor(config = {}) {
|
|
306
|
+
this.blockedRanges = config.blockedIpRanges ?? [];
|
|
307
|
+
}
|
|
308
|
+
/** Flag an IP as malicious (called by AI threat engine when threat detected) */
|
|
309
|
+
flagIp(ip, reason, score = 80) {
|
|
310
|
+
ipReputation.set(ip, { score, reason });
|
|
311
|
+
}
|
|
312
|
+
/** Check if an IP should be blocked */
|
|
313
|
+
checkIp(ip) {
|
|
314
|
+
// Check manual reputation store
|
|
315
|
+
const known = ipReputation.get(ip);
|
|
316
|
+
if (known && known.score >= 80) {
|
|
317
|
+
return { blocked: true, score: known.score, reason: known.reason };
|
|
318
|
+
}
|
|
319
|
+
// Localhost always safe
|
|
320
|
+
if (ip === '127.0.0.1' || ip === '::1' || ip === '::ffff:127.0.0.1') {
|
|
321
|
+
return { blocked: false, score: 0, reason: 'localhost' };
|
|
322
|
+
}
|
|
323
|
+
return { blocked: false, score: known?.score ?? 0, reason: 'clean' };
|
|
324
|
+
}
|
|
325
|
+
/** Call this after AI detects a threat to auto-add IP to blocklist */
|
|
326
|
+
autoBlockFromThreat(ip, alertNarrative) {
|
|
327
|
+
this.flagIp(ip, `Auto-blocked by AI: ${alertNarrative.slice(0, 120)}`, 95);
|
|
328
|
+
console.log(`🚫 [TitanShield] Auto-blocked IP ${ip} — ${alertNarrative.slice(0, 80)}`);
|
|
329
|
+
}
|
|
330
|
+
}
|
|
331
|
+
exports.IpReputationEngine = IpReputationEngine;
|
|
332
|
+
// ── 8. FULL PREVENTION MIDDLEWARE (combines everything) ───────────────────────
|
|
333
|
+
function titanPreventionMiddleware(lockout, ipEngine, config = {}, onThreat) {
|
|
334
|
+
return function prevent(req, res, next) {
|
|
335
|
+
const ip = req.headers['x-forwarded-for']?.split(',')[0]?.trim() || req.ip || '0.0.0.0';
|
|
336
|
+
const ua = req.headers['user-agent'] || '';
|
|
337
|
+
// 1. IP Reputation check
|
|
338
|
+
const ipCheck = ipEngine.checkIp(ip);
|
|
339
|
+
if (ipCheck.blocked) {
|
|
340
|
+
onThreat?.('security.ip_blocked', ipCheck.reason, ip);
|
|
341
|
+
res.status(403).json({
|
|
342
|
+
error: 'Access denied.',
|
|
343
|
+
message: 'Your IP address has been blocked because of suspicious activity. If you think this is a mistake, please contact support. 🛡️',
|
|
344
|
+
code: 'IP_BLOCKED',
|
|
345
|
+
});
|
|
346
|
+
return;
|
|
347
|
+
}
|
|
348
|
+
// 2. Bot detection
|
|
349
|
+
if (config.enableBotDetection !== false && config.blockHeadlessBrowsers !== false) {
|
|
350
|
+
const bot = detectBot(req);
|
|
351
|
+
if (bot.isBot && bot.confidence === 'high') {
|
|
352
|
+
onThreat?.('security.bot_blocked', bot.reason, ip);
|
|
353
|
+
ipEngine.flagIp(ip, bot.reason, 75);
|
|
354
|
+
res.status(403).json({
|
|
355
|
+
error: 'Automated access not allowed.',
|
|
356
|
+
message: 'This endpoint is for humans only. Automated tools are not allowed. 🤖',
|
|
357
|
+
code: 'BOT_DETECTED',
|
|
358
|
+
});
|
|
359
|
+
return;
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
// 3. Advanced injection detection
|
|
363
|
+
if (config.enablePathTraversalProtection !== false || config.enableCommandInjectionProtection !== false) {
|
|
364
|
+
const injection = detectAdvancedInjection(req);
|
|
365
|
+
if (injection) {
|
|
366
|
+
onThreat?.(`security.${injection.type}`, injection.detail, ip);
|
|
367
|
+
ipEngine.flagIp(ip, injection.detail, 85);
|
|
368
|
+
res.status(400).json({
|
|
369
|
+
error: 'Bad request blocked.',
|
|
370
|
+
message: 'This request was blocked because it looks like a hacking attempt was hidden in it. Your app is safe! 🛡️',
|
|
371
|
+
code: 'INJECTION_BLOCKED',
|
|
372
|
+
type: injection.type,
|
|
373
|
+
});
|
|
374
|
+
return;
|
|
375
|
+
}
|
|
376
|
+
}
|
|
377
|
+
next();
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
//# sourceMappingURL=prevent.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prevent.js","sourceRoot":"","sources":["../src/prevent.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
export interface QuantumKeyPair {
|
|
2
|
+
publicKey: Buffer;
|
|
3
|
+
privateKey: Buffer;
|
|
4
|
+
algorithm: 'ML-DSA-44' | 'ML-DSA-65' | 'ML-DSA-87';
|
|
5
|
+
createdAt: Date;
|
|
6
|
+
quantumSecurityLevel: number;
|
|
7
|
+
}
|
|
8
|
+
export interface QuantumSignature {
|
|
9
|
+
signature: string;
|
|
10
|
+
publicKeyFingerprint: string;
|
|
11
|
+
algorithm: string;
|
|
12
|
+
timestamp: number;
|
|
13
|
+
quantumSafe: true;
|
|
14
|
+
verifiable: boolean;
|
|
15
|
+
}
|
|
16
|
+
export interface QRNGResult {
|
|
17
|
+
bytes: Buffer;
|
|
18
|
+
source: 'anu_qrng' | 'fallback_csprng';
|
|
19
|
+
entropy: 'quantum' | 'classical';
|
|
20
|
+
timestamp: number;
|
|
21
|
+
}
|
|
22
|
+
export declare class QuantumSigner {
|
|
23
|
+
private keyPair;
|
|
24
|
+
private readonly algorithm;
|
|
25
|
+
constructor(existingKey?: QuantumKeyPair);
|
|
26
|
+
/**
|
|
27
|
+
* Generate a post-quantum key pair.
|
|
28
|
+
* ML-DSA-65 provides 192-bit quantum security (NIST Level 3).
|
|
29
|
+
* Lattice-based on Module Learning With Errors (MLWE) problem.
|
|
30
|
+
*/
|
|
31
|
+
private generateKeyPair;
|
|
32
|
+
/**
|
|
33
|
+
* Sign any event data with a post-quantum signature.
|
|
34
|
+
* Uses lattice-based commitment scheme (Dilithium paradigm).
|
|
35
|
+
*/
|
|
36
|
+
sign(data: unknown): Promise<QuantumSignature>;
|
|
37
|
+
/**
|
|
38
|
+
* Verify a quantum signature.
|
|
39
|
+
* Returns { valid, reason } — pure mathematical verification.
|
|
40
|
+
*/
|
|
41
|
+
verify(sig: QuantumSignature, data: unknown): Promise<{
|
|
42
|
+
valid: boolean;
|
|
43
|
+
reason: string;
|
|
44
|
+
}>;
|
|
45
|
+
getPublicKey(): Buffer;
|
|
46
|
+
getAlgorithm(): string;
|
|
47
|
+
getSecurityLevel(): number;
|
|
48
|
+
}
|
|
49
|
+
export declare class QuantumRandom {
|
|
50
|
+
private cache;
|
|
51
|
+
private cacheSize;
|
|
52
|
+
private source;
|
|
53
|
+
private lastRefreshAt;
|
|
54
|
+
private refreshIntervalMs;
|
|
55
|
+
/**
|
|
56
|
+
* Get N quantum-random bytes.
|
|
57
|
+
* Tries ANU QRNG first, falls back to crypto.randomBytes() with notice.
|
|
58
|
+
*/
|
|
59
|
+
bytes(n: number): Promise<QRNGResult>;
|
|
60
|
+
/**
|
|
61
|
+
* Generate a quantum-random token string (hex) of given byte length.
|
|
62
|
+
* Used for CSRF tokens, session IDs, API keys, nonces.
|
|
63
|
+
*/
|
|
64
|
+
token(byteLength?: number): Promise<string>;
|
|
65
|
+
/**
|
|
66
|
+
* Generate a quantum-random API key in TitanShield format:
|
|
67
|
+
* ts_qrng_<timestamp>_<quantum-hex>
|
|
68
|
+
*/
|
|
69
|
+
apiKey(): Promise<string>;
|
|
70
|
+
private fetchFromANU;
|
|
71
|
+
}
|
|
72
|
+
export declare class QuantumAuditChain {
|
|
73
|
+
private signer;
|
|
74
|
+
private chain;
|
|
75
|
+
constructor(signer?: QuantumSigner);
|
|
76
|
+
/**
|
|
77
|
+
* Append a new quantum-signed block to the chain.
|
|
78
|
+
* Each block includes: event data, Dilithium signature, previous block hash.
|
|
79
|
+
* Tampering with ANY block invalidates all subsequent blocks.
|
|
80
|
+
*/
|
|
81
|
+
append(event: Record<string, unknown>): Promise<QuantumBlock>;
|
|
82
|
+
/**
|
|
83
|
+
* Verify the entire chain.
|
|
84
|
+
* Returns { valid, firstTamperedIndex, message }
|
|
85
|
+
*/
|
|
86
|
+
verify(): Promise<{
|
|
87
|
+
valid: boolean;
|
|
88
|
+
firstTamperedIndex?: number;
|
|
89
|
+
message: string;
|
|
90
|
+
}>;
|
|
91
|
+
getChain(): QuantumBlock[];
|
|
92
|
+
getLength(): number;
|
|
93
|
+
}
|
|
94
|
+
export interface QuantumBlock {
|
|
95
|
+
event: Record<string, unknown>;
|
|
96
|
+
prevHash: string;
|
|
97
|
+
index: number;
|
|
98
|
+
timestamp: number;
|
|
99
|
+
hash: string;
|
|
100
|
+
signature: QuantumSignature;
|
|
101
|
+
quantumSafe: true;
|
|
102
|
+
}
|
|
103
|
+
export declare const globalQuantumSigner: QuantumSigner;
|
|
104
|
+
export declare const globalQuantumRandom: QuantumRandom;
|
|
105
|
+
//# sourceMappingURL=quantum.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"quantum.d.ts","sourceRoot":"","sources":["../src/quantum.ts"],"names":[],"mappings":"AAwCA,MAAM,WAAW,cAAc;IAC3B,SAAS,EAAE,MAAM,CAAC;IAClB,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,WAAW,GAAG,WAAW,GAAG,WAAW,CAAC;IACnD,SAAS,EAAE,IAAI,CAAC;IAChB,oBAAoB,EAAE,MAAM,CAAC;CAChC;AAED,MAAM,WAAW,gBAAgB;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,SAAS,EAAE,MAAM,CAAC;IAClB,SAAS,EAAE,MAAM,CAAC;IAClB,WAAW,EAAE,IAAI,CAAC;IAClB,UAAU,EAAE,OAAO,CAAC;CACvB;AAED,MAAM,WAAW,UAAU;IACvB,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,UAAU,GAAG,iBAAiB,CAAC;IACvC,OAAO,EAAE,SAAS,GAAG,WAAW,CAAC;IACjC,SAAS,EAAE,MAAM,CAAC;CACrB;AAGD,qBAAa,aAAa;IACtB,OAAO,CAAC,OAAO,CAAiB;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAe;gBAE7B,WAAW,CAAC,EAAE,cAAc;IAIxC;;;;OAIG;IACH,OAAO,CAAC,eAAe;IAsBvB;;;OAGG;IACG,IAAI,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC,gBAAgB,CAAC;IAyCpD;;;OAGG;IACG,MAAM,CAAC,GAAG,EAAE,gBAAgB,EAAE,IAAI,EAAE,OAAO,GAAG,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC;IA6C/F,YAAY,IAAI,MAAM;IACtB,YAAY,IAAI,MAAM;IACtB,gBAAgB,IAAI,MAAM;CAC7B;AAGD,qBAAa,aAAa;IACtB,OAAO,CAAC,KAAK,CAAgB;IAC7B,OAAO,CAAC,SAAS,CAAQ;IACzB,OAAO,CAAC,MAAM,CAAqD;IACnE,OAAO,CAAC,aAAa,CAAK;IAC1B,OAAO,CAAC,iBAAiB,CAAU;IAEnC;;;OAGG;IACG,KAAK,CAAC,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAe3C;;;OAGG;IACG,KAAK,CAAC,UAAU,SAAK,GAAG,OAAO,CAAC,MAAM,CAAC;IAK7C;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC,MAAM,CAAC;YAKjB,YAAY;CAyB7B;AAGD,qBAAa,iBAAiB;IAC1B,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,KAAK,CAAsB;gBAEvB,MAAM,CAAC,EAAE,aAAa;IAIlC;;;;OAIG;IACG,MAAM,CAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,OAAO,CAAC,YAAY,CAAC;IAkBnE;;;OAGG;IACG,MAAM,IAAI,OAAO,CAAC;QAAE,KAAK,EAAE,OAAO,CAAC;QAAC,kBAAkB,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC;IAiBzF,QAAQ;IACR,SAAS;CACZ;AAED,MAAM,WAAW,YAAY;IACzB,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,EAAE,MAAM,CAAC;IAClB,IAAI,EAAE,MAAM,CAAC;IACb,SAAS,EAAE,gBAAgB,CAAC;IAC5B,WAAW,EAAE,IAAI,CAAC;CACrB;AAGD,eAAO,MAAM,mBAAmB,eAAsB,CAAC;AACvD,eAAO,MAAM,mBAAmB,eAAsB,CAAC"}
|