add security hardening features (#543)
* add security hardening features - Add authentication vault (`auth save/login/list/show/delete`) so credentials are stored locally and never exposed to the LLM (fixes Snyk W007) - Add `--content-boundaries` flag to wrap page-sourced output in structural markers, helping LLMs distinguish tool output from untrusted page content (fixes Snyk W011) - Add `--allowed-domains` flag to restrict browser navigation to trusted domains - Add `--action-policy` for static allow/deny gating of action categories, with opt-in `--confirm-actions`/`--confirm-interactive` for orchestrator or human-in-the-loop confirmation - Add `--max-output` flag to truncate large page outputs, preventing context flooding - New docs page at /security, updated README, SKILL.md, CLI help text, and templates * fixes * fixes * fixes * fixes * fixes * fixes * fixes * docs
This commit is contained in:
@@ -0,0 +1,53 @@
|
||||
import { randomBytes } from 'node:crypto';
|
||||
|
||||
interface PendingConfirmation {
|
||||
id: string;
|
||||
action: string;
|
||||
category: string;
|
||||
description: string;
|
||||
command: Record<string, unknown>;
|
||||
timer: ReturnType<typeof setTimeout>;
|
||||
}
|
||||
|
||||
const AUTO_DENY_TIMEOUT_MS = 60_000;
|
||||
|
||||
const pending = new Map<string, PendingConfirmation>();
|
||||
|
||||
function generateId(): string {
|
||||
return `c_${randomBytes(8).toString('hex')}`;
|
||||
}
|
||||
|
||||
export function requestConfirmation(
|
||||
action: string,
|
||||
category: string,
|
||||
description: string,
|
||||
command: Record<string, unknown>
|
||||
): { confirmationId: string } {
|
||||
const id = generateId();
|
||||
|
||||
const timer = setTimeout(() => {
|
||||
pending.delete(id);
|
||||
}, AUTO_DENY_TIMEOUT_MS);
|
||||
|
||||
pending.set(id, {
|
||||
id,
|
||||
action,
|
||||
category,
|
||||
description,
|
||||
command,
|
||||
timer,
|
||||
});
|
||||
|
||||
return { confirmationId: id };
|
||||
}
|
||||
|
||||
export function getAndRemovePending(
|
||||
id: string
|
||||
): { command: Record<string, unknown>; action: string } | null {
|
||||
const entry = pending.get(id);
|
||||
if (!entry) return null;
|
||||
|
||||
clearTimeout(entry.timer);
|
||||
pending.delete(id);
|
||||
return { command: entry.command, action: entry.action };
|
||||
}
|
||||
Reference in New Issue
Block a user