Security 9 min read

The Ultimate Web Form Security Checklist for 2025

A comprehensive security checklist for web forms covering encryption, validation, CSRF protection, rate limiting, and more. Protect your users and your business.

By VeilForms Team

Web forms are a primary attack vector. Every form on your site is a potential entry point for malicious actors. This checklist covers essential security measures for any web form.

Transport Security

HTTPS/TLS

  • All pages with forms use HTTPS
  • TLS 1.2 or higher (TLS 1.0 and 1.1 are deprecated)
  • Strong cipher suites configured
  • HSTS header enabled
  • Certificate valid and from trusted CA
Strict-Transport-Security: max-age=31536000; includeSubDomains

Content Security Policy

  • CSP header configured to prevent XSS
  • form-action directive limits where forms can submit
Content-Security-Policy: default-src 'self'; form-action 'self' https://api.veilforms.com;

Input Validation

Client-Side Validation

  • Required fields marked and validated
  • Input types appropriate (email, tel, number, etc.)
  • Pattern matching for formatted inputs
  • Length limits on text inputs
  • Helpful error messages (don’t reveal system info)
<input type="email" name="email" required
       pattern="[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$"
       maxlength="254"
       title="Please enter a valid email address">

Server-Side Validation

  • All inputs validated server-side (never trust client)
  • Type checking (string, number, date, etc.)
  • Length validation (min/max)
  • Format validation (regex patterns)
  • Business logic validation
  • Sanitization before storage
// Server-side validation example
function validateEmail(email) {
  if (typeof email !== 'string') return false;
  if (email.length > 254) return false;
  const emailRegex = /^[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}$/i;
  return emailRegex.test(email);
}

CSRF Protection

  • CSRF tokens on all state-changing forms
  • Token validation on server
  • Tokens are unique per session
  • SameSite cookie attribute set
<form method="POST">
  <input type="hidden" name="_csrf" value="{{ csrfToken }}">
  <!-- form fields -->
</form>

Rate Limiting

  • Submission rate limiting (e.g., 10 per minute per IP)
  • Exponential backoff for repeated failures
  • CAPTCHA for high-risk forms
  • Honeypot fields for bot detection
<!-- Honeypot field - hidden from users, bots fill it in -->
<div style="display:none">
  <input type="text" name="website" tabindex="-1" autocomplete="off">
</div>

Data Protection

Encryption

  • Client-side encryption for sensitive data
  • Encryption at rest for stored data
  • Key management procedures documented
  • Encryption algorithms are current (AES-256, RSA-2048+)
// Client-side encryption with VeilForms
VeilForms.init({
  formId: 'contact',
  publicKey: 'your-public-key',
  encryption: {
    algorithm: 'AES-256-GCM',
    keyDerivation: 'RSA-OAEP'
  }
});

Data Minimization

  • Only collect necessary data
  • Don’t require optional fields
  • Clear retention policies
  • Automatic data deletion when no longer needed

PII Handling

  • PII identified in form submissions
  • Appropriate protections for PII
  • Access controls for PII
  • Audit logging for PII access

Authentication Forms

Login Forms

  • Rate limiting on login attempts
  • Account lockout after failures
  • Generic error messages (don’t reveal if user exists)
  • Secure password requirements enforced
  • Multi-factor authentication available
<!-- Good: Generic error message -->
<p class="error">Invalid email or password</p>

<!-- Bad: Reveals user existence -->
<p class="error">No account found for this email</p>

Password Fields

  • type=“password” attribute
  • autocomplete=“new-password” for registration
  • autocomplete=“current-password” for login
  • Password strength indicator
  • No password in URL or logs
<input type="password" name="password"
       autocomplete="new-password"
       minlength="12"
       required>

Password Reset

  • Token-based reset (not security questions)
  • Token expiration (15-60 minutes)
  • One-time use tokens
  • Invalidate existing sessions on reset

File Upload Security

  • File type validation (whitelist allowed types)
  • File size limits
  • Filename sanitization
  • Store outside web root
  • Virus scanning for uploads
  • Rename files (don’t use user-provided names)
// Server-side file validation
const ALLOWED_TYPES = ['image/jpeg', 'image/png', 'application/pdf'];
const MAX_SIZE = 10 * 1024 * 1024; // 10MB

function validateFile(file) {
  if (!ALLOWED_TYPES.includes(file.mimetype)) {
    throw new Error('File type not allowed');
  }
  if (file.size > MAX_SIZE) {
    throw new Error('File too large');
  }
}

SQL Injection Prevention

  • Parameterized queries (never concatenate user input)
  • ORM/query builder with proper escaping
  • Least privilege database accounts
  • Input validation before queries
// Bad: SQL injection vulnerability
const query = `SELECT * FROM users WHERE email = '${email}'`;

// Good: Parameterized query
const query = 'SELECT * FROM users WHERE email = $1';
const result = await db.query(query, [email]);

XSS Prevention

  • Output encoding for all user data
  • Content Security Policy headers
  • HttpOnly cookies for sessions
  • Input sanitization (but encoding is primary defense)
// Always encode output
function encodeHTML(str) {
  return str.replace(/[&<>"']/g, (char) => ({
    '&': '&amp;',
    '<': '&lt;',
    '>': '&gt;',
    '"': '&quot;',
    "'": '&#39;'
  }[char]));
}

Logging and Monitoring

  • Log form submissions (without sensitive data)
  • Log validation failures
  • Log authentication attempts
  • Alert on anomalies (spike in failures, etc.)
  • Regular log review
// Log submission without sensitive data
logger.info('Form submission', {
  formId: 'contact',
  timestamp: new Date().toISOString(),
  ip: request.ip,
  userAgent: request.headers['user-agent'],
  success: true
  // Don't log: email, message, or other form data
});

Accessibility Security

  • Error messages are accessible
  • CAPTCHA alternatives for accessibility
  • Form labels properly associated
  • Focus management on errors

Testing

  • Automated security scanning (OWASP ZAP, etc.)
  • Manual penetration testing
  • Dependency vulnerability scanning
  • Regular security audits

Incident Response

  • Incident response plan documented
  • Contact information for security issues
  • Breach notification procedures
  • Regular security training for team

Quick Wins

If you can only do a few things, prioritize:

  1. HTTPS everywhere - Non-negotiable
  2. Server-side validation - Never trust client input
  3. CSRF tokens - Prevent cross-site attacks
  4. Parameterized queries - Prevent SQL injection
  5. Output encoding - Prevent XSS
  6. Client-side encryption - Protect sensitive data

Security is a process, not a destination. Use this checklist as a starting point, and regularly review your form security as threats evolve.

Need help securing your forms? VeilForms handles encryption, validation, and security best practices out of the box.