cipher-security 2.1.0 → 2.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/bin/cipher.js +10 -0
- package/lib/analyze/consistency.js +566 -0
- package/lib/analyze/constitution.js +110 -0
- package/lib/analyze/sharding.js +251 -0
- package/lib/autonomous/agent-tool.js +165 -0
- package/lib/autonomous/framework.js +17 -0
- package/lib/autonomous/handoff.js +506 -0
- package/lib/autonomous/modes/blue.js +26 -0
- package/lib/autonomous/modes/red.js +28 -0
- package/lib/benchmark/agent.js +88 -26
- package/lib/benchmark/baselines.js +3 -0
- package/lib/benchmark/claude-code-solver.js +254 -0
- package/lib/benchmark/cognitive.js +283 -0
- package/lib/benchmark/index.js +12 -2
- package/lib/benchmark/knowledge.js +281 -0
- package/lib/benchmark/llm.js +156 -15
- package/lib/benchmark/models.js +5 -2
- package/lib/benchmark/nyu-ctf.js +192 -0
- package/lib/benchmark/overthewire.js +347 -0
- package/lib/benchmark/picoctf.js +281 -0
- package/lib/benchmark/prompts.js +280 -0
- package/lib/benchmark/registry.js +219 -0
- package/lib/benchmark/remote-solver.js +356 -0
- package/lib/benchmark/remote-target.js +263 -0
- package/lib/benchmark/reporter.js +35 -0
- package/lib/benchmark/runner.js +174 -10
- package/lib/benchmark/sandbox.js +35 -0
- package/lib/benchmark/scorer.js +22 -4
- package/lib/benchmark/solver.js +34 -1
- package/lib/benchmark/tools.js +262 -16
- package/lib/commands.js +9 -0
- package/lib/execution/council.js +434 -0
- package/lib/execution/parallel.js +292 -0
- package/lib/gates/circuit-breaker.js +135 -0
- package/lib/gates/confidence.js +302 -0
- package/lib/gates/corrections.js +219 -0
- package/lib/gates/self-check.js +245 -0
- package/lib/gateway/commands.js +727 -0
- package/lib/guardrails/engine.js +364 -0
- package/lib/mcp/server.js +349 -3
- package/lib/memory/compressor.js +94 -7
- package/lib/pipeline/hooks.js +288 -0
- package/lib/pipeline/index.js +11 -0
- package/lib/review/budget.js +210 -0
- package/lib/review/engine.js +526 -0
- package/lib/review/layers/acceptance-auditor.js +279 -0
- package/lib/review/layers/blind-hunter.js +500 -0
- package/lib/review/layers/defense-in-depth.js +209 -0
- package/lib/review/layers/edge-case-hunter.js +266 -0
- package/lib/review/panel.js +519 -0
- package/lib/review/two-stage.js +244 -0
- package/lib/session/cost-tracker.js +203 -0
- package/lib/session/logger.js +349 -0
- package/package.json +1 -1
|
@@ -0,0 +1,279 @@
|
|
|
1
|
+
// Copyright (c) 2026 defconxt. All rights reserved.
|
|
2
|
+
// Licensed under AGPL-3.0 — see LICENSE file for details.
|
|
3
|
+
// CIPHER is a trademark of defconxt.
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Acceptance Auditor — Security architecture review layer.
|
|
7
|
+
*
|
|
8
|
+
* Evaluates code from an architectural security perspective:
|
|
9
|
+
* authentication/authorization patterns, trust boundary crossings,
|
|
10
|
+
* OWASP Top 10 structural concerns, privilege escalation paths,
|
|
11
|
+
* and data flow integrity.
|
|
12
|
+
*
|
|
13
|
+
* @module review/layers/acceptance-auditor
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import { ReviewFinding, Severity } from '../engine.js';
|
|
17
|
+
|
|
18
|
+
// ---------------------------------------------------------------------------
|
|
19
|
+
// Pattern definitions
|
|
20
|
+
// ---------------------------------------------------------------------------
|
|
21
|
+
|
|
22
|
+
/** @type {import('./blind-hunter.js').VulnPattern[]} */
|
|
23
|
+
const PATTERNS = [
|
|
24
|
+
// ── Authentication / Authorization ────────────────────────────────────
|
|
25
|
+
{
|
|
26
|
+
id: 'AA-AUTH-001',
|
|
27
|
+
title: 'Route without authentication middleware',
|
|
28
|
+
pattern: /(?:app|router)\s*\.(?:get|post|put|patch|delete)\s*\(\s*['"][^'"]*(?:admin|user|account|profile|setting|dashboard|api\/v)[^'"]*['"]\s*,\s*(?:async\s+)?\(?(?:req|ctx)/g,
|
|
29
|
+
severity: Severity.HIGH,
|
|
30
|
+
cweIds: ['CWE-306'],
|
|
31
|
+
description: 'Sensitive route handler without authentication middleware in the chain.',
|
|
32
|
+
remediation: 'Add authentication middleware before the route handler: app.get("/admin", auth, handler).',
|
|
33
|
+
languages: ['javascript', 'typescript'],
|
|
34
|
+
tags: ['owasp-a07', 'T1078'],
|
|
35
|
+
exclude: /auth|authenticate|isAuthenticated|requireAuth|protect|guard|verify|login|register|signup|public|health|ping/i,
|
|
36
|
+
},
|
|
37
|
+
{
|
|
38
|
+
id: 'AA-AUTH-002',
|
|
39
|
+
title: 'Missing authorization check — direct ID access',
|
|
40
|
+
pattern: /(?:req\.params\.id|req\.params\.\w+Id|ctx\.params\.id)\s*(?:;|\))/g,
|
|
41
|
+
severity: Severity.MEDIUM,
|
|
42
|
+
cweIds: ['CWE-862'],
|
|
43
|
+
description: 'Resource accessed by user-supplied ID without ownership/permission verification.',
|
|
44
|
+
remediation: 'Verify the authenticated user owns or has permission to access the requested resource.',
|
|
45
|
+
languages: ['javascript', 'typescript'],
|
|
46
|
+
tags: ['owasp-a01', 'T1078'],
|
|
47
|
+
exclude: /authorize|permission|owns|owner|canAccess|hasPermission|role/i,
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
id: 'AA-AUTH-003',
|
|
51
|
+
title: 'Hardcoded role check — brittle authorization',
|
|
52
|
+
pattern: /(?:role|user\.role|req\.user\.role)\s*(?:===?|!==?|==)\s*['"](?:admin|root|superuser|moderator)['"]/g,
|
|
53
|
+
severity: Severity.LOW,
|
|
54
|
+
cweIds: ['CWE-863'],
|
|
55
|
+
description: 'Role checked with hardcoded string comparison. Fragile and hard to maintain.',
|
|
56
|
+
remediation: 'Use a permission/policy system (RBAC/ABAC) instead of hardcoded role strings.',
|
|
57
|
+
languages: ['javascript', 'typescript', 'python'],
|
|
58
|
+
tags: ['owasp-a01'],
|
|
59
|
+
},
|
|
60
|
+
|
|
61
|
+
// ── Session / Token Security ──────────────────────────────────────────
|
|
62
|
+
{
|
|
63
|
+
id: 'AA-SESS-001',
|
|
64
|
+
title: 'Session cookie without secure flags',
|
|
65
|
+
pattern: /(?:cookie|session)\s*(?::\s*\{|=\s*\{)[^}]*(?!secure\s*:\s*true)/g,
|
|
66
|
+
severity: Severity.MEDIUM,
|
|
67
|
+
cweIds: ['CWE-614'],
|
|
68
|
+
description: 'Session cookie configuration may be missing secure, httpOnly, or sameSite flags.',
|
|
69
|
+
remediation: 'Set cookie options: { secure: true, httpOnly: true, sameSite: "strict" }.',
|
|
70
|
+
languages: ['javascript', 'typescript'],
|
|
71
|
+
tags: ['owasp-a07'],
|
|
72
|
+
exclude: /secure\s*:\s*true.*httpOnly\s*:\s*true|httpOnly\s*:\s*true.*secure\s*:\s*true/,
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
id: 'AA-SESS-002',
|
|
76
|
+
title: 'JWT without expiration',
|
|
77
|
+
pattern: /jwt\.sign\s*\(\s*[^,]+\s*,\s*[^,]+\s*\)/g,
|
|
78
|
+
severity: Severity.MEDIUM,
|
|
79
|
+
cweIds: ['CWE-613'],
|
|
80
|
+
description: 'JWT signed without expiration (expiresIn) option. Tokens never expire.',
|
|
81
|
+
remediation: 'Add expiration: jwt.sign(payload, secret, { expiresIn: "1h" }).',
|
|
82
|
+
languages: ['javascript', 'typescript'],
|
|
83
|
+
tags: ['owasp-a07'],
|
|
84
|
+
exclude: /expiresIn|exp:/,
|
|
85
|
+
},
|
|
86
|
+
{
|
|
87
|
+
id: 'AA-SESS-003',
|
|
88
|
+
title: 'JWT secret from hardcoded string',
|
|
89
|
+
pattern: /jwt\.(?:sign|verify)\s*\([^)]*['"][a-zA-Z0-9]{8,}['"]/g,
|
|
90
|
+
severity: Severity.HIGH,
|
|
91
|
+
cweIds: ['CWE-798'],
|
|
92
|
+
description: 'JWT signing/verification using a hardcoded secret string.',
|
|
93
|
+
remediation: 'Load JWT secret from environment variable or secrets manager.',
|
|
94
|
+
languages: ['javascript', 'typescript'],
|
|
95
|
+
tags: ['owasp-a02'],
|
|
96
|
+
},
|
|
97
|
+
|
|
98
|
+
// ── Data Exposure ─────────────────────────────────────────────────────
|
|
99
|
+
{
|
|
100
|
+
id: 'AA-DATA-001',
|
|
101
|
+
title: 'Sensitive data in response — possible over-exposure',
|
|
102
|
+
pattern: /res\.(?:json|send)\s*\(\s*(?:user|account|profile|customer|patient|employee)/g,
|
|
103
|
+
severity: Severity.MEDIUM,
|
|
104
|
+
cweIds: ['CWE-200'],
|
|
105
|
+
description: 'Full object sent in response. May expose sensitive fields (password, SSN, tokens).',
|
|
106
|
+
remediation: 'Select specific fields to return. Use a DTO/serializer to strip sensitive data.',
|
|
107
|
+
languages: ['javascript', 'typescript'],
|
|
108
|
+
tags: ['owasp-a01', 'privacy'],
|
|
109
|
+
},
|
|
110
|
+
{
|
|
111
|
+
id: 'AA-DATA-002',
|
|
112
|
+
title: 'Error details leaked to client',
|
|
113
|
+
pattern: /res\.(?:json|send|status)\s*\([^)]*(?:err\.stack|err\.message|error\.stack|stack\s*:|stackTrace)/g,
|
|
114
|
+
severity: Severity.MEDIUM,
|
|
115
|
+
cweIds: ['CWE-209'],
|
|
116
|
+
description: 'Error stack trace or detailed message sent to client. Information disclosure.',
|
|
117
|
+
remediation: 'Return generic error messages to clients. Log full details server-side only.',
|
|
118
|
+
languages: ['javascript', 'typescript'],
|
|
119
|
+
tags: ['owasp-a04'],
|
|
120
|
+
},
|
|
121
|
+
{
|
|
122
|
+
id: 'AA-DATA-003',
|
|
123
|
+
title: 'Sensitive data logged',
|
|
124
|
+
pattern: /(?:console\.log|logger?\.\w+|log\.(?:info|debug|warn|error))\s*\([^)]*(?:password|token|secret|apiKey|api_key|authorization|credit.?card|ssn|social.?security)/gi,
|
|
125
|
+
severity: Severity.MEDIUM,
|
|
126
|
+
cweIds: ['CWE-532'],
|
|
127
|
+
description: 'Sensitive data (passwords, tokens, PII) written to logs.',
|
|
128
|
+
remediation: 'Redact sensitive fields before logging. Use structured logging with field masking.',
|
|
129
|
+
languages: ['*'],
|
|
130
|
+
tags: ['owasp-a09', 'privacy'],
|
|
131
|
+
},
|
|
132
|
+
|
|
133
|
+
// ── Input Trust Boundaries ────────────────────────────────────────────
|
|
134
|
+
{
|
|
135
|
+
id: 'AA-TRUST-001',
|
|
136
|
+
title: 'Unsanitized user input in database operation',
|
|
137
|
+
pattern: /(?:findOne|find|updateOne|update|deleteOne|delete|insert|create)\s*\(\s*(?:req\.body|req\.query|req\.params)/g,
|
|
138
|
+
severity: Severity.HIGH,
|
|
139
|
+
cweIds: ['CWE-20'],
|
|
140
|
+
description: 'User input passed directly to database operation without validation or sanitization.',
|
|
141
|
+
remediation: 'Validate and sanitize input. Use schema validation (Joi, Zod, ajv) before DB operations.',
|
|
142
|
+
languages: ['javascript', 'typescript'],
|
|
143
|
+
tags: ['owasp-a03'],
|
|
144
|
+
},
|
|
145
|
+
{
|
|
146
|
+
id: 'AA-TRUST-002',
|
|
147
|
+
title: 'Missing input validation — no schema/validator',
|
|
148
|
+
pattern: /app\.(?:post|put|patch)\s*\(\s*['"][^'"]+['"][\s\S]{0,100}req\.body\./g,
|
|
149
|
+
severity: Severity.MEDIUM,
|
|
150
|
+
cweIds: ['CWE-20'],
|
|
151
|
+
description: 'POST/PUT/PATCH handler accesses req.body without visible input validation.',
|
|
152
|
+
remediation: 'Add input validation middleware (express-validator, Joi, Zod) before processing.',
|
|
153
|
+
languages: ['javascript', 'typescript'],
|
|
154
|
+
tags: ['owasp-a03'],
|
|
155
|
+
exclude: /validate|schema|joi|zod|ajv|express-validator|celebrate|check\(|body\(/i,
|
|
156
|
+
},
|
|
157
|
+
|
|
158
|
+
// ── Rate Limiting / DoS Protection ────────────────────────────────────
|
|
159
|
+
{
|
|
160
|
+
id: 'AA-DOS-001',
|
|
161
|
+
title: 'Missing rate limiting on auth endpoint',
|
|
162
|
+
pattern: /(?:app|router)\.post\s*\(\s*['"]\/(?:login|auth|signin|register|signup|reset|forgot|token)['"][\s\S]{0,200}(?:async\s+)?\(?(?:req|ctx)/g,
|
|
163
|
+
severity: Severity.MEDIUM,
|
|
164
|
+
cweIds: ['CWE-307'],
|
|
165
|
+
description: 'Authentication endpoint without rate limiting. Enables brute-force attacks.',
|
|
166
|
+
remediation: 'Add rate limiting middleware: express-rate-limit, rate-limiter-flexible.',
|
|
167
|
+
languages: ['javascript', 'typescript'],
|
|
168
|
+
tags: ['owasp-a07', 'T1110'],
|
|
169
|
+
exclude: /rateLimit|rateLimiter|limiter|throttle|brute/i,
|
|
170
|
+
},
|
|
171
|
+
|
|
172
|
+
// ── Privilege Escalation ──────────────────────────────────────────────
|
|
173
|
+
{
|
|
174
|
+
id: 'AA-PRIV-001',
|
|
175
|
+
title: 'User-controlled role/permission assignment',
|
|
176
|
+
pattern: /(?:req\.body|req\.query|input)\s*\.\s*(?:role|permission|isAdmin|is_admin|privilege|group)/g,
|
|
177
|
+
severity: Severity.CRITICAL,
|
|
178
|
+
cweIds: ['CWE-269'],
|
|
179
|
+
description: 'User can control their own role or permission level. Privilege escalation.',
|
|
180
|
+
remediation: 'Never allow users to set their own roles. Assign roles server-side by authorized admins.',
|
|
181
|
+
languages: ['javascript', 'typescript', 'python'],
|
|
182
|
+
tags: ['owasp-a01', 'T1078'],
|
|
183
|
+
},
|
|
184
|
+
|
|
185
|
+
// ── Security Headers / Configuration ──────────────────────────────────
|
|
186
|
+
{
|
|
187
|
+
id: 'AA-HDR-001',
|
|
188
|
+
title: 'Missing security headers — no helmet or manual headers',
|
|
189
|
+
pattern: /app\s*=\s*express\s*\(\)/g,
|
|
190
|
+
severity: Severity.INFO,
|
|
191
|
+
cweIds: ['CWE-16'],
|
|
192
|
+
description: 'Express app created. Verify security headers are set (helmet or manual).',
|
|
193
|
+
remediation: 'Use helmet() middleware: app.use(helmet()) for comprehensive security headers.',
|
|
194
|
+
languages: ['javascript', 'typescript'],
|
|
195
|
+
tags: ['owasp-a05'],
|
|
196
|
+
exclude: /helmet/,
|
|
197
|
+
},
|
|
198
|
+
|
|
199
|
+
// ── Logging / Audit ───────────────────────────────────────────────────
|
|
200
|
+
{
|
|
201
|
+
id: 'AA-AUDIT-001',
|
|
202
|
+
title: 'Sensitive operation without audit logging',
|
|
203
|
+
pattern: /(?:delete|remove|destroy|drop|truncate|purge)\s*\(/g,
|
|
204
|
+
severity: Severity.LOW,
|
|
205
|
+
cweIds: ['CWE-778'],
|
|
206
|
+
description: 'Destructive operation without visible audit logging.',
|
|
207
|
+
remediation: 'Add audit logging for destructive operations: who, what, when, from where.',
|
|
208
|
+
languages: ['javascript', 'typescript', 'python'],
|
|
209
|
+
tags: ['owasp-a09'],
|
|
210
|
+
exclude: /log|audit|track|record|event/i,
|
|
211
|
+
},
|
|
212
|
+
];
|
|
213
|
+
|
|
214
|
+
// ---------------------------------------------------------------------------
|
|
215
|
+
// Acceptance Auditor review function
|
|
216
|
+
// ---------------------------------------------------------------------------
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Run Acceptance Auditor security architecture review against source files.
|
|
220
|
+
*
|
|
221
|
+
* @param {import('../engine.js').SourceFile[]} sources
|
|
222
|
+
* @param {object} [options]
|
|
223
|
+
* @returns {Promise<ReviewFinding[]>}
|
|
224
|
+
*/
|
|
225
|
+
export async function acceptanceAuditReview(sources, options = {}) {
|
|
226
|
+
const findings = [];
|
|
227
|
+
|
|
228
|
+
for (const source of sources) {
|
|
229
|
+
const lines = source.content.split('\n');
|
|
230
|
+
|
|
231
|
+
for (const pat of PATTERNS) {
|
|
232
|
+
if (!pat.languages.includes('*') && !pat.languages.includes(source.language)) {
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
for (let i = 0; i < lines.length; i++) {
|
|
237
|
+
const line = lines[i];
|
|
238
|
+
const trimmed = line.trimStart();
|
|
239
|
+
if (trimmed.startsWith('//') || trimmed.startsWith('#') || trimmed.startsWith('*')) continue;
|
|
240
|
+
|
|
241
|
+
pat.pattern.lastIndex = 0;
|
|
242
|
+
const match = pat.pattern.exec(line);
|
|
243
|
+
if (!match) continue;
|
|
244
|
+
|
|
245
|
+
if (pat.exclude) {
|
|
246
|
+
pat.exclude.lastIndex = 0;
|
|
247
|
+
if (pat.exclude.test(line)) continue;
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
// For multi-line patterns, check surrounding context
|
|
251
|
+
if (pat.id === 'AA-TRUST-002') {
|
|
252
|
+
// Check if there's validation in the surrounding 10 lines
|
|
253
|
+
const context = lines.slice(Math.max(0, i - 5), Math.min(lines.length, i + 5)).join('\n');
|
|
254
|
+
if (/validate|schema|joi|zod|ajv/i.test(context)) continue;
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
findings.push(
|
|
258
|
+
new ReviewFinding({
|
|
259
|
+
title: pat.title,
|
|
260
|
+
severity: pat.severity,
|
|
261
|
+
layer: 'acceptance-auditor',
|
|
262
|
+
file: source.path,
|
|
263
|
+
line: i + 1,
|
|
264
|
+
column: match.index + 1,
|
|
265
|
+
description: pat.description,
|
|
266
|
+
proof: line.trim().slice(0, 200),
|
|
267
|
+
remediation: pat.remediation,
|
|
268
|
+
cweIds: [...pat.cweIds],
|
|
269
|
+
tags: pat.tags ? [...pat.tags] : [],
|
|
270
|
+
language: source.language,
|
|
271
|
+
meta: { patternId: pat.id },
|
|
272
|
+
}),
|
|
273
|
+
);
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
return findings;
|
|
279
|
+
}
|