agentsclimarketplace

Input validation

Skill hereshecodes/secureskills/skills/input-validation

Security skills for AI coding agents. Install once, write secure code every time.

Install
npx -y skills add hereshecodes/secureskills --skill input-validation

Assembled from the repository path, not quoted from the project. Check it against their README if it does not work.

One thing to look at

  • 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.

What its author says it does

Copied from the file, not written here

Use when processing user input, form data, file uploads, or query parameters

SKILL.md

2.9 KB, as published. Nobody here has run it

Input Validation

Validate everything that enters your system. Server-side. Every time. Client-side validation is UX, not security.

Related: injection-prevention, xss-csrf, api-security, security-context

Rule 1: Validate Server-Side (Always)

Client-side validation can be bypassed with one curl command.

// WRONG — only client-side validation
<input type="email" required>  // Attacker skips this entirely

// RIGHT — validate on the server
function createUser(req, res) {
  const { email, name } = req.body;
  if (!email || !isValidEmail(email)) return res.status(400).json({ error: 'Valid email required' });
  if (!name || name.length > 100) return res.status(400).json({ error: 'Name required, max 100 chars' });
  // proceed
}

Rule 2: Whitelist, Don't Blacklist

Reject everything except what you expect. Blacklists always miss something.

// WRONG — trying to block bad characters
if (input.includes('<script>')) reject();

// RIGHT — only allow expected format
if (!/^[a-zA-Z0-9\s\-]{1,100}$/.test(input)) reject();

Rule 3: Validate Type, Length, and Range

Every field has constraints. Enforce them.

# WRONG — no validation
age = request.form['age']
save_user(age=age)

# RIGHT — validate type, range, and length
age = request.form.get('age')
if not age or not age.isdigit() or not (0 <= int(age) <= 150):
    return bad_request('Age must be a number between 0 and 150')
save_user(age=int(age))

Rule 4: Validate File Uploads

Check extension, MIME type, and file signature. Never trust the filename.

// WRONG — trusts the file extension
if (file.originalname.endsWith('.jpg')) saveFile(file);

// RIGHT — check MIME type AND magic bytes
const allowedMimes = ['image/jpeg', 'image/png', 'image/webp'];
if (!allowedMimes.includes(file.mimetype)) reject();

const fileBuffer = fs.readFileSync(file.path);
const type = await fileTypeFromBuffer(fileBuffer);
if (!type || !allowedMimes.includes(type.mime)) reject();

Rule 5: Sanitize Before Storage, Escape Before Display

Two different operations. Both required.

// Sanitize on input (remove dangerous content)
const cleanHtml = DOMPurify.sanitize(userInput);
await saveToDb(cleanHtml);

// Escape on output (prevent XSS in different contexts)
element.textContent = storedValue;  // HTML context

Quick Reference

DoDon't
Validate server-side on every requestRely on client-side validation alone
Whitelist expected formatsBlacklist known bad patterns
Enforce type, length, and range limitsAccept any value from the client
Check file MIME type AND magic bytesTrust file extensions
Sanitize on input, escape on outputSkip either step
Return clear error messagesSilently accept bad input

Keep looking

Skills are one crate of 328,083. Ordering is by how many stacks a row turns up in, so the top of any crate is what has actually been picked rather than what has the most stars.