input-validation

Use when writing or reviewing code that processes user input — validates and sanitizes to prevent SQL injection, XSS, CSRF, and other injection attacks. NOT when the code path doesn't touch user-supplied data.

8 stars

Best use case

input-validation is best used when you need a repeatable AI agent workflow instead of a one-off prompt.

Use when writing or reviewing code that processes user input — validates and sanitizes to prevent SQL injection, XSS, CSRF, and other injection attacks. NOT when the code path doesn't touch user-supplied data.

Teams using input-validation should expect a more consistent output, faster repeated execution, less prompt rewriting.

When to use this skill

  • You want a reusable workflow that can be run more than once with consistent structure.

When not to use this skill

  • You only need a quick one-off answer and do not need a reusable workflow.
  • You cannot install or maintain the underlying files, dependencies, or repository context.

Installation

Claude Code / Cursor / Codex

$curl -o ~/.claude/skills/input-validation/SKILL.md --create-dirs "https://raw.githubusercontent.com/drvoss/everything-copilot-cli/main/skills/security/input-validation/SKILL.md"

Manual Installation

  1. Download SKILL.md from GitHub
  2. Place it in .claude/skills/input-validation/SKILL.md inside your project
  3. Restart your AI agent — it will auto-discover the skill

How input-validation Compares

Feature / Agentinput-validationStandard Approach
Platform SupportNot specifiedLimited / Varies
Context Awareness High Baseline
Installation ComplexityUnknownN/A

Frequently Asked Questions

What does this skill do?

Use when writing or reviewing code that processes user input — validates and sanitizes to prevent SQL injection, XSS, CSRF, and other injection attacks. NOT when the code path doesn't touch user-supplied data.

Where can I find the source code?

You can find the source code on GitHub using the link provided at the top of the page.

SKILL.md Source

# Input Validation

## When to Use

- Building or reviewing API endpoints that accept user input
- Working with database queries, HTML rendering, or form handling
- Auditing an existing application for injection vulnerabilities
- Adding validation middleware to a web framework
- Handling file uploads, URL parameters, or header values

## Prerequisites

- Understanding of the application's input surfaces (APIs, forms, file uploads)
- Access to the codebase's request handlers and data layer
- A validation library available (zod, joi, express-validator, etc.)

## Workflow

### 1. Map Input Surfaces

Identify everywhere user input enters the application:

```powershell
# Find route handlers / API endpoints
grep -rn "app\.\(get\|post\|put\|delete\|patch\)\|router\." src/ --include="*.ts"

# Find request body/query/param access
grep -rn "req\.body\|req\.query\|req\.params\|request\.json" src/ --include="*.ts"

# Find file upload handlers
grep -rn "multer\|upload\|formidable\|busboy" src/ --include="*.ts"
```

### 2. SQL Injection Prevention

```powershell
# Find raw SQL queries — these are high risk
grep -rn "query\s*(\|execute\s*(\|raw\s*(" src/ --include="*.ts" -A 2
```

```typescript
// ❌ VULNERABLE — string concatenation
const result = await db.query(`SELECT * FROM users WHERE id = '${userId}'`);

// ✅ SAFE — parameterized query
const result = await db.query('SELECT * FROM users WHERE id = $1', [userId]);

// ✅ SAFE — ORM with built-in parameterization
const user = await User.findOne({ where: { id: userId } });
```

### 3. XSS Prevention

```powershell
# Find direct HTML rendering with user data
grep -rn "innerHTML\|dangerouslySetInnerHTML\|document\.write\|v-html" src/ --include="*.ts" --include="*.tsx" --include="*.vue"

# Find template rendering without escaping
grep -rn "res\.send\|res\.write" src/ --include="*.ts" -A 3
```

```typescript
// ❌ VULNERABLE — raw HTML insertion
element.innerHTML = userComment;

// ✅ SAFE — text content (auto-escaped)
element.textContent = userComment;

// ✅ SAFE — sanitize before rendering
import DOMPurify from 'dompurify';
element.innerHTML = DOMPurify.sanitize(userComment);
```

### 4. CSRF Prevention

```powershell
# Check for CSRF middleware
grep -rn "csrf\|csurf\|csrfToken" src/ --include="*.ts"

# Find state-changing endpoints without protection
grep -rn "app\.post\|app\.put\|app\.delete" src/ --include="*.ts"
```

```typescript
// Add CSRF protection middleware
import csrf from 'csurf';
app.use(csrf({ cookie: true }));

// Include token in forms
app.get('/form', (req, res) => {
  res.render('form', { csrfToken: req.csrfToken() });
});
```

### 5. Schema Validation at the Boundary

Validate all input at the entry point using a schema library:

```typescript
import { z } from 'zod';

const CreateUserSchema = z.object({
  email: z.string().email().max(254),
  name: z.string().min(1).max(100).trim(),
  age: z.number().int().min(0).max(150),
});

app.post('/users', (req, res) => {
  const result = CreateUserSchema.safeParse(req.body);
  if (!result.success) {
    return res.status(400).json({ errors: result.error.issues });
  }
  // result.data is now typed and validated
  createUser(result.data);
});
```

### 6. Additional Validation Patterns

