MCP security patterns for prompt injection defense, tool poisoning prevention, and permission management. Use when securing MCP servers, validating tool descriptions, implementing allowlists.
View on GitHubFebruary 4, 2026
Select agents to install to:
npx add-skill https://github.com/yonatangross/skillforge-claude-plugin/blob/main/plugins/ork/skills/mcp-security-hardening/SKILL.md -a claude-code --skill mcp-security-hardeningInstallation paths:
.claude/skills/mcp-security-hardening/# MCP Security Hardening
Defense-in-depth security patterns for Model Context Protocol (MCP) integrations.
## Overview
- Securing MCP server implementations
- Validating tool descriptions before LLM exposure
- Implementing zero-trust tool allowlists
- Detecting tool poisoning attacks (TPA)
- Managing tool permissions and capabilities
## Core Security Principle
> **Treat ALL tool descriptions as untrusted input.**
> **Validate tool identity with hash verification.**
> **Apply least privilege to all tool capabilities.**
## Threat Model Summary
| Attack Vector | Defense | Implementation |
|---------------|---------|----------------|
| Tool Poisoning (TPA) | Zero-trust allowlist | Hash verification, mandatory vetting |
| Prompt Injection | Description sanitization | Regex filtering, encoding detection |
| Rug Pull | Change detection | Hash comparison on each invocation |
| Data Exfiltration | Output filtering | Sensitive pattern removal |
| Session Hijacking | Secure sessions | Cryptographic IDs, no auth in sessions |
## Layer 1: Tool Description Sanitization
```python
import re
FORBIDDEN_PATTERNS = [
r"ignore previous", r"system prompt", r"<.*instruction.*>",
r"IMPORTANT:", r"override", r"admin", r"sudo",
r"\\x[0-9a-fA-F]{2}", # Hex encoding
r"&#x?[0-9a-fA-F]+;", # HTML entities
]
def sanitize_tool_description(description: str) -> str:
"""Remove instruction-like phrases or encoding tricks."""
if not description:
return ""
sanitized = description
for pattern in FORBIDDEN_PATTERNS:
sanitized = re.sub(pattern, "[REDACTED]", sanitized, flags=re.I)
return sanitized.strip()
def detect_injection_attempt(description: str) -> str | None:
"""Detect prompt injection patterns."""
indicators = [
(r"ignore.*previous", "instruction_override"),
(r"you are now", "role_hijack"),
(r"forget.*above", "context_wipe"),
]
for pattern, attack_type in indicators:
if re.search(patter