Compare commits

..

No commits in common. "0c512a0cbc171c51bfb0fc368b8a060495d54d87" and "90e7cf37ab8ce718104b7bb6516771c70fe49868" have entirely different histories.

2 changed files with 0 additions and 55 deletions

View file

@ -12,21 +12,6 @@ import { setupAgentWorkspace } from "../agent/identity";
// Allowed characters for agent names: lowercase letters, numbers, hyphens
const NAME_PATTERN = /^[a-z0-9][a-z0-9-]{0,30}[a-z0-9]$/;
/**
* Validates that an agent name is safe and does not escape the workspaces root
* via path traversal. Throws an Error if the resolved path would lie outside root.
*/
export function validateAgentName(name: string, workspacesRoot: string): void {
if (!name) {
throw new Error(`Ungültiger Agent-Name: "${name}"`);
}
const root = path.resolve(workspacesRoot);
const wsPath = path.resolve(root, name);
if (!wsPath.startsWith(root + path.sep)) {
throw new Error(`Ungültiger Agent-Name: "${name}"`);
}
}
export const newAgentCommand = new SlashCommandBuilder()
.setName("new-agent")
.setDescription("Erstellt einen neuen Agenten mit eigenem Kanal und Workspace")
@ -63,15 +48,6 @@ export async function handleNewAgent(
return;
}
// Path-traversal containment check
try {
validateAgentName(name, config.workspaces_root);
} catch (error) {
const msg = error instanceof Error ? error.message : "Ungültiger Agent-Name";
await interaction.reply({ content: msg, ephemeral: true });
return;
}
// Check uniqueness
if (db.getWorkspaceByName(name)) {
await interaction.reply({

View file

@ -1,31 +0,0 @@
import { describe, it, expect } from "vitest";
import { validateAgentName } from "../../src/commands/new-agent";
const ROOT = "/tmp/ws";
describe("validateAgentName path traversal containment", () => {
it('throws for "../etc"', () => {
expect(() => validateAgentName("../etc", ROOT)).toThrow();
});
it('throws for ".."', () => {
expect(() => validateAgentName("..", ROOT)).toThrow();
});
it('does not throw for "a/../b" (resolves to /tmp/ws/b, stays inside root)', () => {
// path.resolve("/tmp/ws", "a/../b") => "/tmp/ws/b" -- still inside root
expect(() => validateAgentName("a/../b", ROOT)).not.toThrow();
});
it('throws for empty string ""', () => {
expect(() => validateAgentName("", ROOT)).toThrow();
});
it('allows "my-agent"', () => {
expect(() => validateAgentName("my-agent", ROOT)).not.toThrow();
});
it('allows "agent-123"', () => {
expect(() => validateAgentName("agent-123", ROOT)).not.toThrow();
});
});