```typescript
// Path traversal prevention
import path from 'path';
function safePath(userInput: string): string {
  const resolved = path.resolve('/allowed/base', userInput);
  if (!resolved.startsWith('/allowed/base')) {
    throw new Error('Path traversal detected');
  }
  return resolved;
}

// URL validation
function safeUrl(url: string): boolean {
  try {
    const parsed = new URL(url);
    return ['http:', 'https:'].includes(parsed.protocol);
  } catch { return false; }
}
```

## Examples

### Audit Existing Endpoints

```powershell
# Find unvalidated endpoints — routes without validation middleware
grep -rn "router\.\(post\|put\|patch\)" src/routes/ --include="*.ts" -A 5 | grep -v "validate\|schema\|zod\|joi"
```

### Add Validation to an Express Route

```typescript
// middleware/validate.ts
import { ZodSchema } from 'zod';
export function validate(schema: ZodSchema) {
  return (req, res, next) => {
    const result = schema.safeParse(req.body);
    if (!result.success) return res.status(400).json({ errors: result.error.issues });
    req.body = result.data;
    next();
  };
}
```

## Common Rationalizations

| Rationalization | Reality |
|----------------|---------|
| "Frontend already validated it" | HTTP requests can be sent directly without going through a browser. |
| "It's an internal API, we can trust it" | Internal services can be compromised too. Apply zero trust principles. |
| "TypeScript ensures type safety" | TypeScript types are compile-time only. Runtime input must be treated as `unknown`. |
| "We use Zod/joi/yup, so we're covered" | Validation libraries are only as good as the schema. A wrong schema is still wrong. |

## Red Flags

- User input used directly in SQL queries
- `JSON.parse()` results used without validation
- User input included in file paths (path traversal risk)
- `parseInt()` or `parseFloat()` results used without `NaN` checks
- Regex patterns vulnerable to ReDoS (`(a+)+`, `([a-zA-Z]+)*`)

## Verification

- [ ] Server-side validation present for all API endpoint inputs
- [ ] Parameterized queries or ORM used (no raw string interpolation)
- [ ] File uploads validated for type, size, and path
- [ ] Validation failures return 400 responses (no detailed internal error exposure)
- [ ] Input validation tests cover both valid and malicious input cases

## Tips

- **Validate at the boundary, trust internally** — validate once where input enters your system
- Use allowlists over denylists — define what's allowed rather than what's blocked
- Always validate type, length, format, and range
- Use parameterized queries for **all** database access, no exceptions
- Set `Content-Security-Policy` headers to prevent XSS at the browser level
- Never trust client-side validation alone — always validate server-side
- Use `explore` agent to trace how user input flows through the application

Related Skills

verification-before-completion

8
from drvoss/everything-copilot-cli

Use before claiming any task is done — run the exact command that proves the fix works, read the output, and only then report success.

using-git-worktrees

8
from drvoss/everything-copilot-cli

Use when you need multiple branches checked out at once — create isolated working directories for parallel development without cloning the repository repeatedly

triage

8
from drvoss/everything-copilot-cli

Use when a single issue needs structured triage — classify it, reproduce if needed, request missing information, and leave a durable brief or close-out note in the tracker.

to-issues

8
from drvoss/everything-copilot-cli

Use when a plan, spec, or PRD must become an actionable backlog — break it into thin dependency-aware issues that each deliver a verifiable vertical slice

sprint-workflow

8
from drvoss/everything-copilot-cli

Use when starting a new feature, refactor, or multi-step dev task — runs the full sprint cycle (Think → Plan → Build → Review → Test → Ship → Monitor) using Copilot CLI's plan/autopilot modes.

sprint-retro

8
from drvoss/everything-copilot-cli

Use at the end of a sprint to run a data-driven retrospective — analyzes session history and git metrics to surface what shipped, what slowed you down, and concrete improvements.

security-audit

8
from drvoss/everything-copilot-cli

Use when a codebase needs a formal security audit beyond a quick scan — applies OWASP Top 10 and STRIDE threat modeling from a CSO perspective to surface systemic vulnerabilities.

release

8
from drvoss/everything-copilot-cli

Use when a sprint or feature is complete and ready to ship — tags the version, generates GitHub Release notes, runs rollout or smoke verification, and publishes to npm/PyPI/Docker registries.

prompt-optimizer

8
from drvoss/everything-copilot-cli

Use when a rough prompt, vague idea, or task description needs to become a finished copy-pasteable prompt for a chat-based LLM - rewrite it into one ready-to-send prompt with no blanks, no placeholders, and a clear output shape.

outside-voice

8
from drvoss/everything-copilot-cli

Use when you need an independent second opinion before, during, or after implementation — run challenge, consult, or review mode in a direct builder-to-builder voice

llm-wiki

8
from drvoss/everything-copilot-cli

Use when research or domain knowledge keeps getting rediscovered across sessions — build a supplementary markdown wiki that compounds synthesized knowledge without replacing GitHub or committed project guidance

interview-me

8
from drvoss/everything-copilot-cli

Use when a request is underspecified and you need to discover what the user actually wants before writing a plan, spec, or code - ask one question at a time, attach your current hypothesis, and stop only after the intent is explicitly confirmed.