Form Field Validation: Two Layers, but Only One Stops Bypasses
Use HTML5 constraints for quick feedback, framework patterns for richer rules, and OWASP guidance for server checks that reject untrusted input.

Form field validation checks that user input has the right format and is consistent with what your application expects. Use HTML5 constraints and clear client-side feedback for a smooth experience, then validate everything again on the server using an allowlist approach, because that is the layer attackers cannot skip. Test both layers, and treat every submitted value as untrusted.
TL;DR:
- Use native attributes such as required, type, minlength, maxlength, min, max, and pattern; patterns match the entire value, so explain formats with title text.
- On the server, canonicalize values before applying allowlists, reject choices outside permitted sets, and log unexpected options because they may indicate tampering.
- Test server rules with direct requests that bypass the browser, including missing fields, oversized values, and dropdown choices the form never offered.
- Keep validation rules in a shared schema so browser checks, server enforcement, and tests use the same definitions instead of drifting apart.
- Write errors as instructions, such as the required date format, and check that screen readers announce them and keyboard focus reaches each field.
Table of Contents
- What form validation checks and why it matters
- Client-side vs server-side validation: who checks what
- How to use HTML5 validation and the Constraint Validation API
- JavaScript patterns and frameworks for richer validation
- Security rules for input validation, based on OWASP
- How to test form validation
- Why server-side rules come first, then the polish
- FAQ
- Sources
What form validation checks and why it matters
Form validation checks user input for format, completeness, and logical consistency before your application acts on it. It comes in two flavors, and it helps to keep them apart.
- Syntactic validation checks the shape of a value: an email contains an
@, a ZIP code has the right number of digits, a date follows the expected pattern. - Semantic validation checks whether a value makes sense in context: the end date comes after the start date, the coupon code exists, the quantity does not exceed available stock.
Good validation pays off in two places. For users, immediate feedback means fewer failed submissions, fewer confusing round trips, and better odds that someone finishes your form. For your data, validated input keeps downstream processing, reporting, and automation from choking on malformed values.
Both flavors are covered by MDN’s guidance on input validation, which also stresses that early client-side feedback must be backed by server-side checks.
Client-side vs server-side validation: who checks what
Think of validation as two layers with different jobs. Client-side checks run in the browser and exist for speed and clarity. Server-side checks run on your backend and exist for correctness and security. Neither replaces the other.
Client-side responsibilities:
- Catch obvious mistakes immediately: missing required fields, wrong input types, simple pattern mismatches.
- Show clear, specific error messages next to the field.
- Use native attributes such as
required,type="email", andpatternwherever they fit.
Server-side responsibilities:
- Act as the final authority on every submitted value, however it arrived.
- Enforce business rules the browser cannot safely know, such as pricing, permissions, and uniqueness.
- Canonicalize input, look up authoritative data, and reject anything outside the allowed set.
A quick example makes the split concrete. The browser can confirm that [email protected] looks like an email address. Only your server can confirm that the address belongs to an active account, or that it is not already registered. The first check improves the experience; the second protects your data.
OWASP’s Input Validation Cheat Sheet is blunt about why: an attacker can disable JavaScript or send HTTP requests directly, so client-side checks can always be bypassed.

