@mcp-guardian/server 1.0.0 → 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.
@@ -1,19 +1,29 @@
1
1
  import { PolicyConfig, PolicyDecision, CallContext, PolicyMode } from './policy-types.js';
2
+ import { ShellTokenizer } from './shell-tokenizer.js';
2
3
  /**
3
4
  * Policy Engine — evaluates every intercepted tools/call against configured rules.
4
5
  * Supports three modes: audit (passive), warn (flag only), block (active enforcement).
6
+ *
7
+ * v1.2: Integrated payload normalization and semantic shell analysis layers
8
+ * to move beyond regex-only detection toward semantic execution security.
5
9
  */
6
10
  export declare class PolicyEngine {
7
11
  private rules;
8
12
  private mode;
9
13
  private callCounters;
14
+ private normalizer;
15
+ private shellTokenizer;
10
16
  constructor(config: PolicyConfig);
11
17
  /**
12
18
  * Evaluate a tools/call request and return a decision.
19
+ *
20
+ * Pipeline: Normalize payload → Semantic shell analysis → Rule evaluation
13
21
  */
14
22
  evaluate(context: CallContext): PolicyDecision;
15
23
  private evaluateRule;
16
24
  private resolveAction;
17
25
  getMode(): PolicyMode;
26
+ /** Expose the shell tokenizer for testing */
27
+ getShellTokenizer(): ShellTokenizer;
18
28
  }
19
29
  //# sourceMappingURL=policy-engine.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy-engine.d.ts","sourceRoot":"","sources":["../../src/policy/policy-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAgB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGxG;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,YAAY,CAA8D;gBAEtE,MAAM,EAAE,YAAY;IAKhC;;OAEG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;IAU9C,OAAO,CAAC,YAAY;IA2EpB,OAAO,CAAC,aAAa;IAMrB,OAAO,IAAI,UAAU;CAGtB"}
