-
Notifications
You must be signed in to change notification settings - Fork 302
Expand file tree
/
Copy pathsanitizeLog.ts
More file actions
78 lines (65 loc) · 1.78 KB
/
sanitizeLog.ts
File metadata and controls
78 lines (65 loc) · 1.78 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
/**
* Sanitizes sensitive data from logs to prevent token exposure in test/staging environments
*/
const SENSITIVE_KEYS = new Set([
'token',
'bearer',
'prv',
'xprv',
'privatekey',
'password',
'otp',
'passphrase',
'walletPassphrase',
]);
const BEARER_V2_PATTERN = /^v2x[a-f0-9]{32,}$/i;
/**
* Checks if a key is sensitive (case-insensitive)
*/
function isSensitiveKey(key: string): boolean {
return SENSITIVE_KEYS.has(key.toLowerCase());
}
/**
* Checks if a value matches the bearer v2 token pattern
*/
function isBearerV2Token(value: unknown): boolean {
return typeof value === 'string' && BEARER_V2_PATTERN.test(value);
}
/**
* Recursively sanitizes an object, replacing sensitive values with '<REMOVED>'
* Handles circular references and nested structures
*/
export function sanitize(obj: unknown, seen = new WeakSet<Record<string, unknown>>(), depth = 0): unknown {
// Prevent infinite recursion
if (depth > 50) {
return '[Max Depth Exceeded]';
}
// Handle primitives
if (obj === null || obj === undefined) {
return obj;
}
if (typeof obj !== 'object') {
return obj;
}
// Handle circular references
if (seen.has(obj as Record<string, unknown>)) {
return '[Circular]';
}
seen.add(obj as Record<string, unknown>);
// Handle arrays
if (Array.isArray(obj)) {
return obj.map((item) => sanitize(item, seen, depth + 1));
}
// Handle objects
const sanitized: Record<string, unknown> = {};
for (const [key, value] of Object.entries(obj)) {
if (isSensitiveKey(key) || isBearerV2Token(value)) {
sanitized[key] = '<REMOVED>';
} else if (typeof value === 'object' && value !== null) {
sanitized[key] = sanitize(value, seen, depth + 1);
} else {
sanitized[key] = value;
}
}
return sanitized;
}