# 🔒 Security Documentation

## Security Audit Summary

This document describes the security measures implemented in the Spec-Kit Plus MCP Server to protect against common vulnerabilities.

---

## ✅ Security Measures Implemented

### 1. Path Traversal Prevention

**Threat:** Attackers could use `..` patterns to write files outside the intended directory.

**Mitigation:**
```python
# Regex pattern detects path traversal attempts
PATH_TRAVERSAL_PATTERN = re.compile(r'\.\.[\\/]|^[.]{2}$|[\\/]\.\.[\\/]|[\\/]\.\.$')

# All paths are validated before use
is_valid, result = _validate_project_path(project_path)
if not is_valid:
    return f"❌ Invalid project path: {result}"
```

**Protected Tools:** `speckit_constitution`, `speckit_specify`, `speckit_plan`, `speckit_tasks`, `speckit_implement`, `speckit_clarify`

---

### 2. Input Validation - AI Agent Whitelist

**Threat:** Malicious AI agent names could be used for injection attacks.

**Mitigation:**
```python
ALLOWED_AI_AGENTS = frozenset([
    "qwen", "claude", "gemini", "copilot", 
    "cursor", "windsurf", "opencode", "codex", "amp"
])

def _validate_ai_agent(ai_agent: str) -> tuple[bool, str]:
    if ai_agent.lower() not in ALLOWED_AI_AGENTS:
        return False, f"Invalid AI agent. Allowed: {', '.join(sorted(ALLOWED_AI_AGENTS))}"
```

**Protected Tools:** `speckit_init`

---

### 3. Content Length Limits

**Threat:** DoS attacks via extremely large inputs.

**Mitigation:**
```python
MAX_PATH_LENGTH = 255
MAX_CONTENT_LENGTH = 10000  # Max characters for principles/requirements/tech_stack

def _validate_content(content: str, field_name: str) -> tuple[bool, str]:
    if len(content) > MAX_CONTENT_LENGTH:
        return False, f"{field_name} exceeds maximum length of {MAX_CONTENT_LENGTH} characters"
```

**Protected Tools:** `speckit_constitution`, `speckit_specify`, `speckit_plan`

---

### 4. Null Byte Injection Prevention

**Threat:** Null bytes (`\x00`) can be used to truncate strings and bypass validation.

**Mitigation:**
```python
# Check all inputs for null bytes
if '\x00' in project_path:
    return False, "Null bytes are not allowed in path"

if '\x00' in content:
    return False, f"Null bytes are not allowed in {field_name}"
```

**Protected Tools:** All tools

---

### 5. Safe Path Joining

**Threat:** Even with validation, path joining could be exploited.

**Mitigation:**
```python
def _safe_join_path(base_path: str, *subpaths: str) -> str:
    base = Path(base_path).resolve()
    result = base
    
    for subpath in subpaths:
        # Sanitize subpath - remove any traversal attempts
        clean_subpath = re.sub(r'\.\.[\\/]', '', subpath)
        result = result / clean_subpath
    
    # Ensure final path is still within base
    try:
        result.resolve().relative_to(base)
    except ValueError:
        raise ValueError(f"Path traversal detected: {subpaths}")
    
    return str(result)
```

**Protected Tools:** `speckit_constitution`, `speckit_specify`, `speckit_plan`

---

### 6. No Shell Injection (shell=False)

**Threat:** Command injection via shell metacharacters.

**Mitigation:**
```python
# ✅ SAFE - Using list form (NOT shell=True)
subprocess.run(
    ["sp"] + args,  # List form prevents shell injection
    capture_output=True,
    text=True,
    timeout=300  # 5 minute timeout
)
```

**Protected Tools:** `speckit_init`, `speckit_check`

---

### 7. Command Timeout Protection

**Threat:** DoS via hanging subprocess calls.

**Mitigation:**
```python
subprocess.run(
    ["sp"] + args,
    timeout=300  # 5 minute timeout
)
```

**Protected Tools:** `speckit_init`, `speckit_check`

---

### 8. Spec-Kit Project Validation

**Threat:** Writing files to arbitrary directories.

**Mitigation:**
```python
def _validate_project_path(project_path: str) -> tuple[bool, str]:
    # ... other checks ...
    
    # Check for .specify folder (indicates initialized Spec-Kit project)
    specify_folder = resolved_path / ".specify"
    if not specify_folder.exists():
        return False, f"Not an initialized Spec-Kit project: {project_path}. Run 'sp init' first."
```

**Protected Tools:** All tools accepting `project_path`

---

### 9. Error Message Sanitization

**Threat:** Information disclosure via error messages.

**Mitigation:**
```python
except Exception as e:
    # Sanitize error message to avoid leaking sensitive info
    error_msg = str(e).replace(os.getcwd(), "<cwd>")
    return f"❌ Error: {type(e).__name__} occurred"
```

---

### 10. UTF-8 Encoding for File Operations

**Threat:** Encoding-based attacks or data corruption.

**Mitigation:**
```python
with open(prompt_file, "w", encoding="utf-8") as f:
    f.write(validated_principles)
```

**Protected Tools:** `speckit_constitution`, `speckit_specify`, `speckit_plan`

---

## 🚫 What's NOT Protected Against

### 1. Spec-Kit CLI Vulnerabilities

If the underlying `sp` CLI has vulnerabilities, they could affect this MCP server. The server mitigates this by:
- Using list-form subprocess calls (no shell=True)
- Validating all inputs before passing to `sp`
- Implementing timeouts

### 2. Authorized User Misuse

The security measures protect against external attacks, not misuse by authorized users. Users with MCP access can:
- Initialize projects
- Write specification files
- Run the Spec-Kit workflow

This is intended behavior.

### 3. Network Attacks

This MCP server runs locally and does not expose network endpoints. Network security depends on the host system.

---

## 📋 Security Checklist for Deployment

- [ ] Ensure `sp` CLI is installed from trusted source (PyPI)
- [ ] Run MCP server with minimal required permissions
- [ ] Do not expose MCP server over network
- [ ] Keep Python and dependencies updated
- [ ] Review logs periodically for suspicious activity

---

## 🐛 Reporting Security Issues

If you discover a security vulnerability, please report it privately before public disclosure.

---

## 📝 Security Changelog

### v0.1.0 - Security Hardening

**Added:**
- Path traversal prevention with regex validation
- AI agent whitelist validation
- Content length limits (10,000 characters)
- Null byte injection prevention
- Safe path joining with resolution verification
- Command timeout (5 minutes)
- Spec-Kit project validation (requires `.specify` folder)
- Error message sanitization
- UTF-8 encoding for all file operations

**Fixed:**
- Removed `description` parameter from FastMCP (compatibility)
- Sanitized error messages to prevent path disclosure