1
+ {"version":3,"file":"policy-engine.d.ts","sourceRoot":"","sources":["../../src/policy/policy-engine.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,cAAc,EAAE,WAAW,EAAgB,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAGxG,OAAO,EAAE,cAAc,EAAe,MAAM,sBAAsB,CAAC;AAEnE;;;;;;GAMG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAkC;IAC/C,OAAO,CAAC,IAAI,CAAa;IACzB,OAAO,CAAC,YAAY,CAA8D;IAClF,OAAO,CAAC,UAAU,CAAmB;IACrC,OAAO,CAAC,cAAc,CAAwB;gBAElC,MAAM,EAAE,YAAY;IAKhC;;;;OAIG;IACH,QAAQ,CAAC,OAAO,EAAE,WAAW,GAAG,cAAc;IAiC9C,OAAO,CAAC,YAAY;IAoGpB,OAAO,CAAC,aAAa;IAMrB,OAAO,IAAI,UAAU;IAIrB,6CAA6C;IAC7C,iBAAiB,IAAI,cAAc;CAGpC"}
@@ -1,29 +1,58 @@
1
1
  import { Logger } from '../utils/logger.js';
2
+ import { getNormalizer } from '../utils/payload-normalizer.js';
3
+ import { ShellTokenizer } from './shell-tokenizer.js';
2
4
  /**
3
5
  * Policy Engine — evaluates every intercepted tools/call against configured rules.
4
6
  * Supports three modes: audit (passive), warn (flag only), block (active enforcement).
7
+ *
8
+ * v1.2: Integrated payload normalization and semantic shell analysis layers
9
+ * to move beyond regex-only detection toward semantic execution security.
5
10
  */
6
11
  export class PolicyEngine {
7
12
  rules;
8
13
  mode;
9
14
  callCounters = new Map();
15
+ normalizer = getNormalizer();
16
+ shellTokenizer = new ShellTokenizer();
10
17
  constructor(config) {
11
18
  this.rules = config.policy.rules;
12
19
  this.mode = config.policy.mode;
13
20
  }
14
21
  /**
15
22
  * Evaluate a tools/call request and return a decision.
23
+ *
24
+ * Pipeline: Normalize payload → Semantic shell analysis → Rule evaluation
16
25
  */
17
26
  evaluate(context) {
27
+ // ── v1.2: Payload normalization (before regex evaluation) ──
28
+ const normalizedArgs = context.arguments
29
+ ? this.normalizer.normalizeJsonValue(context.arguments)
30
+ : {};
31
+ const normalizedContext = {
32
+ ...context,
33
+ arguments: normalizedArgs,
34
+ };
35
+ // ── v1.2: Semantic shell analysis on argument strings ──
36
+ const argsStr = JSON.stringify(normalizedArgs);
37
+ const shellRisk = argsStr.length > 0
38
+ ? this.shellTokenizer.analyzeRisk(this.shellTokenizer.tokenize(argsStr).commands)
39
+ : { hasCommandSubstitution: false, hasPipes: false, hasRedirects: false, hasLogicalChains: false, dangerousCommands: [], shellMetacharacters: [] };
40
+ // Check for high-risk semantic patterns regardless of rule match
41
+ if (shellRisk.hasCommandSubstitution) {
42
+ Logger.info(`[policy] Semantic: command substitution detected in '${context.toolName}' arguments`);
43
+ }
44
+ if (shellRisk.dangerousCommands.length > 0) {
45
+ Logger.info(`[policy] Semantic: dangerous commands [${shellRisk.dangerousCommands.join(', ')}] in '${context.toolName}' arguments`);
46
+ }
18
47
  for (const rule of this.rules) {
19
- const decision = this.evaluateRule(rule, context);
48
+ const decision = this.evaluateRule(rule, normalizedContext, { argsStr, shellRisk });
20
49
  if (decision)
21
50
  return decision;
22
51
  }
23
52
  // Default: pass
24
53
  return { action: 'pass', rule: 'default', reason: 'No policy rules matched' };
25
54
  }
26
- evaluateRule(rule, ctx) {
55
+ evaluateRule(rule, ctx, analysis) {
27
56
  // Tool allowlist/denylist
28
57
  if (rule.tools) {
29
58
  if (rule.tools.allow && rule.tools.allow.length > 0) {
@@ -37,13 +66,12 @@ export class PolicyEngine {
37
66
  }
38
67
  }
39
68
  }
40
- // Malicious pattern detection
69
+ // v1.2: Malicious pattern detection — runs against NORMALIZED payload
41
70
  if (rule.patterns) {
42
- const argsStr = ctx.arguments ? JSON.stringify(ctx.arguments) : '';
43
71
  for (const pattern of rule.patterns) {
44
72
  try {
45
- if (new RegExp(pattern).test(argsStr)) {
46
- return { action: this.resolveAction(rule.action), rule: rule.name, reason: `Argument pattern '${pattern}' matched in tool call` };
73
+ if (new RegExp(pattern).test(analysis.argsStr)) {
74
+ return { action: this.resolveAction(rule.action), rule: rule.name, reason: `Argument pattern '${pattern}' matched in tool call (normalized)` };
47
75
  }
48
76
  }
49
77
  catch {
@@ -51,6 +79,25 @@ export class PolicyEngine {
51
79
  }
52
80
  }
53
81
  }
82
+ // v1.2: Semantic shell detection rule — automatic high-risk pattern block
83
+ if (rule.name === 'block-shell-injection' || rule.name.includes('shell')) {
84
+ // Command substitution is always high-risk
85
+ if (analysis.shellRisk.hasCommandSubstitution) {
86
+ return { action: this.resolveAction('block'), rule: rule.name, reason: 'Semantic: shell command substitution detected in arguments' };
87
+ }
88
+ // Dangerous commands in any context
89
+ if (analysis.shellRisk.dangerousCommands.length > 0) {
90
+ return {
91
+ action: this.resolveAction('block'),
92
+ rule: rule.name,
93
+ reason: `Semantic: dangerous shell commands detected: [${analysis.shellRisk.dangerousCommands.join(', ')}]`,
94
+ };
95
+ }
96
+ // Pipe chains with dangerous patterns
97
+ if (analysis.shellRisk.hasPipes && analysis.shellRisk.hasCommandSubstitution) {
98
+ return { action: this.resolveAction('block'), rule: rule.name, reason: 'Semantic: pipe chain with command substitution' };
99
+ }
100
+ }
54
101
  // Max tokens per call
55
102
  if (rule.maxTokens && ctx.requestTokens > rule.maxTokens) {
56
103
  return { action: this.resolveAction(rule.action), rule: rule.name, reason: `Token count ${ctx.requestTokens} exceeds max ${rule.maxTokens}` };
@@ -104,5 +151,9 @@ export class PolicyEngine {
104
151
  getMode() {
105
152
  return this.mode;
106
153
  }
154
+ /** Expose the shell tokenizer for testing */
155
+ getShellTokenizer() {
156
+ return this.shellTokenizer;
157
+ }
107
158
  }
108
159
  //# sourceMappingURL=policy-engine.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"policy-engine.js","sourceRoot":"","sources":["../../src/policy/policy-engine.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"policy-engine.js","sourceRoot":"","sources":["../../src/policy/policy-engine.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Shell Command Tokenizer & Semantic Analyzer
3
+ *
4
+ * Parses tool argument strings into tokenized AST nodes for semantic
5
+ * security analysis. Goes beyond regex pattern matching by understanding
6
+ * shell grammar: pipelines, redirects, command substitutions, logical chains.
7
+ *
8
+ * This is the semantic detection layer that addresses the architectural
9
+ * limitation of regex-only detection. Instead of pattern-matching "$(rm -rf /)"
10
+ * we parse it as a CommandSubstitution AST node and then analyze the inner
11
+ * command semantically.
12
+ */
13
+ export declare enum TokenType {
14
+ WORD = "WORD",
15
+ STRING = "STRING",
16
+ VARIABLE = "VARIABLE",
17
+ COMMAND_SUBSTITUTION = "COMMAND_SUBSTITUTION",
18
+ BACKTICK_SUBSTITUTION = "BACKTICK_SUBSTITUTION",
19
+ PIPE = "PIPE",
20
+ REDIRECT = "REDIRECT",
21
+ SEMICOLON = "SEMICOLON",
22
+ AND_IF = "AND_IF",// &&
23
+ OR_IF = "OR_IF",// ||
24
+ BACKGROUND = "BACKGROUND",
25
+ SUBSHELL = "SUBSHELL"
26
+ }
27
+ export interface Token {
28
+ type: TokenType;
29
+ value: string;
30
+ /** Start position in original string */
31
+ start: number;
32
+ /** End position in original string */
33
+ end: number;
34
+ /** For compound tokens (substitution, subshell), nested tokens */
35
+ children?: Token[];
36
+ }
37
+ export interface ShellAST {
38
+ /** Top-level commands (separated by ;, &&, ||, &) */
39
+ commands: Token[];
40
+ /** Whether the input contained potentially dangerous constructs */
41
+ warnings: string[];
42
+ }
43
+ /**
44
+ * Dangerous command categories for semantic analysis.
45
+ */
46
+ export interface CommandRisk {
47
+ /** High risk: command substitution present */
48
+ hasCommandSubstitution: boolean;
49
+ /** High risk: pipe chains present */
50
+ hasPipes: boolean;
51
+ /** Medium risk: redirect operators present */
52
+ hasRedirects: boolean;
53
+ /** Medium risk: logical chain operators */
54
+ hasLogicalChains: boolean;
55
+ /** Dangerous commands detected in tokenized words */
56
+ dangerousCommands: string[];
57
+ /** Shell metacharacters found */
58
+ shellMetacharacters: string[];
59
+ }
60
+ /**
61
+ * ShellTokenizer parses shell-like input into an AST without executing anything.
62
+ * It's a security analyzer, not a full POSIX shell parser — focus is on detecting
63
+ * execution patterns that signal malicious intent.
64
+ */
65
+ export declare class ShellTokenizer {
66
+ private readonly DANGEROUS_COMMANDS;
67
+ /**
68
+ * Tokenize a string that may contain shell syntax.
69
+ */
70
+ tokenize(input: string): ShellAST;
71
+ /**
72
+ * Parse the next token starting at position pos.
73
+ */
74
+ private nextToken;
75
+ /**
76
+ * Parse a delimited token like $(...), ${...}, `...`, (...).
77
+ * Recursively tokenizes inner content.
78
+ */
79
+ private parseDelimited;
80
+ /**
81
+ * Analyze a token for risk.
82
+ */
83
+ analyzeRisk(tokens: Token[]): CommandRisk;
84
+ /**
85
+ * Full semantic analysis: tokenize + assess risk.
86
+ */
87
+ analyze(input: string): {
88
+ ast: ShellAST;
89
+ risk: CommandRisk;
90
+ };
91
+ }
92
+ //# sourceMappingURL=shell-tokenizer.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-tokenizer.d.ts","sourceRoot":"","sources":["../../src/policy/shell-tokenizer.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,oBAAY,SAAS;IACnB,IAAI,SAAS;IACb,MAAM,WAAW;IACjB,QAAQ,aAAa;IACrB,oBAAoB,yBAAyB;IAC7C,qBAAqB,0BAA0B;IAC/C,IAAI,SAAS;IACb,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,MAAM,WAAW,CAAM,KAAK;IAC5B,KAAK,UAAU,CAAQ,KAAK;IAC5B,UAAU,eAAe;IACzB,QAAQ,aAAa;CACtB;AAED,MAAM,WAAW,KAAK;IACpB,IAAI,EAAE,SAAS,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;IACd,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAC;IACd,sCAAsC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,kEAAkE;IAClE,QAAQ,CAAC,EAAE,KAAK,EAAE,CAAC;CACpB;AAED,MAAM,WAAW,QAAQ;IACvB,qDAAqD;IACrD,QAAQ,EAAE,KAAK,EAAE,CAAC;IAClB,mEAAmE;IACnE,QAAQ,EAAE,MAAM,EAAE,CAAC;CACpB;AAED;;GAEG;AACH,MAAM,WAAW,WAAW;IAC1B,8CAA8C;IAC9C,sBAAsB,EAAE,OAAO,CAAC;IAChC,qCAAqC;IACrC,QAAQ,EAAE,OAAO,CAAC;IAClB,8CAA8C;IAC9C,YAAY,EAAE,OAAO,CAAC;IACtB,2CAA2C;IAC3C,gBAAgB,EAAE,OAAO,CAAC;IAC1B,qDAAqD;IACrD,iBAAiB,EAAE,MAAM,EAAE,CAAC;IAC5B,iCAAiC;IACjC,mBAAmB,EAAE,MAAM,EAAE,CAAC;CAC/B;AAED;;;;GAIG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,QAAQ,CAAC,kBAAkB,CAShC;IAEH;;OAEG;IACH,QAAQ,CAAC,KAAK,EAAE,MAAM,GAAG,QAAQ;IA6BjC;;OAEG;IACH,OAAO,CAAC,SAAS;IA2IjB;;;OAGG;IACH,OAAO,CAAC,cAAc;IA0CtB;;OAEG;IACH,WAAW,CAAC,MAAM,EAAE,KAAK,EAAE,GAAG,WAAW;IAoDzC;;OAEG;IACH,OAAO,CAAC,KAAK,EAAE,MAAM,GAAG;QAAE,GAAG,EAAE,QAAQ,CAAC;QAAC,IAAI,EAAE,WAAW,CAAA;KAAE;CAK7D"}
@@ -0,0 +1,300 @@
1
+ /**
2
+ * Shell Command Tokenizer & Semantic Analyzer
3
+ *
4
+ * Parses tool argument strings into tokenized AST nodes for semantic
5
+ * security analysis. Goes beyond regex pattern matching by understanding
6
+ * shell grammar: pipelines, redirects, command substitutions, logical chains.
7
+ *
8
+ * This is the semantic detection layer that addresses the architectural
9
+ * limitation of regex-only detection. Instead of pattern-matching "$(rm -rf /)"
10
+ * we parse it as a CommandSubstitution AST node and then analyze the inner
11
+ * command semantically.
12
+ */
13
+ export var TokenType;
14
+ (function (TokenType) {
15
+ TokenType["WORD"] = "WORD";
16
+ TokenType["STRING"] = "STRING";
17
+ TokenType["VARIABLE"] = "VARIABLE";
18
+ TokenType["COMMAND_SUBSTITUTION"] = "COMMAND_SUBSTITUTION";
19
+ TokenType["BACKTICK_SUBSTITUTION"] = "BACKTICK_SUBSTITUTION";
20
+ TokenType["PIPE"] = "PIPE";
21
+ TokenType["REDIRECT"] = "REDIRECT";
22
+ TokenType["SEMICOLON"] = "SEMICOLON";
23
+ TokenType["AND_IF"] = "AND_IF";
24
+ TokenType["OR_IF"] = "OR_IF";
25
+ TokenType["BACKGROUND"] = "BACKGROUND";
26
+ TokenType["SUBSHELL"] = "SUBSHELL";
27
+ })(TokenType || (TokenType = {}));
28
+ /**
29
+ * ShellTokenizer parses shell-like input into an AST without executing anything.
30
+ * It's a security analyzer, not a full POSIX shell parser — focus is on detecting
31
+ * execution patterns that signal malicious intent.
32
+ */
33
+ export class ShellTokenizer {
34
+ DANGEROUS_COMMANDS = new Set([
35
+ 'rm', 'dd', 'mkfs', 'fdisk', 'shred',
36
+ 'chmod', 'chown', 'passwd', 'mount', 'umount',
37
+ 'iptables', 'nc', 'curl', 'wget', 'telnet',
38
+ 'eval', 'exec', 'source', 'bash', 'sh', 'zsh',
39
+ 'python', 'perl', 'ruby', 'node', 'php',
40
+ 'ssh', 'scp', 'rsync',
41
+ 'kill', 'pkill', 'reboot', 'shutdown', 'halt',
42
+ 'tcpdump', 'nmap', 'traceroute',
43
+ ]);
44
+ /**
45
+ * Tokenize a string that may contain shell syntax.
46
+ */
47
+ tokenize(input) {
48
+ const warnings = [];
49
+ const tokens = [];
50
+ let pos = 0;
51
+ while (pos < input.length) {
52
+ // Skip whitespace
53
+ if (/\s/.test(input[pos])) {
54
+ pos++;
55
+ continue;
56
+ }
57
+ const result = this.nextToken(input, pos);
58
+ if (!result)
59
+ break;
60
+ tokens.push(result.token);
61
+ pos = result.nextPos;
62
+ if (result.token.type === TokenType.WORD) {
63
+ const word = result.token.value.toLowerCase();
64
+ if (this.DANGEROUS_COMMANDS.has(word)) {
65
+ warnings.push(`Dangerous command detected: '${result.token.value}'`);
66
+ }
67
+ }
68
+ }
69
+ return { commands: tokens, warnings };
70
+ }
71
+ /**
72
+ * Parse the next token starting at position pos.
73
+ */
74
+ nextToken(input, pos) {
75
+ const ch = input[pos];
76
+ if (ch === undefined)
77
+ return null;
78
+ // ── Pipe ──────────────────────────────────────────
79
+ if (ch === '|' && input[pos + 1] !== '|') {
80
+ return {
81
+ token: { type: TokenType.PIPE, value: '|', start: pos, end: pos + 1 },
82
+ nextPos: pos + 1,
83
+ };
84
+ }
85
+ // ── Logical operators && || ────────────────────────
86
+ if (ch === '&' && input[pos + 1] === '&') {
87
+ return {
88
+ token: { type: TokenType.AND_IF, value: '&&', start: pos, end: pos + 2 },
89
+ nextPos: pos + 2,
90
+ };
91
+ }
92
+ if (ch === '|' && input[pos + 1] === '|') {
93
+ return {
94
+ token: { type: TokenType.OR_IF, value: '||', start: pos, end: pos + 2 },
95
+ nextPos: pos + 2,
96
+ };
97
+ }
98
+ // ── Semicolon ─────────────────────────────────────
99
+ if (ch === ';') {
100
+ return {
101
+ token: { type: TokenType.SEMICOLON, value: ';', start: pos, end: pos + 1 },
102
+ nextPos: pos + 1,
103
+ };
104
+ }
105
+ // ── Background & ──────────────────────────────────
106
+ if (ch === '&') {
107
+ return {
108
+ token: { type: TokenType.BACKGROUND, value: '&', start: pos, end: pos + 1 },
109
+ nextPos: pos + 1,
110
+ };
111
+ }
112
+ // ── Redirect > >> < << <<< >& ─────────────────────
113
+ if (ch === '>' || ch === '<') {
114
+ let end = pos + 1;
115
+ if (input[end] === '>' || input[end] === ch)
116
+ end++;
117
+ if (input[end] === '&' && ch === '>')
118
+ end++;
119
+ return {
120
+ token: { type: TokenType.REDIRECT, value: input.slice(pos, end), start: pos, end },
121
+ nextPos: end,
122
+ };
123
+ }
124
+ // ── Command substitution $(...) ────────────────────
125
+ if (ch === '$' && input[pos + 1] === '(') {
126
+ return this.parseDelimited(input, pos, '$(', ')', TokenType.COMMAND_SUBSTITUTION);
127
+ }
128
+ // ── Backtick substitution `...` ────────────────────
129
+ if (ch === '`') {
130
+ return this.parseDelimited(input, pos, '`', '`', TokenType.BACKTICK_SUBSTITUTION);
131
+ }
132
+ // ── Variable ${...} or $NAME ─────────────────────
133
+ if (ch === '$') {
134
+ if (input[pos + 1] === '{') {
135
+ return this.parseDelimited(input, pos, '${', '}', TokenType.VARIABLE);
136
+ }
137
+ // Simple variable: $NAME, $1, $@, $?
138
+ let end = pos + 1;
139
+ if (/[A-Za-z0-9_?!@#*]/.test(input[end] || '')) {
140
+ end++;
141
+ while (end < input.length && /[A-Za-z0-9_]/.test(input[end]))
142
+ end++;
143
+ }
144
+ return {
145
+ token: { type: TokenType.VARIABLE, value: input.slice(pos, end), start: pos, end },
146
+ nextPos: end,
147
+ };
148
+ }
149
+ // ── Subshell (...) ────────────────────────────────
150
+ if (ch === '(') {
151
+ return this.parseDelimited(input, pos, '(', ')', TokenType.SUBSHELL);
152
+ }
153
+ // ── Single-quoted string ──────────────────────────
154
+ if (ch === "'") {
155
+ const end = input.indexOf("'", pos + 1);
156
+ if (end === -1) {
157
+ // Unterminated — consume rest
158
+ return {
159
+ token: { type: TokenType.STRING, value: input.slice(pos), start: pos, end: input.length },
160
+ nextPos: input.length,
161
+ };
162
+ }
163
+ return {
164
+ token: { type: TokenType.STRING, value: input.slice(pos, end + 1), start: pos, end: end + 1 },
165
+ nextPos: end + 1,
166
+ };
167
+ }
168
+ // ── Double-quoted string ──────────────────────────
169
+ if (ch === '"') {
170
+ const end = input.indexOf('"', pos + 1);
171
+ if (end === -1) {
172
+ return {
173
+ token: { type: TokenType.STRING, value: input.slice(pos), start: pos, end: input.length },
174
+ nextPos: input.length,
175
+ };
176
+ }
177
+ return {
178
+ token: { type: TokenType.STRING, value: input.slice(pos, end + 1), start: pos, end: end + 1 },
179
+ nextPos: end + 1,
180
+ };
181
+ }
182
+ // ── Word (unquoted command/argument) ──────────────
183
+ let end = pos;
184
+ while (end < input.length &&
185
+ !/\s/.test(input[end]) &&
186
+ !'|&;<>$`\'"()'.includes(input[end])) {
187
+ end++;
188
+ }
189
+ if (end > pos) {
190
+ return {
191
+ token: { type: TokenType.WORD, value: input.slice(pos, end), start: pos, end },
192
+ nextPos: end,
193
+ };
194
+ }
195
+ // Consume unknown char
196
+ return {
197
+ token: { type: TokenType.WORD, value: ch, start: pos, end: pos + 1 },
198
+ nextPos: pos + 1,
199
+ };
200
+ }
201
+ /**
202
+ * Parse a delimited token like $(...), ${...}, `...`, (...).
203
+ * Recursively tokenizes inner content.
204
+ */
205
+ parseDelimited(input, pos, open, close, type) {
206
+ let depth = 1;
207
+ let index = pos + open.length;
208
+ const start = pos;
209
+ while (index < input.length && depth > 0) {
210
+ if (input.slice(index, index + open.length) === open && type === TokenType.SUBSHELL) {
211
+ depth++;
212
+ index += open.length;
213
+ continue;
214
+ }
215
+ if (input.slice(index, index + close.length) === close) {
216
+ depth--;
217
+ if (depth === 0) {
218
+ index += close.length;
219
+ break;
220
+ }
221
+ }
222
+ index++;
223
+ }
224
+ const inner = input.slice(start + open.length, index - close.length);
225
+ const innerAst = this.tokenize(inner);
226
+ return {
227
+ token: {
228
+ type,
229
+ value: input.slice(start, index),
230
+ start,
231
+ end: index,
232
+ children: innerAst.commands.length > 0 ? innerAst.commands : undefined,
233
+ },
234
+ nextPos: index,
235
+ };
236
+ }
237
+ /**
238
+ * Analyze a token for risk.
239
+ */
240
+ analyzeRisk(tokens) {
241
+ const risk = {
242
+ hasCommandSubstitution: false,
243
+ hasPipes: false,
244
+ hasRedirects: false,
245
+ hasLogicalChains: false,
246
+ dangerousCommands: [],
247
+ shellMetacharacters: [],
248
+ };
249
+ const walkTokens = (list) => {
250
+ for (const token of list) {
251
+ switch (token.type) {
252
+ case TokenType.COMMAND_SUBSTITUTION:
253
+ case TokenType.BACKTICK_SUBSTITUTION:
254
+ risk.hasCommandSubstitution = true;
255
+ if (token.children)
256
+ walkTokens(token.children);
257
+ break;
258
+ case TokenType.PIPE:
259
+ risk.hasPipes = true;
260
+ break;
261
+ case TokenType.REDIRECT:
262
+ risk.hasRedirects = true;
263
+ break;
264
+ case TokenType.AND_IF:
265
+ case TokenType.OR_IF:
266
+ risk.hasLogicalChains = true;
267
+ break;
268
+ case TokenType.WORD:
269
+ if (this.DANGEROUS_COMMANDS.has(token.value.toLowerCase())) {
270
+ if (!risk.dangerousCommands.includes(token.value)) {
271
+ risk.dangerousCommands.push(token.value);
272
+ }
273
+ }
274
+ break;
275
+ case TokenType.SUBSHELL:
276
+ risk.shellMetacharacters.push('(...)');
277
+ if (token.children)
278
+ walkTokens(token.children);
279
+ break;
280
+ case TokenType.VARIABLE:
281
+ risk.shellMetacharacters.push(token.value);
282
+ break;
283
+ default:
284
+ break;
285
+ }
286
+ }
287
+ };
288
+ walkTokens(tokens);
289
+ return risk;
290
+ }
291
+ /**
292
+ * Full semantic analysis: tokenize + assess risk.
293
+ */
294
+ analyze(input) {
295
+ const ast = this.tokenize(input);
296
+ const risk = this.analyzeRisk(ast.commands);
297
+ return { ast, risk };
298
+ }
299
+ }
300
+ //# sourceMappingURL=shell-tokenizer.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shell-tokenizer.js","sourceRoot":"","sources":["../../src/policy/shell-tokenizer.ts"],"names":[],"mappings":"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"}
@@ -1,10 +1,19 @@
1
+ import { createServer } from 'http';
1
2
  import { PolicyWatcher } from '../policy/policy-watcher.js';
3
+ import { DashboardAuth } from '../auth/dashboard-auth.js';
2
4
  /**
3
5
  * Lightweight dashboard server that serves:
4
- * - / — the dashboard HTML
5
- * - /api/policycurrent policy (JSON)
6
- * - /api/policy/reloadtrigger policy reload
7
- * - /metricsPrometheus metrics
6
+ * - / — the dashboard HTML (requires auth if enabled)
7
+ * - /loginlogin page (when JWT auth is enabled)
8
+ * - /api/loginPOST login endpoint
9
+ * - /api/policycurrent policy (JSON, requires auth)
10
+ * - /api/policy/reload — trigger policy reload (requires auth)
11
+ * - /metrics — Prometheus metrics (can be auth-gated or public via DASHBOARD_METRICS_PUBLIC=true)
12
+ *
13
+ * v1.2: Integrated DashboardAuth for JWT/API key authentication, CSRF protection.
8
14
  */
9
- export declare function startDashboardServer(port?: number, policyWatcher?: PolicyWatcher): Promise<void>;
15
+ export declare function startDashboardServer(port?: number, policyWatcher?: PolicyWatcher, dashboardAuth?: DashboardAuth): Promise<{
16
+ auth: DashboardAuth;
17
+ server: ReturnType<typeof createServer>;
18
+ }>;
10
19
  //# sourceMappingURL=dashboard-server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"dashboard-server.d.ts","sourceRoot":"","sources":["../../src/utils/dashboard-server.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAM5D;;;;;;GAMG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,GAAE,MAAa,EACnB,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC,IAAI,CAAC,CA2Ef"}
1
+ {"version":3,"file":"dashboard-server.d.ts","sourceRoot":"","sources":["../../src/utils/dashboard-server.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAmC,MAAM,MAAM,CAAC;AAKrE,OAAO,EAAE,aAAa,EAAE,MAAM,6BAA6B,CAAC;AAC5D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAM1D;;;;;;;;;;GAUG;AACH,wBAAsB,oBAAoB,CACxC,IAAI,GAAE,MAAa,EACnB,aAAa,CAAC,EAAE,aAAa,EAC7B,aAAa,CAAC,EAAE,aAAa,GAC5B,OAAO,CAAC;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,UAAU,CAAC,OAAO,YAAY,CAAC,CAAA;CAAE,CAAC,CA2P3E"}