claude-flow-novice 1.6.2 → 1.6.4
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/.claude/settings.json +16 -5
- package/.claude/settings.local.json +3 -2
- package/.claude-flow-novice/dist/src/api/auth-service.js +84 -38
- package/.claude-flow-novice/dist/src/api/auth-service.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/index.js +3 -0
- package/.claude-flow-novice/dist/src/coordination/index.js.map +1 -1
- package/.claude-flow-novice/dist/src/coordination/v1-transparency/interfaces/v1-transparency-system.js +12 -0
- package/.claude-flow-novice/dist/src/coordination/v1-transparency/interfaces/v1-transparency-system.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v1-transparency/v1-to-v2-bridge.js +433 -0
- package/.claude-flow-novice/dist/src/coordination/v1-transparency/v1-to-v2-bridge.js.map +1 -0
- package/.claude-flow-novice/dist/src/coordination/v1-transparency/v1-transparency-adapter.js +1468 -0
- package/.claude-flow-novice/dist/src/coordination/v1-transparency/v1-transparency-adapter.js.map +1 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/apm-integration.js +724 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/apm-integration.js.map +1 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/datadog-collector.js +363 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/datadog-collector.js.map +1 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/index.js +97 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/index.js.map +1 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/newrelic-collector.js +384 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/newrelic-collector.js.map +1 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/performance-optimizer.js +612 -0
- package/.claude-flow-novice/dist/src/monitoring/apm/performance-optimizer.js.map +1 -0
- package/.claude-flow-novice/dist/src/monitoring/metrics-collector.js +282 -0
- package/.claude-flow-novice/dist/src/monitoring/metrics-collector.js.map +1 -0
- package/.claude-flow-novice/dist/src/providers/provider-manager.js +5 -3
- package/.claude-flow-novice/dist/src/providers/provider-manager.js.map +1 -1
- package/.claude-flow-novice/dist/src/providers/tiered-router.js +9 -17
- package/.claude-flow-novice/dist/src/providers/tiered-router.js.map +1 -1
- package/.claude-flow-novice/dist/src/web/api/apm-routes.js +355 -0
- package/.claude-flow-novice/dist/src/web/api/apm-routes.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/frontend/src/utils/security.js +425 -0
- package/.claude-flow-novice/dist/src/web/frontend/src/utils/security.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/security/security-middleware.js +379 -0
- package/.claude-flow-novice/dist/src/web/security/security-middleware.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/websocket/apm-websocket-handler.js +441 -0
- package/.claude-flow-novice/dist/src/web/websocket/apm-websocket-handler.js.map +1 -0
- package/.claude-flow-novice/dist/src/web/websocket/websocket-manager.js +255 -1
- package/.claude-flow-novice/dist/src/web/websocket/websocket-manager.js.map +1 -1
- package/.claude-flow-novice/metrics.db +0 -0
- package/AGENT_PERFORMANCE_GUIDELINES.md +88 -0
- package/CLAUDE.md +103 -3
- package/config/hooks/post-edit-pipeline.js +68 -118
- package/config/hooks/pre-tool-memory-safety.js +209 -0
- package/package.json +9 -4
- package/scripts/cleanup-idle-sessions.sh +59 -0
- package/scripts/monitor-loop.sh +65 -0
- package/scripts/monitor-memory.sh +47 -0
- package/scripts/monitor.py +43 -0
- package/scripts/test-provider-routing.cjs +7 -9
- package/wiki/Provider-Routing.md +57 -69
- package/.claude-flow-novice/metrics.db-shm +0 -0
- package/.claude-flow-novice/metrics.db-wal +0 -0
|
@@ -0,0 +1,425 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Security Utilities for Frontend Application
|
|
3
|
+
* Comprehensive security measures for XSS protection, input validation, and secure data handling
|
|
4
|
+
*/ // Content Security Policy helper
|
|
5
|
+
export const CSP_CONSTANTS = {
|
|
6
|
+
DEFAULT_SRC: "'self'",
|
|
7
|
+
SCRIPT_SRC: "'self' 'unsafe-inline' 'unsafe-eval'",
|
|
8
|
+
STYLE_SRC: "'self' 'unsafe-inline'",
|
|
9
|
+
IMG_SRC: "'self' data: https:",
|
|
10
|
+
CONNECT_SRC: "'self' ws: wss:",
|
|
11
|
+
FONT_SRC: "'self' data:",
|
|
12
|
+
OBJECT_SRC: "'none'",
|
|
13
|
+
MEDIA_SRC: "'self'",
|
|
14
|
+
FRAME_SRC: "'none'",
|
|
15
|
+
CHILD_SRC: "'none'",
|
|
16
|
+
WORKER_SRC: "'self'",
|
|
17
|
+
MANIFEST_SRC: "'self'",
|
|
18
|
+
UPGRADE_INSECURE_REQUESTS: true
|
|
19
|
+
};
|
|
20
|
+
// Security headers helper
|
|
21
|
+
export const addSecurityHeaders = (headers)=>{
|
|
22
|
+
return {
|
|
23
|
+
...headers,
|
|
24
|
+
'Content-Security-Policy': Object.entries(CSP_CONSTANTS).map(([key, value])=>{
|
|
25
|
+
const cspKey = key.replace('_', '-').toLowerCase();
|
|
26
|
+
return `${cspKey} ${Array.isArray(value) ? value.join(' ') : value}`;
|
|
27
|
+
}).join('; '),
|
|
28
|
+
'X-Content-Type-Options': 'nosniff',
|
|
29
|
+
'X-Frame-Options': 'DENY',
|
|
30
|
+
'X-XSS-Protection': '1; mode=block',
|
|
31
|
+
'Referrer-Policy': 'strict-origin-when-cross-origin',
|
|
32
|
+
'Permissions-Policy': 'geolocation=(), microphone=(), camera=(), payment=()',
|
|
33
|
+
'Strict-Transport-Security': 'max-age=31536000; includeSubDomains'
|
|
34
|
+
};
|
|
35
|
+
};
|
|
36
|
+
// Sanitization utilities
|
|
37
|
+
export class ContentSanitizer {
|
|
38
|
+
static allowedTags = [
|
|
39
|
+
'p',
|
|
40
|
+
'br',
|
|
41
|
+
'strong',
|
|
42
|
+
'em',
|
|
43
|
+
'u',
|
|
44
|
+
'ol',
|
|
45
|
+
'ul',
|
|
46
|
+
'li',
|
|
47
|
+
'h1',
|
|
48
|
+
'h2',
|
|
49
|
+
'h3',
|
|
50
|
+
'h4',
|
|
51
|
+
'h5',
|
|
52
|
+
'h6',
|
|
53
|
+
'blockquote',
|
|
54
|
+
'code',
|
|
55
|
+
'pre'
|
|
56
|
+
];
|
|
57
|
+
static allowedAttributes = {
|
|
58
|
+
'a': [
|
|
59
|
+
'href',
|
|
60
|
+
'title',
|
|
61
|
+
'target'
|
|
62
|
+
],
|
|
63
|
+
'img': [
|
|
64
|
+
'src',
|
|
65
|
+
'alt',
|
|
66
|
+
'title',
|
|
67
|
+
'width',
|
|
68
|
+
'height'
|
|
69
|
+
]
|
|
70
|
+
};
|
|
71
|
+
static dangerousPatterns = [
|
|
72
|
+
/javascript:/gi,
|
|
73
|
+
/data:(?!image\/)/gi,
|
|
74
|
+
/vbscript:/gi,
|
|
75
|
+
/on\w+\s*=/gi,
|
|
76
|
+
/<script/gi,
|
|
77
|
+
/<iframe/gi,
|
|
78
|
+
/<object/gi,
|
|
79
|
+
/<embed/gi,
|
|
80
|
+
/<link/gi,
|
|
81
|
+
/<meta/gi,
|
|
82
|
+
/@import/gi,
|
|
83
|
+
/expression\(/gi
|
|
84
|
+
];
|
|
85
|
+
static sanitizeHTML(html) {
|
|
86
|
+
let sanitized = html;
|
|
87
|
+
// Remove dangerous patterns
|
|
88
|
+
this.dangerousPatterns.forEach((pattern)=>{
|
|
89
|
+
sanitized = sanitized.replace(pattern, '');
|
|
90
|
+
});
|
|
91
|
+
// Basic HTML tag removal for now (will be enhanced with DOMPurify)
|
|
92
|
+
sanitized = sanitized.replace(/<[^>]*>/g, '');
|
|
93
|
+
// Encode special characters
|
|
94
|
+
sanitized = this.encodeHTMLEntities(sanitized);
|
|
95
|
+
return sanitized;
|
|
96
|
+
}
|
|
97
|
+
static sanitizeText(text) {
|
|
98
|
+
return this.encodeHTMLEntities(text).replace(/[\x00-\x1F\x7F]/g, '').substring(0, 10000).trim();
|
|
99
|
+
}
|
|
100
|
+
static sanitizeURL(url) {
|
|
101
|
+
try {
|
|
102
|
+
const parsed = new URL(url, window.location.origin);
|
|
103
|
+
// Only allow http, https protocols
|
|
104
|
+
if (![
|
|
105
|
+
'http:',
|
|
106
|
+
'https:'
|
|
107
|
+
].includes(parsed.protocol)) {
|
|
108
|
+
return '#';
|
|
109
|
+
}
|
|
110
|
+
// Remove dangerous parts
|
|
111
|
+
parsed.hash = '';
|
|
112
|
+
parsed.username = '';
|
|
113
|
+
parsed.password = '';
|
|
114
|
+
return parsed.toString();
|
|
115
|
+
} catch {
|
|
116
|
+
return '#';
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
static encodeHTMLEntities(text) {
|
|
120
|
+
const entityMap = {
|
|
121
|
+
'&': '&',
|
|
122
|
+
'<': '<',
|
|
123
|
+
'>': '>',
|
|
124
|
+
'"': '"',
|
|
125
|
+
"'": ''',
|
|
126
|
+
'/': '/'
|
|
127
|
+
};
|
|
128
|
+
return text.replace(/[&<>"'/]/g, (char)=>entityMap[char] || char);
|
|
129
|
+
}
|
|
130
|
+
static validateCSS(css) {
|
|
131
|
+
const dangerousCSS = [
|
|
132
|
+
/javascript:/gi,
|
|
133
|
+
/expression\(/gi,
|
|
134
|
+
/@import/gi,
|
|
135
|
+
/binding\(/gi,
|
|
136
|
+
/behavior\s*:/gi
|
|
137
|
+
];
|
|
138
|
+
return !dangerousCSS.some((pattern)=>pattern.test(css));
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
// Input validation utilities
|
|
142
|
+
export class InputValidator {
|
|
143
|
+
static patterns = {
|
|
144
|
+
email: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
|
|
145
|
+
url: /^https?:\/\/.+/,
|
|
146
|
+
phone: /^\+?[\d\s\-\(\)]+$/,
|
|
147
|
+
alphanumeric: /^[a-zA-Z0-9]+$/,
|
|
148
|
+
numeric: /^[0-9]*\.?[0-9]+$/,
|
|
149
|
+
safeFilename: /^[a-zA-Z0-9._-]+$/
|
|
150
|
+
};
|
|
151
|
+
static validateEmail(email) {
|
|
152
|
+
return this.patterns.email.test(email) && email.length <= 254;
|
|
153
|
+
}
|
|
154
|
+
static validateURL(url) {
|
|
155
|
+
return this.patterns.url.test(url) && url.length <= 2048;
|
|
156
|
+
}
|
|
157
|
+
static validatePhone(phone) {
|
|
158
|
+
return this.patterns.phone.test(phone) && phone.length <= 20;
|
|
159
|
+
}
|
|
160
|
+
static validateLength(input, min, max) {
|
|
161
|
+
return input.length >= min && input.length <= max;
|
|
162
|
+
}
|
|
163
|
+
static validateNoSQL(input) {
|
|
164
|
+
const noSQLPatterns = [
|
|
165
|
+
/\$where/gi,
|
|
166
|
+
/\$gt/gi,
|
|
167
|
+
/\$lt/gi,
|
|
168
|
+
/\$ne/gi,
|
|
169
|
+
/\$in/gi,
|
|
170
|
+
/\$nin/gi,
|
|
171
|
+
/\{.*\$.*\}/gi,
|
|
172
|
+
/javascript:/gi,
|
|
173
|
+
/eval\(/gi
|
|
174
|
+
];
|
|
175
|
+
return !noSQLPatterns.some((pattern)=>pattern.test(input));
|
|
176
|
+
}
|
|
177
|
+
static validateSQL(input) {
|
|
178
|
+
const sqlPatterns = [
|
|
179
|
+
/drop\s+table/gi,
|
|
180
|
+
/delete\s+from/gi,
|
|
181
|
+
/insert\s+into/gi,
|
|
182
|
+
/update\s+.*set/gi,
|
|
183
|
+
/union\s+select/gi,
|
|
184
|
+
/exec\s*\(/gi,
|
|
185
|
+
/script\s*>/gi,
|
|
186
|
+
/--/gi,
|
|
187
|
+
/\/\*/gi,
|
|
188
|
+
/\*\//gi
|
|
189
|
+
];
|
|
190
|
+
return !sqlPatterns.some((pattern)=>pattern.test(input));
|
|
191
|
+
}
|
|
192
|
+
static sanitizeFilename(filename) {
|
|
193
|
+
return filename.replace(/[^a-zA-Z0-9._-]/g, '_').replace(/_{2,}/g, '_').toLowerCase().substring(0, 255);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
// CSRF protection utilities
|
|
197
|
+
export class CSRFProtection {
|
|
198
|
+
static token = null;
|
|
199
|
+
static generateToken() {
|
|
200
|
+
const token = Array.from(crypto.getRandomValues(new Uint8Array(32))).map((b)=>b.toString(16).padStart(2, '0')).join('');
|
|
201
|
+
this.token = token;
|
|
202
|
+
this.storeToken(token);
|
|
203
|
+
return token;
|
|
204
|
+
}
|
|
205
|
+
static getToken() {
|
|
206
|
+
if (!this.token) {
|
|
207
|
+
this.token = this.retrieveToken();
|
|
208
|
+
}
|
|
209
|
+
return this.token;
|
|
210
|
+
}
|
|
211
|
+
static validateToken(token) {
|
|
212
|
+
const storedToken = this.getToken();
|
|
213
|
+
return storedToken !== null && storedToken === token;
|
|
214
|
+
}
|
|
215
|
+
static storeToken(token) {
|
|
216
|
+
try {
|
|
217
|
+
sessionStorage.setItem('csrf-token', token);
|
|
218
|
+
} catch (error) {
|
|
219
|
+
console.warn('Could not store CSRF token:', error);
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
static retrieveToken() {
|
|
223
|
+
try {
|
|
224
|
+
return sessionStorage.getItem('csrf-token');
|
|
225
|
+
} catch (error) {
|
|
226
|
+
console.warn('Could not retrieve CSRF token:', error);
|
|
227
|
+
return null;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
static addToFormData(formData) {
|
|
231
|
+
const token = this.getToken();
|
|
232
|
+
if (token) {
|
|
233
|
+
formData.append('csrf-token', token);
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
static addToHeaders(headers) {
|
|
237
|
+
const token = this.getToken();
|
|
238
|
+
if (token) {
|
|
239
|
+
headers['X-CSRF-Token'] = token;
|
|
240
|
+
}
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
// Secure storage utilities
|
|
244
|
+
export class SecureStorage {
|
|
245
|
+
static encryptionKey = 'claude-flow-secure-storage';
|
|
246
|
+
static setItem(key, value, useEncryption = true) {
|
|
247
|
+
try {
|
|
248
|
+
const serializedValue = JSON.stringify(value);
|
|
249
|
+
const finalValue = useEncryption ? this.simpleEncrypt(serializedValue) : serializedValue;
|
|
250
|
+
localStorage.setItem(key, finalValue);
|
|
251
|
+
} catch (error) {
|
|
252
|
+
console.warn('Could not store item:', error);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
static getItem(key, useEncryption = true) {
|
|
256
|
+
try {
|
|
257
|
+
const storedValue = localStorage.getItem(key);
|
|
258
|
+
if (!storedValue) return null;
|
|
259
|
+
const decryptedValue = useEncryption ? this.simpleDecrypt(storedValue) : storedValue;
|
|
260
|
+
return JSON.parse(decryptedValue);
|
|
261
|
+
} catch (error) {
|
|
262
|
+
console.warn('Could not retrieve item:', error);
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
static removeItem(key) {
|
|
267
|
+
try {
|
|
268
|
+
localStorage.removeItem(key);
|
|
269
|
+
} catch (error) {
|
|
270
|
+
console.warn('Could not remove item:', error);
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
static clear() {
|
|
274
|
+
try {
|
|
275
|
+
localStorage.clear();
|
|
276
|
+
} catch (error) {
|
|
277
|
+
console.warn('Could not clear storage:', error);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
static simpleEncrypt(text) {
|
|
281
|
+
// Simple XOR encryption (not production-grade, but better than plaintext)
|
|
282
|
+
const key = this.encryptionKey;
|
|
283
|
+
let result = '';
|
|
284
|
+
for(let i = 0; i < text.length; i++){
|
|
285
|
+
result += String.fromCharCode(text.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
|
286
|
+
}
|
|
287
|
+
return btoa(result);
|
|
288
|
+
}
|
|
289
|
+
static simpleDecrypt(encryptedText) {
|
|
290
|
+
try {
|
|
291
|
+
const key = this.encryptionKey;
|
|
292
|
+
const decoded = atob(encryptedText);
|
|
293
|
+
let result = '';
|
|
294
|
+
for(let i = 0; i < decoded.length; i++){
|
|
295
|
+
result += String.fromCharCode(decoded.charCodeAt(i) ^ key.charCodeAt(i % key.length));
|
|
296
|
+
}
|
|
297
|
+
return result;
|
|
298
|
+
} catch (error) {
|
|
299
|
+
return '';
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
}
|
|
303
|
+
// Security event logging
|
|
304
|
+
export class SecurityLogger {
|
|
305
|
+
static logEndpoint = '/api/security-events';
|
|
306
|
+
static logSecurityEvent(event) {
|
|
307
|
+
const securityEvent = {
|
|
308
|
+
...event,
|
|
309
|
+
timestamp: event.timestamp || Date.now(),
|
|
310
|
+
userAgent: navigator.userAgent,
|
|
311
|
+
url: window.location.href,
|
|
312
|
+
sessionId: this.getSessionId()
|
|
313
|
+
};
|
|
314
|
+
// Log to console in development
|
|
315
|
+
if (process.env.NODE_ENV === 'development') {
|
|
316
|
+
console.warn('Security Event:', securityEvent);
|
|
317
|
+
}
|
|
318
|
+
// Store locally for debugging
|
|
319
|
+
this.storeLocalEvent(securityEvent);
|
|
320
|
+
// Send to server (in production)
|
|
321
|
+
if (process.env.NODE_ENV === 'production') {
|
|
322
|
+
this.sendToServer(securityEvent);
|
|
323
|
+
}
|
|
324
|
+
}
|
|
325
|
+
static getSessionId() {
|
|
326
|
+
let sessionId = sessionStorage.getItem('security-session-id');
|
|
327
|
+
if (!sessionId) {
|
|
328
|
+
sessionId = `session-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
329
|
+
sessionStorage.setItem('security-session-id', sessionId);
|
|
330
|
+
}
|
|
331
|
+
return sessionId;
|
|
332
|
+
}
|
|
333
|
+
static storeLocalEvent(event) {
|
|
334
|
+
try {
|
|
335
|
+
const events = JSON.parse(localStorage.getItem('security-events') || '[]');
|
|
336
|
+
events.push(event);
|
|
337
|
+
// Keep only last 100 events
|
|
338
|
+
if (events.length > 100) {
|
|
339
|
+
events.splice(0, events.length - 100);
|
|
340
|
+
}
|
|
341
|
+
localStorage.setItem('security-events', JSON.stringify(events));
|
|
342
|
+
} catch (error) {
|
|
343
|
+
console.warn('Could not store security event:', error);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
static async sendToServer(event) {
|
|
347
|
+
try {
|
|
348
|
+
await fetch(this.logEndpoint, {
|
|
349
|
+
method: 'POST',
|
|
350
|
+
headers: {
|
|
351
|
+
'Content-Type': 'application/json'
|
|
352
|
+
},
|
|
353
|
+
body: JSON.stringify(event)
|
|
354
|
+
});
|
|
355
|
+
} catch (error) {
|
|
356
|
+
console.warn('Could not send security event to server:', error);
|
|
357
|
+
}
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
// Rate limiting utilities
|
|
361
|
+
export class RateLimiter {
|
|
362
|
+
static attempts = new Map();
|
|
363
|
+
static isAllowed(identifier, maxAttempts = 5, windowMs = 60000) {
|
|
364
|
+
const now = Date.now();
|
|
365
|
+
const attempts = this.attempts.get(identifier) || [];
|
|
366
|
+
// Remove old attempts outside the window
|
|
367
|
+
const validAttempts = attempts.filter((timestamp)=>now - timestamp < windowMs);
|
|
368
|
+
if (validAttempts.length >= maxAttempts) {
|
|
369
|
+
SecurityLogger.logSecurityEvent({
|
|
370
|
+
type: 'unauthorized_access',
|
|
371
|
+
severity: 'medium',
|
|
372
|
+
details: {
|
|
373
|
+
action: 'rate_limit_exceeded',
|
|
374
|
+
identifier,
|
|
375
|
+
attempts: validAttempts.length
|
|
376
|
+
}
|
|
377
|
+
});
|
|
378
|
+
return false;
|
|
379
|
+
}
|
|
380
|
+
// Add current attempt
|
|
381
|
+
validAttempts.push(now);
|
|
382
|
+
this.attempts.set(identifier, validAttempts);
|
|
383
|
+
return true;
|
|
384
|
+
}
|
|
385
|
+
static getRemainingAttempts(identifier, maxAttempts = 5, windowMs = 60000) {
|
|
386
|
+
const now = Date.now();
|
|
387
|
+
const attempts = this.attempts.get(identifier) || [];
|
|
388
|
+
const validAttempts = attempts.filter((timestamp)=>now - timestamp < windowMs);
|
|
389
|
+
return Math.max(0, maxAttempts - validAttempts.length);
|
|
390
|
+
}
|
|
391
|
+
static reset(identifier) {
|
|
392
|
+
this.attempts.delete(identifier);
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
// Security configuration
|
|
396
|
+
export const SECURITY_CONFIG = {
|
|
397
|
+
// Input limits
|
|
398
|
+
MAX_INPUT_LENGTH: 10000,
|
|
399
|
+
MAX_FILENAME_LENGTH: 255,
|
|
400
|
+
MAX_URL_LENGTH: 2048,
|
|
401
|
+
// Rate limiting
|
|
402
|
+
RATE_LIMIT: {
|
|
403
|
+
LOGIN_ATTEMPTS: 5,
|
|
404
|
+
LOGIN_WINDOW: 15 * 60 * 1000,
|
|
405
|
+
API_REQUESTS: 100,
|
|
406
|
+
API_WINDOW: 60 * 1000 // 1 minute
|
|
407
|
+
},
|
|
408
|
+
// Password requirements
|
|
409
|
+
PASSWORD: {
|
|
410
|
+
MIN_LENGTH: 8,
|
|
411
|
+
MAX_LENGTH: 128,
|
|
412
|
+
REQUIRE_UPPERCASE: true,
|
|
413
|
+
REQUIRE_LOWERCASE: true,
|
|
414
|
+
REQUIRE_NUMBERS: true,
|
|
415
|
+
REQUIRE_SPECIAL_CHARS: true
|
|
416
|
+
},
|
|
417
|
+
// Session settings
|
|
418
|
+
SESSION: {
|
|
419
|
+
TIMEOUT: 30 * 60 * 1000,
|
|
420
|
+
WARNING_TIMEOUT: 5 * 60 * 1000,
|
|
421
|
+
RENEWAL_THRESHOLD: 5 * 60 * 1000 // Renew if less than 5 minutes left
|
|
422
|
+
}
|
|
423
|
+
};
|
|
424
|
+
|
|
425
|
+
//# sourceMappingURL=security.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../../../../../../src/web/frontend/src/utils/security.ts"],"names":["CSP_CONSTANTS","DEFAULT_SRC","SCRIPT_SRC","STYLE_SRC","IMG_SRC","CONNECT_SRC","FONT_SRC","OBJECT_SRC","MEDIA_SRC","FRAME_SRC","CHILD_SRC","WORKER_SRC","MANIFEST_SRC","UPGRADE_INSECURE_REQUESTS","addSecurityHeaders","headers","Object","entries","map","key","value","cspKey","replace","toLowerCase","Array","isArray","join","ContentSanitizer","allowedTags","allowedAttributes","dangerousPatterns","sanitizeHTML","html","sanitized","forEach","pattern","encodeHTMLEntities","sanitizeText","text","substring","trim","sanitizeURL","url","parsed","URL","window","location","origin","includes","protocol","hash","username","password","toString","entityMap","char","validateCSS","css","dangerousCSS","some","test","InputValidator","patterns","email","phone","alphanumeric","numeric","safeFilename","validateEmail","length","validateURL","validatePhone","validateLength","input","min","max","validateNoSQL","noSQLPatterns","validateSQL","sqlPatterns","sanitizeFilename","filename","CSRFProtection","token","generateToken","from","crypto","getRandomValues","Uint8Array","b","padStart","storeToken","getToken","retrieveToken","validateToken","storedToken","sessionStorage","setItem","error","console","warn","getItem","addToFormData","formData","append","addToHeaders","SecureStorage","encryptionKey","useEncryption","serializedValue","JSON","stringify","finalValue","simpleEncrypt","localStorage","storedValue","decryptedValue","simpleDecrypt","parse","removeItem","clear","result","i","String","fromCharCode","charCodeAt","btoa","encryptedText","decoded","atob","SecurityLogger","logEndpoint","logSecurityEvent","event","securityEvent","timestamp","Date","now","userAgent","navigator","href","sessionId","getSessionId","process","env","NODE_ENV","storeLocalEvent","sendToServer","Math","random","substr","events","push","splice","fetch","method","body","RateLimiter","attempts","Map","isAllowed","identifier","maxAttempts","windowMs","get","validAttempts","filter","type","severity","details","action","set","getRemainingAttempts","reset","delete","SECURITY_CONFIG","MAX_INPUT_LENGTH","MAX_FILENAME_LENGTH","MAX_URL_LENGTH","RATE_LIMIT","LOGIN_ATTEMPTS","LOGIN_WINDOW","API_REQUESTS","API_WINDOW","PASSWORD","MIN_LENGTH","MAX_LENGTH","REQUIRE_UPPERCASE","REQUIRE_LOWERCASE","REQUIRE_NUMBERS","REQUIRE_SPECIAL_CHARS","SESSION","TIMEOUT","WARNING_TIMEOUT","RENEWAL_THRESHOLD"],"mappings":"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"}
|