Skip to content
BAEM1N.DEV — AI, RAG, LLMOps 개발 블로그
Go back

DeepCoWork #11: Security Checklist -- Path Traversal, Input Validation, CSP, CORS

TL;DR: Nine layers of defense-in-depth — path traversal prevention, CORS whitelist, file size limits, HITL approval, and more — control AI agent filesystem access.

Table of contents

Open Table of contents

Threat Model

The threat model combines the OWASP Top 10 with AI agent-specific threats.

ThreatVectorImpact
Path traversal../../etc/passwdSystem file read/write
Prompt injectionMalicious user inputAgent executes unintended commands
Unrestricted shellrm -rf /System destruction
API key leakLogs, error messagesCost incurred, data exposure
Large file attack10GB file uploadMemory/disk exhaustion

1. Path Traversal Prevention

is_safe_path() validates every file access:

def is_safe_path(base: Path, target: Path) -> bool:
    try:
        target.resolve().relative_to(base.resolve())
        return True
    except ValueError:
        return False

Path.resolve() expands symlinks and .., then relative_to() checks containment within the base directory. Used in file read/write endpoints, skill directories, and workspace paths.

2. Workspace Boundary Check

User-specified workspace paths outside the home directory (~) are rejected and replaced with a default path. Prevents access to the root filesystem.

3. Skill Name Validation

def _validate_skill_name(name: str) -> str:
    if not re.match(r'^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$', name):
        raise HTTPException(400, "Lowercase letters, numbers, hyphens only (1-64 chars)")
    if ".." in name or "/" in name or "\\" in name:
        raise HTTPException(400, "Invalid skill name")
    return name

Since skill names become directory names, path separators are strictly rejected.

4. CORS Whitelist

app.add_middleware(
    CORSMiddleware,
    allow_origins=[
        "http://127.0.0.1", "http://localhost",
        "tauri://localhost", "https://tauri.localhost",
    ],
    allow_origin_regex=r"http://(127\.0\.0\.1|localhost):\d+",
    allow_methods=["GET", "POST", "PUT", "DELETE"],
    allow_headers=["Content-Type", "Accept"],
)

Only localhost and Tauri-specific origins are allowed. Following the Tauri security documentation recommendations, external websites cannot call the API.

5. File Size Limits

ResourceLimit
General files10MB
Memory files (SOUL/USER/AGENTS.md)50KB
Shell command output50KB (max_output_bytes)
Tool result SSE transmission2KB (truncated)

6. HITL: Human Approval Gate

Dangerous tool calls cannot execute without user approval. Read-only tools are auto-approved. 300-second timeout triggers auto-rejection.

7. Shell Command Limits

LocalShellBackend restricts working directory, enforces 60-second timeout, and caps output at 50KB.

8. API Key Protection

Settings API returns api_key_set: true/false instead of the actual key value. Keys are stored only in environment variables and ~/.cowork.env.

Benchmark

MetricValue
is_safe_path() verification overhead~0.1ms/call
CORS allowed origins4 (localhost variants + Tauri)
General file size limit10MB
Memory file size limit50KB
Shell command timeout60 seconds
Skill name regex validation^[a-z0-9][a-z0-9-]{0,62}[a-z0-9]?$

Security Checklist Summary

FAQ

Can the agent run sudo commands?

Technically possible, but HITL shows $ sudo ... to the user for rejection. All shell commands through the execute tool require approval.

Is prompt injection prevented?

There is no system-prompt-level defense. HITL is the practical defense line. Even if the agent generates malicious commands, they will not execute without user approval.


Series

  1. DeepCoWork: I Built an AI Agent Desktop App
  2. Tauri 2 + Python Sidecar
  3. DeepAgents SDK Internals
  4. System Prompt Design per Mode
  5. SSE Streaming Pipeline
  6. HITL Approval Flow
  7. Multi-Agent ACP Mode
  8. Agent Memory 4 Layers
  9. Skills System
  10. LLM Provider Integration
  11. [This post] Security Checklist
  12. GitHub Actions Cross-Platform Build

AI-assisted content
Share this post on:

Previous Post
DeepCoWork #12: GitHub Actions Cross-Platform Build -- PyInstaller Sidecar, CI/CD
Next Post
DeepCoWork #10: LLM Provider Integration -- 5 Backends, Model Auto-Detection, Build Variants