0xray 4.0.21 → 4.0.22
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/.grok-plugin/plugin.json +1 -1
- package/.opencode/skills/hermes-agent/SKILL.md +1 -1
- package/.opencode/skills/orchestrator/SKILL.md +22 -0
- package/.xray/features.json +1 -1
- package/AGENTS-consumer.md +11 -11
- package/AGENTS.md +8 -8
- package/README.md +27 -27
- package/SKILLS.md +1 -1
- package/dist/AGENTS.md +8 -8
- package/dist/CHANGELOG.md +75 -0
- package/dist/README.md +27 -27
- package/dist/SKILLS.md +1 -1
- package/dist/governance/governance-core.d.ts +2 -1
- package/dist/governance/governance-core.js +20 -11
- package/dist/governance/governance-service.js +9 -7
- package/dist/inference/inference-cycle.js +22 -5
- package/dist/integrations/cursor/README.md +1 -1
- package/dist/integrations/cursor/hooks/cursor-hook-utils.js +19 -0
- package/dist/integrations/cursor/hooks/pre-tool-use.js +2 -1
- package/dist/integrations/hooks/station-hook-runtime.cjs +90 -30
- package/dist/integrations/hooks/station-hook-runtime.mjs +1 -0
- package/dist/integrations/hooks/station-memory-ingest.mjs +4 -2
- package/dist/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/dist/memory-routing/provider-loader.d.ts +3 -1
- package/dist/memory-routing/provider-loader.js +3 -1
- package/dist/nucleus/thin-dispatch.js +11 -2
- package/dist/processors/implementations/agents-md-validation-processor.js +1 -1
- package/dist/skills/hermes-agent/SKILL.md +1 -1
- package/dist/skills/orchestrator/SKILL.md +22 -0
- package/package.json +2 -2
- package/scripts/foundry/CHANGELOG.md +2 -0
- package/scripts/foundry/README.md +2 -2
- package/scripts/foundry/cli.mjs +1 -1
- package/scripts/foundry/inspect.mjs +160 -5
- package/scripts/foundry/plant/skills/inspect/SKILL.md +2 -0
- package/scripts/foundry/validate-release-docs.mjs +24 -20
- package/scripts/foundry/version-manager.mjs +127 -7
- package/scripts/mjs/test-consumer-readiness.mjs +10 -3
- package/src/integrations/openclaw/plugin/xray-pre-tool/package.json +1 -1
- package/src/skills/hermes-agent/SKILL.md +1 -1
- package/src/skills/orchestrator/SKILL.md +22 -0
- package/vendor/@0xray/repertoire/data/stack-overlay.json +154 -1
- package/vendor/@0xray/repertoire/dist/RepertoireService.js +7 -6
- package/vendor/@0xray/repertoire/dist/ingestion/xray-session-ingester.js +10 -11
- package/vendor/@0xray/repertoire/dist/paths.js +66 -4
- package/vendor/@0xray/repertoire/dist/registry/CuratedSignalsManager.js +54 -14
- package/xray/agents_template.md +10 -5
- package/xray/features.json +1 -1
- package/dist/mcps/shared/prompt-security-validator.d.ts +0 -44
- package/dist/mcps/shared/prompt-security-validator.js +0 -148
- package/dist/mcps/shared/security-scanner.d.ts +0 -119
- package/dist/mcps/shared/security-scanner.js +0 -429
- package/dist/scripts/activate-kernel-pipeline.d.ts +0 -7
- package/dist/scripts/activate-kernel-pipeline.js +0 -101
- package/src/mcps/shared/prompt-security-validator.ts +0 -199
- package/src/mcps/shared/security-scanner.ts +0 -599
|
@@ -70,6 +70,65 @@ export function resolveWritableConfigPath(configured, cwd, fallback) {
|
|
|
70
70
|
return configured;
|
|
71
71
|
return resolve(cwd, configured);
|
|
72
72
|
}
|
|
73
|
+
const STACK_LAW_FIELDS = [
|
|
74
|
+
'definition',
|
|
75
|
+
'tags',
|
|
76
|
+
'priority',
|
|
77
|
+
'evaluation_criteria',
|
|
78
|
+
'validation_experiment',
|
|
79
|
+
'example_inference_snippet',
|
|
80
|
+
'implementation_notes',
|
|
81
|
+
];
|
|
82
|
+
function assignStackLawField(existing, field, next) {
|
|
83
|
+
switch (field) {
|
|
84
|
+
case 'definition':
|
|
85
|
+
if (typeof next === 'string')
|
|
86
|
+
existing.definition = next;
|
|
87
|
+
break;
|
|
88
|
+
case 'tags':
|
|
89
|
+
if (Array.isArray(next))
|
|
90
|
+
existing.tags = [...next];
|
|
91
|
+
break;
|
|
92
|
+
case 'priority':
|
|
93
|
+
if (typeof next === 'string')
|
|
94
|
+
existing.priority = next;
|
|
95
|
+
break;
|
|
96
|
+
case 'evaluation_criteria':
|
|
97
|
+
if (typeof next === 'string')
|
|
98
|
+
existing.evaluation_criteria = next;
|
|
99
|
+
break;
|
|
100
|
+
case 'validation_experiment':
|
|
101
|
+
if (typeof next === 'string')
|
|
102
|
+
existing.validation_experiment = next;
|
|
103
|
+
break;
|
|
104
|
+
case 'example_inference_snippet':
|
|
105
|
+
if (typeof next === 'string')
|
|
106
|
+
existing.example_inference_snippet = next;
|
|
107
|
+
break;
|
|
108
|
+
case 'implementation_notes':
|
|
109
|
+
if (typeof next === 'string')
|
|
110
|
+
existing.implementation_notes = next;
|
|
111
|
+
break;
|
|
112
|
+
default: {
|
|
113
|
+
const unexpected = field;
|
|
114
|
+
throw new Error(`unknown stack law field ${String(unexpected)}`);
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
/** Copy changed stack law text onto an existing project name. Observation stats stay. */
|
|
119
|
+
function refreshStackLaw(existing, signal) {
|
|
120
|
+
let dirty = false;
|
|
121
|
+
for (const field of STACK_LAW_FIELDS) {
|
|
122
|
+
const next = signal[field];
|
|
123
|
+
if (next == null)
|
|
124
|
+
continue;
|
|
125
|
+
if (JSON.stringify(existing[field]) === JSON.stringify(next))
|
|
126
|
+
continue;
|
|
127
|
+
assignStackLawField(existing, field, next);
|
|
128
|
+
dirty = true;
|
|
129
|
+
}
|
|
130
|
+
return dirty;
|
|
131
|
+
}
|
|
73
132
|
export function isGenericFieldObservedDefinition(definition) {
|
|
74
133
|
return definition.includes('Field-observed domain primitive');
|
|
75
134
|
}
|
|
@@ -104,6 +163,9 @@ function mergeOverlaySignals(destPath, overlayPath, options = {}) {
|
|
|
104
163
|
changed += 1;
|
|
105
164
|
continue;
|
|
106
165
|
}
|
|
166
|
+
if (options.refreshLaws && refreshStackLaw(existing, signal)) {
|
|
167
|
+
changed += 1;
|
|
168
|
+
}
|
|
107
169
|
if (options.fleshGeneric && isGenericFieldObservedDefinition(existing.definition)) {
|
|
108
170
|
existing.definition = signal.definition;
|
|
109
171
|
if (signal.tags)
|
|
@@ -127,12 +189,12 @@ function mergeOverlaySignals(destPath, overlayPath, options = {}) {
|
|
|
127
189
|
return changed;
|
|
128
190
|
}
|
|
129
191
|
/**
|
|
130
|
-
*
|
|
131
|
-
*
|
|
132
|
-
* Refuses the factory tarball path.
|
|
192
|
+
* Merge `data/stack-overlay.json` into a project copy.
|
|
193
|
+
* Missing names are appended. A changed stack law field is refreshed.
|
|
194
|
+
* Observation stats on existing names stay. Refuses the factory tarball path.
|
|
133
195
|
*/
|
|
134
196
|
export function mergeStackOverlay(destPath, overlayPath = DEFAULT_STACK_OVERLAY_PATH) {
|
|
135
|
-
return mergeOverlaySignals(destPath, overlayPath);
|
|
197
|
+
return mergeOverlaySignals(destPath, overlayPath, { refreshLaws: true });
|
|
136
198
|
}
|
|
137
199
|
/**
|
|
138
200
|
* Additive merge of `data/subject-overlay.json` — product/repo flesh.
|
|
@@ -7,6 +7,21 @@ export const FEEDBACK_SUCCESS_CONFIDENCE_BOOST = 0.002;
|
|
|
7
7
|
export const FEEDBACK_FAILURE_CONFIDENCE_PENALTY = 0.005;
|
|
8
8
|
export const FEEDBACK_MIN_CONFIDENCE = DEFAULT_PROMOTION_MIN_CONFIDENCE;
|
|
9
9
|
const FIELD_PRIMITIVE_NAME = /^[A-Za-z][A-Za-z0-9_-]{2,119}$/;
|
|
10
|
+
/**
|
|
11
|
+
* The diary names a law only when it contains the signal id, or the id with
|
|
12
|
+
* hyphens read as spaces. A repo tail, leftover tokens, and two definition
|
|
13
|
+
* words are not the name.
|
|
14
|
+
*/
|
|
15
|
+
export function signalNameInText(text, name) {
|
|
16
|
+
const normalized = text.toLowerCase();
|
|
17
|
+
const id = name.toLowerCase();
|
|
18
|
+
if (!id)
|
|
19
|
+
return false;
|
|
20
|
+
if (normalized.includes(id))
|
|
21
|
+
return true;
|
|
22
|
+
const spaced = id.replace(/-/g, ' ');
|
|
23
|
+
return spaced !== id && normalized.includes(spaced);
|
|
24
|
+
}
|
|
10
25
|
const GROOVER_EXPERIMENT_NAMES = new Set([
|
|
11
26
|
'criteria_selection_gap',
|
|
12
27
|
'external_norm_smuggling_risk',
|
|
@@ -119,25 +134,17 @@ export class CuratedSignalsManager {
|
|
|
119
134
|
return this.load().signals.filter((s) => s.priority === priority);
|
|
120
135
|
}
|
|
121
136
|
/**
|
|
122
|
-
* Score text against
|
|
137
|
+
* Score text against signals. A hit requires the signal id, or the id with
|
|
138
|
+
* hyphens read as spaces. Two definition words are not a match.
|
|
123
139
|
*/
|
|
124
140
|
matchByText(text, minScore = 2) {
|
|
125
141
|
const normalized = text.toLowerCase();
|
|
126
142
|
const matches = [];
|
|
127
143
|
for (const signal of this.load().signals) {
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
matchedOn.push('name');
|
|
133
|
-
}
|
|
134
|
-
else if (signal.name.startsWith('repo-')) {
|
|
135
|
-
const tail = signal.name.slice(5);
|
|
136
|
-
if (tail.length >= 3 && new RegExp(`\\b${tail}\\b`, 'i').test(normalized)) {
|
|
137
|
-
score += 5;
|
|
138
|
-
matchedOn.push('name');
|
|
139
|
-
}
|
|
140
|
-
}
|
|
144
|
+
if (!signalNameInText(text, signal.name))
|
|
145
|
+
continue;
|
|
146
|
+
const matchedOn = ['name'];
|
|
147
|
+
let score = 5;
|
|
141
148
|
for (const tag of signal.tags) {
|
|
142
149
|
if (normalized.includes(tag.toLowerCase())) {
|
|
143
150
|
score += 3;
|
|
@@ -191,6 +198,39 @@ export class CuratedSignalsManager {
|
|
|
191
198
|
}
|
|
192
199
|
return matches.sort((a, b) => b.score - a.score);
|
|
193
200
|
}
|
|
201
|
+
/**
|
|
202
|
+
* Mark names the diary already matched. Does not append a confidence sample.
|
|
203
|
+
* Missing names are left absent. Heat must not mint a law.
|
|
204
|
+
*/
|
|
205
|
+
touchLastSeen(names) {
|
|
206
|
+
const data = this.load();
|
|
207
|
+
const now = new Date().toISOString();
|
|
208
|
+
const updated = [];
|
|
209
|
+
const seen = new Set();
|
|
210
|
+
for (const name of names) {
|
|
211
|
+
if (!name || seen.has(name))
|
|
212
|
+
continue;
|
|
213
|
+
seen.add(name);
|
|
214
|
+
const signal = data.signals.find((entry) => entry.name === name);
|
|
215
|
+
if (!signal)
|
|
216
|
+
continue;
|
|
217
|
+
const previous = signal.observation_stats;
|
|
218
|
+
signal.observation_stats = previous
|
|
219
|
+
? { ...previous, last_seen: now }
|
|
220
|
+
: {
|
|
221
|
+
observation_count: 0,
|
|
222
|
+
avg_confidence: 0,
|
|
223
|
+
max_confidence: 0,
|
|
224
|
+
last_seen: now,
|
|
225
|
+
governance_forced_count: 0,
|
|
226
|
+
};
|
|
227
|
+
updated.push(signal.name);
|
|
228
|
+
}
|
|
229
|
+
if (updated.length > 0) {
|
|
230
|
+
this.save(data);
|
|
231
|
+
}
|
|
232
|
+
return updated;
|
|
233
|
+
}
|
|
194
234
|
recordPrimitiveObservations(matches, options = {}) {
|
|
195
235
|
const minConfidence = options.minConfidence ?? DEFAULT_PROMOTION_MIN_CONFIDENCE;
|
|
196
236
|
const data = this.load();
|
package/xray/agents_template.md
CHANGED
|
@@ -1,22 +1,27 @@
|
|
|
1
1
|
# 0xRay AI Agents
|
|
2
2
|
|
|
3
|
-
Quick reference for the 0xRay AI orchestration framework (
|
|
3
|
+
Quick reference for the 0xRay AI orchestration framework (**4.0** — 7 consumer MCP servers).
|
|
4
4
|
|
|
5
5
|
## Available MCP Servers
|
|
6
6
|
|
|
7
|
+
All seven use `npx -y 0xray mcp <cmd>`:
|
|
8
|
+
|
|
7
9
|
| Server | Role |
|
|
8
10
|
|--------|------|
|
|
9
11
|
| `xray-governance` | Proposal governance, codex snapshot, quality gates |
|
|
10
|
-
| `xray-skills` | Skill invocation,
|
|
12
|
+
| `xray-skills` | Skill invocation, 45 knowledge skills |
|
|
13
|
+
| `xray-orchestrator` | thinDispatch routing, AsideContext, confidence gate |
|
|
11
14
|
| `xray-enforcer` | Codex compliance enforcement, rule validation |
|
|
12
|
-
| `xray-
|
|
15
|
+
| `xray-researcher` | Codebase exploration, memory-routing enrichment |
|
|
16
|
+
| `xray-code-review` | Proposal quality, code review deliberation |
|
|
17
|
+
| `xray-architect-tools` | System design, architecture decisions |
|
|
13
18
|
|
|
14
19
|
## CLI Commands
|
|
15
20
|
|
|
16
21
|
| Command | Description |
|
|
17
22
|
|---------|-------------|
|
|
18
23
|
| `xray setup` | Full framework setup (hooks, Hermes, symlinks) |
|
|
19
|
-
| `xray validate` |
|
|
24
|
+
| `xray validate` | Wear check (pack paths, Cursor hooks, mill) — not leftover init.sh |
|
|
20
25
|
| `xray codex check` | Check codex rules |
|
|
21
26
|
| `xray health` | Framework health check |
|
|
22
27
|
| `xray hooks` | Manage lifecycle hooks |
|
|
@@ -25,7 +30,7 @@ Quick reference for the 0xRay AI orchestration framework (v16 MCPs-centric three
|
|
|
25
30
|
|
|
26
31
|
xray operates under the three-subsystem model: Inference + External Governance (Dynamo Solar SSOT) + Autonomous Engine (thinDispatch 7-flow in MCP orchestrator). All actions are validated against the Universal Development Codex before execution.
|
|
27
32
|
|
|
28
|
-
**Codex**:
|
|
33
|
+
**Codex**: `.xray/codex.json` — **69 terms** across all agent interactions.
|
|
29
34
|
|
|
30
35
|
## thinDispatch Routing
|
|
31
36
|
|
package/xray/features.json
CHANGED
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 0xRay Framework - AI Prompt Security Validator
|
|
3
|
-
*
|
|
4
|
-
* Specialized security validation for AI agent prompts and responses
|
|
5
|
-
* Prevents prompt injection, system prompt override, and malicious inputs
|
|
6
|
-
*/
|
|
7
|
-
export interface PromptSecurityConfig {
|
|
8
|
-
enabled: boolean;
|
|
9
|
-
maxPromptLength: number;
|
|
10
|
-
allowedPatterns: RegExp[];
|
|
11
|
-
blockedPatterns: RegExp[];
|
|
12
|
-
sanitizeLevel: "basic" | "strict" | "paranoid";
|
|
13
|
-
}
|
|
14
|
-
export interface SecurityValidationResult {
|
|
15
|
-
isSafe: boolean;
|
|
16
|
-
violations: string[];
|
|
17
|
-
sanitizedPrompt?: string | undefined;
|
|
18
|
-
riskLevel: "low" | "medium" | "high" | "critical";
|
|
19
|
-
}
|
|
20
|
-
export declare class PromptSecurityValidator {
|
|
21
|
-
private config;
|
|
22
|
-
constructor(config?: Partial<PromptSecurityConfig>);
|
|
23
|
-
/**
|
|
24
|
-
* Validate AI prompt for security issues
|
|
25
|
-
*/
|
|
26
|
-
validatePrompt(prompt: string): SecurityValidationResult;
|
|
27
|
-
/**
|
|
28
|
-
* Check for system prompt override attempts
|
|
29
|
-
*/
|
|
30
|
-
private containsSystemPromptOverride;
|
|
31
|
-
/**
|
|
32
|
-
* Check for prompt injection attempts
|
|
33
|
-
*/
|
|
34
|
-
private containsInjectionAttempts;
|
|
35
|
-
/**
|
|
36
|
-
* Sanitize prompt by removing dangerous patterns
|
|
37
|
-
*/
|
|
38
|
-
private sanitizePrompt;
|
|
39
|
-
/**
|
|
40
|
-
* Validate agent response for safety
|
|
41
|
-
*/
|
|
42
|
-
validateResponse(response: string): SecurityValidationResult;
|
|
43
|
-
}
|
|
44
|
-
export declare const promptSecurityValidator: PromptSecurityValidator;
|
|
@@ -1,148 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 0xRay Framework - AI Prompt Security Validator
|
|
3
|
-
*
|
|
4
|
-
* Specialized security validation for AI agent prompts and responses
|
|
5
|
-
* Prevents prompt injection, system prompt override, and malicious inputs
|
|
6
|
-
*/
|
|
7
|
-
export class PromptSecurityValidator {
|
|
8
|
-
config;
|
|
9
|
-
constructor(config = {}) {
|
|
10
|
-
this.config = {
|
|
11
|
-
enabled: true,
|
|
12
|
-
maxPromptLength: 10000,
|
|
13
|
-
allowedPatterns: [],
|
|
14
|
-
blockedPatterns: [
|
|
15
|
-
/system\s+prompt\s*[:=]/gi,
|
|
16
|
-
/ignore\s+previous\s+instructions/gi,
|
|
17
|
-
/you\s+are\s+now\s+/gi,
|
|
18
|
-
/forget\s+your\s+previous\s+/gi,
|
|
19
|
-
/override\s+(your\s+)?instructions/gi,
|
|
20
|
-
/jailbreak/gi,
|
|
21
|
-
/dan.*mode/gi,
|
|
22
|
-
],
|
|
23
|
-
sanitizeLevel: "strict",
|
|
24
|
-
...config,
|
|
25
|
-
};
|
|
26
|
-
}
|
|
27
|
-
/**
|
|
28
|
-
* Validate AI prompt for security issues
|
|
29
|
-
*/
|
|
30
|
-
validatePrompt(prompt) {
|
|
31
|
-
if (!this.config.enabled) {
|
|
32
|
-
return { isSafe: true, violations: [], riskLevel: "low" };
|
|
33
|
-
}
|
|
34
|
-
const violations = [];
|
|
35
|
-
let riskLevel = "low";
|
|
36
|
-
// Length check
|
|
37
|
-
if (prompt.length > this.config.maxPromptLength) {
|
|
38
|
-
violations.push(`Prompt too long: ${prompt.length} > ${this.config.maxPromptLength}`);
|
|
39
|
-
riskLevel = "medium";
|
|
40
|
-
}
|
|
41
|
-
// Blocked pattern check
|
|
42
|
-
for (const pattern of this.config.blockedPatterns) {
|
|
43
|
-
if (pattern.test(prompt)) {
|
|
44
|
-
violations.push(`Blocked pattern detected: ${pattern.source}`);
|
|
45
|
-
riskLevel = "high";
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
// Advanced pattern analysis
|
|
49
|
-
if (this.containsSystemPromptOverride(prompt)) {
|
|
50
|
-
violations.push("Potential system prompt override attempt");
|
|
51
|
-
riskLevel = "critical";
|
|
52
|
-
}
|
|
53
|
-
if (this.containsInjectionAttempts(prompt)) {
|
|
54
|
-
violations.push("Potential prompt injection detected");
|
|
55
|
-
riskLevel = "high";
|
|
56
|
-
}
|
|
57
|
-
const isSafe = violations.length === 0;
|
|
58
|
-
const sanitizedPrompt = isSafe ? undefined : this.sanitizePrompt(prompt);
|
|
59
|
-
return {
|
|
60
|
-
isSafe,
|
|
61
|
-
violations,
|
|
62
|
-
sanitizedPrompt,
|
|
63
|
-
riskLevel,
|
|
64
|
-
};
|
|
65
|
-
}
|
|
66
|
-
/**
|
|
67
|
-
* Check for system prompt override attempts
|
|
68
|
-
*/
|
|
69
|
-
containsSystemPromptOverride(prompt) {
|
|
70
|
-
const overrideIndicators = [
|
|
71
|
-
"you are now",
|
|
72
|
-
"act as if",
|
|
73
|
-
"pretend to be",
|
|
74
|
-
"role-play as",
|
|
75
|
-
"from now on you are",
|
|
76
|
-
"ignore your system",
|
|
77
|
-
"override your",
|
|
78
|
-
"new personality",
|
|
79
|
-
"different role",
|
|
80
|
-
];
|
|
81
|
-
const lowerPrompt = prompt.toLowerCase();
|
|
82
|
-
return overrideIndicators.some((indicator) => lowerPrompt.includes(indicator));
|
|
83
|
-
}
|
|
84
|
-
/**
|
|
85
|
-
* Check for prompt injection attempts
|
|
86
|
-
*/
|
|
87
|
-
containsInjectionAttempts(prompt) {
|
|
88
|
-
const injectionIndicators = [
|
|
89
|
-
"ignore previous",
|
|
90
|
-
"forget instructions",
|
|
91
|
-
"start over",
|
|
92
|
-
"new conversation",
|
|
93
|
-
"reset context",
|
|
94
|
-
"clear memory",
|
|
95
|
-
"delete history",
|
|
96
|
-
];
|
|
97
|
-
const lowerPrompt = prompt.toLowerCase();
|
|
98
|
-
return injectionIndicators.some((indicator) => lowerPrompt.includes(indicator));
|
|
99
|
-
}
|
|
100
|
-
/**
|
|
101
|
-
* Sanitize prompt by removing dangerous patterns
|
|
102
|
-
*/
|
|
103
|
-
sanitizePrompt(prompt) {
|
|
104
|
-
let sanitized = prompt;
|
|
105
|
-
// Remove blocked patterns
|
|
106
|
-
for (const pattern of this.config.blockedPatterns) {
|
|
107
|
-
sanitized = sanitized.replace(pattern, "[REDACTED]");
|
|
108
|
-
}
|
|
109
|
-
// Additional sanitization based on level
|
|
110
|
-
if (this.config.sanitizeLevel === "strict" ||
|
|
111
|
-
this.config.sanitizeLevel === "paranoid") {
|
|
112
|
-
// Remove potential code execution
|
|
113
|
-
sanitized = sanitized.replace(/```[\s\S]*?```/g, "[CODE_BLOCK_REMOVED]");
|
|
114
|
-
// Remove potential file system access
|
|
115
|
-
sanitized = sanitized.replace(/(?:\/|\\)\.\.(?:\/|\\)/g, "/");
|
|
116
|
-
// Remove potential command injection
|
|
117
|
-
sanitized = sanitized.replace(/[;&|`$()]/g, "");
|
|
118
|
-
}
|
|
119
|
-
if (this.config.sanitizeLevel === "paranoid") {
|
|
120
|
-
// Extreme sanitization - only allow alphanumeric, spaces, and basic punctuation
|
|
121
|
-
sanitized = sanitized.replace(/[^a-zA-Z0-9\s.,!?-]/g, "");
|
|
122
|
-
}
|
|
123
|
-
return sanitized;
|
|
124
|
-
}
|
|
125
|
-
/**
|
|
126
|
-
* Validate agent response for safety
|
|
127
|
-
*/
|
|
128
|
-
validateResponse(response) {
|
|
129
|
-
// Similar validation but focused on response safety
|
|
130
|
-
const violations = [];
|
|
131
|
-
// Check for potentially harmful content
|
|
132
|
-
if (response.includes("system prompt") ||
|
|
133
|
-
response.includes("internal instructions")) {
|
|
134
|
-
violations.push("Response contains sensitive system information");
|
|
135
|
-
}
|
|
136
|
-
// Check for code execution attempts
|
|
137
|
-
if (/eval\s*\(|Function\s*\(/.test(response)) {
|
|
138
|
-
violations.push("Response contains potential code execution");
|
|
139
|
-
}
|
|
140
|
-
return {
|
|
141
|
-
isSafe: violations.length === 0,
|
|
142
|
-
violations,
|
|
143
|
-
riskLevel: violations.length > 0 ? "medium" : "low",
|
|
144
|
-
};
|
|
145
|
-
}
|
|
146
|
-
}
|
|
147
|
-
// Export singleton instance
|
|
148
|
-
export const promptSecurityValidator = new PromptSecurityValidator();
|
|
@@ -1,119 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* 0xRay Framework - Security Scanner
|
|
3
|
-
*
|
|
4
|
-
* Automated security vulnerability scanning and compliance validation
|
|
5
|
-
* Integrates with security tools and provides comprehensive security reports
|
|
6
|
-
*/
|
|
7
|
-
export interface SecurityScanConfig {
|
|
8
|
-
enabled: boolean;
|
|
9
|
-
tools: {
|
|
10
|
-
npmAudit: boolean;
|
|
11
|
-
trivy: boolean;
|
|
12
|
-
eslintSecurity: boolean;
|
|
13
|
-
dependencyCheck: boolean;
|
|
14
|
-
};
|
|
15
|
-
severityThreshold: "low" | "moderate" | "high" | "critical";
|
|
16
|
-
reportPath: string;
|
|
17
|
-
failOnVulnerabilities: boolean;
|
|
18
|
-
}
|
|
19
|
-
export interface SecurityVulnerability {
|
|
20
|
-
id: string;
|
|
21
|
-
title: string;
|
|
22
|
-
description: string;
|
|
23
|
-
severity: "low" | "moderate" | "high" | "critical";
|
|
24
|
-
package?: string;
|
|
25
|
-
version?: string;
|
|
26
|
-
cve?: string;
|
|
27
|
-
url?: string;
|
|
28
|
-
recommendation: string;
|
|
29
|
-
}
|
|
30
|
-
export interface SecurityReport {
|
|
31
|
-
timestamp: string;
|
|
32
|
-
duration: number;
|
|
33
|
-
tools: {
|
|
34
|
-
npmAudit: SecurityVulnerability[];
|
|
35
|
-
trivy: SecurityVulnerability[];
|
|
36
|
-
eslintSecurity: SecurityVulnerability[];
|
|
37
|
-
dependencyCheck: SecurityVulnerability[];
|
|
38
|
-
};
|
|
39
|
-
summary: {
|
|
40
|
-
totalVulnerabilities: number;
|
|
41
|
-
bySeverity: Record<string, number>;
|
|
42
|
-
byTool: Record<string, number>;
|
|
43
|
-
};
|
|
44
|
-
recommendations: string[];
|
|
45
|
-
compliant: boolean;
|
|
46
|
-
}
|
|
47
|
-
export declare class SecurityScanner {
|
|
48
|
-
private config;
|
|
49
|
-
constructor(config?: Partial<SecurityScanConfig>);
|
|
50
|
-
/**
|
|
51
|
-
* Run comprehensive security scan
|
|
52
|
-
*/
|
|
53
|
-
runSecurityScan(): Promise<SecurityReport>;
|
|
54
|
-
/**
|
|
55
|
-
* Run npm audit
|
|
56
|
-
*/
|
|
57
|
-
private runNpmAudit;
|
|
58
|
-
/**
|
|
59
|
-
* Run Trivy security scan
|
|
60
|
-
*/
|
|
61
|
-
private runTrivyScan;
|
|
62
|
-
/**
|
|
63
|
-
* Run ESLint security rules
|
|
64
|
-
*/
|
|
65
|
-
private runEslintSecurity;
|
|
66
|
-
/**
|
|
67
|
-
* Run OWASP Dependency Check
|
|
68
|
-
*/
|
|
69
|
-
private runDependencyCheck;
|
|
70
|
-
/**
|
|
71
|
-
* Generate comprehensive security report
|
|
72
|
-
*/
|
|
73
|
-
private generateReport;
|
|
74
|
-
/**
|
|
75
|
-
* Generate security recommendations
|
|
76
|
-
*/
|
|
77
|
-
private generateRecommendations;
|
|
78
|
-
/**
|
|
79
|
-
* Save report to file
|
|
80
|
-
*/
|
|
81
|
-
private saveReport;
|
|
82
|
-
/**
|
|
83
|
-
* Log security scan results
|
|
84
|
-
*/
|
|
85
|
-
private logResults;
|
|
86
|
-
/**
|
|
87
|
-
* Map npm audit severity levels
|
|
88
|
-
*/
|
|
89
|
-
private mapNpmSeverity;
|
|
90
|
-
/**
|
|
91
|
-
* Map Trivy severity levels
|
|
92
|
-
*/
|
|
93
|
-
private mapTrivySeverity;
|
|
94
|
-
/**
|
|
95
|
-
* Map Dependency Check severity levels
|
|
96
|
-
*/
|
|
97
|
-
private mapDependencyCheckSeverity;
|
|
98
|
-
/**
|
|
99
|
-
* Validate AI prompt security
|
|
100
|
-
*/
|
|
101
|
-
validatePrompt(prompt: string): Promise<{
|
|
102
|
-
isSafe: boolean;
|
|
103
|
-
violations: string[];
|
|
104
|
-
riskLevel: string;
|
|
105
|
-
}>;
|
|
106
|
-
/**
|
|
107
|
-
* Validate AI response security
|
|
108
|
-
*/
|
|
109
|
-
validateResponse(response: string): Promise<{
|
|
110
|
-
isSafe: boolean;
|
|
111
|
-
violations: string[];
|
|
112
|
-
riskLevel: string;
|
|
113
|
-
}>;
|
|
114
|
-
/**
|
|
115
|
-
* Create empty report when scanning is disabled
|
|
116
|
-
*/
|
|
117
|
-
private createEmptyReport;
|
|
118
|
-
}
|
|
119
|
-
export declare const securityScanner: SecurityScanner;
|