How to use HTML5 validation and the Constraint Validation API
For many forms, the browser already does the heavy lifting. HTML5 validation attributes and the Constraint Validation API cover most simple constraints without extra scripts. Here is a practical order of work:
- Declare constraints with attributes. Use
required,type(such asemail,number,url),minlength,maxlength,min,max, andpatterndirectly on the input. - Write patterns as full matches. A
patterncan define the expected format and is evaluated against the entire value, so keep it strict and add atitleattribute that explains the expected format. - Read the validity state. Each field exposes a
validityobject (valueMissing,typeMismatch,patternMismatch,tooShort, and others) so you can tell exactly which rule failed. - Trigger checks on demand. Call
checkValidity()to test a field or form silently, orreportValidity()to test and show the browser’s error bubble. - Customize messages. Call
setCustomValidity("Your message")to set your own error text, andsetCustomValidity("")to clear it. Read the result back withvalidationMessage. - Handle what attributes cannot. For file-size limits, read
input.files[0].sizethrough the File API, compare it to your limit, and callsetCustomValiditywhen the file is too large.
<input type="email" id="email" required>
Pro Tip: Always reset the custom message with setCustomValidity("") before re-checking a field. A leftover message keeps the field invalid even after the user fixes it.
JavaScript patterns and frameworks for richer validation
When native attributes run out, add JavaScript. The right tool depends on how complex your form is.
- Vanilla JavaScript: Validate on
inputorblurevents, and debounce the handler so you are not flashing errors on every keystroke. UsesetCustomValidityfor custom rules, compare fields against each other for cross-field checks (password and confirmation, date ranges), and callreportValidity()at submit time. A common trick is addingnovalidateto the form and rendering your own error UI, as discussed in this Stack Overflow thread on HTML form validation. - Angular: Attach synchronous validators for local rules and asynchronous validators for anything that needs a server lookup, such as username availability. See Angular’s form validation guide for how validators attach to controls. Keep async validators for checks that truly need the network, since they add latency.
- Formik with Yup (React): Formik supports synchronous and asynchronous validation, accepts a Yup
validationSchema, and exposesvalidateFormandvalidateFieldfor manual triggering. ChoosevalidateOnChangefor instant feedback orvalidateOnBlurfor a calmer experience on long forms. - FormKit (Vue): FormKit lets you declare rules right on the input, with more than 30 built-in rules. Rule hints such as
debounce,force, andoptionalcontrol when and how each rule runs, so validation stays declarative and reacts as the user types.
Whatever you pick, run the same rules in one place. Schema-first approaches keep client and server definitions from drifting apart.
Security rules for input validation, based on OWASP
Security is where validation stops being a convenience and becomes a requirement. The OWASP guidance boils down to a short checklist:
- Treat all input as untrusted. Form fields, headers, cookies, and hidden inputs all count.
- Prefer allowlists to denylists. Define exactly what is acceptable and reject the rest. Denylists try to predict attacks and lose to new ones.
- Validate at the authoritative boundary. Check on the server as early as possible, after canonicalizing the input so encoded variants cannot slip past your rules.
- Anchor your regexes. Use full-match anchors and avoid permissive patterns like
.*, which accept far more than you intend. - Log suspicious input. A value that violates an expected enumeration, such as a dropdown choice that was never offered, usually signals tampering. Record it and escalate.
Client-side validation can be bypassed by an attacker, so server-side validation is mandatory as the final arbiter of data integrity and security, as OWASP’s Input Validation Cheat Sheet states. Treat browser checks as a courtesy to users, never as a defense.
If you are connecting validated forms to signing flows, our overview of how secure form software protects every submission covers the handling side of this story.
How to test form validation
Validation that is not tested drifts. Cover it at several levels:
- Unit test the rules. Test each validator function and schema rule with valid, invalid, and edge-case values. In Formik, the
validateFormandvalidateFieldhelpers make this straightforward. - Mock async validators. Replace network-backed validators with fixed responses so tests stay fast and deterministic.
- Integration test the server. Send requests that skip the browser entirely, with missing fields, oversized values, and unexpected enumeration choices, and confirm the server rejects each one.
- Check the experience by hand. Tab through the form to confirm focus order, use a screen reader to confirm errors are announced, and read each message asking whether a real person could fix the problem from it alone.
Pro Tip: Write error messages that say what to do (“Enter a date in MM/DD/YYYY format”), not just what went wrong (“Invalid date”).
For forms with conditional logic, our walkthrough on fixing hidden required fields in conditional e-signature forms shows a common validation trap.
Why server-side rules come first, then the polish
My view is simple: sequence your effort by risk. Build the allowlist checks on the server first, because they protect your data whether or not the front end behaves. Then add helpful client-side feedback on top, so honest users get fast, friendly guidance. Centralize rules in a schema so the same definitions power both layers and the test suite stays small. Teams that build the pretty client-side layer first tend to discover, late, that nothing stands behind it. If your forms feed contracts or signatures, our guide to the best secure form builders for sensitive workflows is a good next read.
— Mustafa Abusharkh
FAQ
What do you mean by form validation?
Form validation is the process of checking that user input is complete, correctly formatted, and logically consistent before it is processed. It usually runs in two layers: client-side for immediate feedback and server-side for security and business rules.
How can I validate an email using JavaScript?
Start with <input type="email" required> and call checkValidity() or reportValidity() to use the browser’s built-in check. Add setCustomValidity if you need a custom message. Then confirm the address on the server, since only the server can verify that it belongs to a real, active account.
How do I validate my HTML form code?
Use native attributes such as required, pattern, and minlength, then test them with checkValidity() and the field’s validity object. Verify the same rules on the server, since the browser alone is never enough.
Why validate again on the server if the browser already did?
Browser checks can be skipped by disabling JavaScript or sending requests directly. The server is the only layer you control, so it must enforce every rule independently.
Sources
- Client-side form validation - Learn web development | MDN
- Input Validation - OWASP Cheat Sheet Series
- Validation | Formik
Recommended
Ready to transform your workflow?
Start using BeeSign today and experience the future of document signing