Severity: LOW
Description
The HTTP server in src/server.ts has no rate limiting on any endpoints. While it's bound to localhost by default, this could still be problematic in some scenarios.
Vulnerable Endpoints
POST /agents/:name/run - No rate limit
app.post("/agents/:name/run", async (c) => {
// Fire-and-forget agent run
// No check for duplicate runs or rate limiting
});
POST /tools/call - No rate limit
app.post("/tools/call", async (c) => {
// Direct tool invocation
// Could be expensive (shell commands, file operations)
});
POST /agents - No rate limit
app.post("/agents", async (c) => {
// Agent creation/registration
});
Risk Scenarios
- Localhost Compromise: If localhost is compromised (malicious browser extension, local malware), attacker can spam requests
- Accidental DoS: Buggy client code in a loop could spawn thousands of agent runs
- Resource Exhaustion: Each agent run spawns MCP servers, runs LLM calls, etc.
- Cost Explosion: Anthropic API calls cost money, unlimited runs = unlimited cost
Current Mitigation
- Server binds to
127.0.0.1 only (not 0.0.0.0)
- No network exposure by default
Impact
- Runaway costs from accidental infinite loops
- System resource exhaustion (memory, CPU, file descriptors)
- Database growth (run logs)
- Difficult to kill runaway processes
Recommendation
Add basic rate limiting with a simple in-memory store:
import { Hono } from "hono";
interface RateLimitEntry {
count: number;
resetAt: number;
}
const rateLimits = new Map<string, RateLimitEntry>();
function checkRateLimit(
key: string,
maxRequests: number,
windowMs: number
): { allowed: boolean; retryAfter?: number } {
const now = Date.now();
const entry = rateLimits.get(key);
if (!entry || now > entry.resetAt) {
rateLimits.set(key, { count: 1, resetAt: now + windowMs });
return { allowed: true };
}
if (entry.count >= maxRequests) {
return { allowed: false, retryAfter: Math.ceil((entry.resetAt - now) / 1000) };
}
entry.count++;
return { allowed: true };
}
// Apply to endpoints:
app.post("/agents/:name/run", async (c) => {
const limit = checkRateLimit(`run:${c.req.param("name")}`, 10, 60_000); // 10 per minute
if (!limit.allowed) {
c.header("Retry-After", String(limit.retryAfter));
return c.json({ error: "Rate limit exceeded" }, 429);
}
// ... rest of handler
});
Or use existing middleware like hono-rate-limiter.
Configuration
Make rate limits configurable in ~/.agentd/config.yaml:
rate_limits:
agent_runs_per_minute: 10
tool_calls_per_minute: 100
agent_creation_per_hour: 5
Created by security audit
Severity: LOW
Description
The HTTP server in
src/server.tshas no rate limiting on any endpoints. While it's bound to localhost by default, this could still be problematic in some scenarios.Vulnerable Endpoints
POST
/agents/:name/run- No rate limitPOST
/tools/call- No rate limitPOST
/agents- No rate limitRisk Scenarios
Current Mitigation
127.0.0.1only (not0.0.0.0)Impact
Recommendation
Add basic rate limiting with a simple in-memory store:
Or use existing middleware like
hono-rate-limiter.Configuration
Make rate limits configurable in
~/.agentd/config.yaml:Created by security audit