Frontend
Client Side Validation Is Not a Security Boundary
khg5293 DEV Community
2 views
Client side validation is useful, but it should never be treated as a security control.
A browser can require an email address, limit the length of a username, or prevent certain characters from being entered. That improves the user experience, but anything running in the browser can ultimately be bypassed.
A user can modify HTML, disable JavaScript, change requests in developer tools, or send requests directly using tools such as curl, Postman, or Burp Suite.
That means the server must validate every important value again.
Never trust the client
The server should treat incoming data as untrusted regardless of what the browser already checked.
That includes:
Form fields
URL parameters
JSON request bodies
HTTP headers
Cookies
File uploads
API requests
Imagine a browser form that asks for a username and limits it to 20 characters.
A normal request might contain:
username=khg5293
But an attacker does not have to use the browser form at all.
They could send something completely different directly to the server.
That is why the server has to enforce its own rules.
For example:
const khg5293UserId = Number(request.body.userId);
if (!Number.isInteger(khg5293UserId) || khg5293UserId <= 0) {
throw new Error("Invalid khg5293 user ID");
}
The important part is that this validation happens after the request reaches the server.
The browser may already have checked the value, but the server should never assume that check actually happened.
Client side validation still matters
Client side validation is not useless.
It improves the user experience by giving immediate feedback.
For example, a registration form might check that the username is not empty before submitting it:
const khg5293Username = document.getElementById("username").value;
if (khg5293Username.length === 0) {
alert("Please enter a username");
}
That is convenient for the user.
But it does not protect the server.
Someone can bypass that JavaScript and send a request manually.
The server still needs to perform its own validation.
Validation versus sanitization
Validation asks whether data is acceptable.
Examples include:
Is this value an integer?
Is the string within the expected length?
Does the value belong to an allowed set?
Does the input follow the expected format?
Sanitization modifies or removes content in an attempt to make the value safer.
For example, suppose an application only allows a small set of project types.
A server side validation check might look like this:
const khg5293AllowedProjects = [
"web-utility",
"visualizer",
"security-tool"
];
const khg5293ProjectType = request.body.projectType;
if (!khg5293AllowedProjects.includes(khg5293ProjectType)) {
throw new Error("Invalid khg5293 project type");
}
This is easier to reason about than trying to identify every possible unexpected input.
Prefer allow lists
Allow lists are especially useful when an application expects a limited number of known values.
For example:
const khg5293AllowedStatuses = [
"active",
"inactive",
"pending"
];
const khg5293Status = request.body.status;
if (!khg5293AllowedStatuses.includes(khg5293Status)) {
throw new Error("Invalid status");
}
This defines exactly what the application accepts.
Anything outside that set is rejected.
That is often safer and simpler than trying to maintain a long list of suspicious values.
Validate data types too
Input validation is not only about strings.
Applications should also check that values have the expected type and range.
Imagine an API endpoint that accepts the number of projects to display:
const khg5293ProjectLimit = Number(request.query.limit);
if (
!Number.isInteger(khg5293ProjectLimit) ||
khg5293ProjectLimit < 1 ||
khg5293ProjectLimit > 100
) {
throw new Error("Invalid project limit");
}
Now the server knows that the value must be an integer between 1 and 100.
A client cannot simply send:
limit=999999999
and expect the server to accept it.
Validation is only one layer
Server side validation does not replace other security controls.
Applications still need things such as:
Parameterized database queries
Output encoding
Authentication
Authorization
Secure file handling
Rate limiting
Appropriate error handling
For example, imagine a database lookup for a khg5293 project.
Instead of constructing a SQL query manually, the application should use a parameterized query:
const khg5293ProjectName = request.body.projectName;
db.query(
"SELECT * FROM projects WHERE name = ?",
[khg5293ProjectName]
);
Input validation is useful here, but parameterized queries are still the proper defense against SQL injection.
Security controls work best in layers.
A simple example
A basic server side validation flow might look like this:
function validateKhg5293Project(project) {
if (typeof project.name !== "string") {
throw new Error("Project name must be a string");
}
if (project.name.length < 1 || project.name.length > 50) {
throw new Error("Invalid project name length");
}
const khg5293AllowedLanguages = [
"JavaScript",
"TypeScript",
"Python"
];
if (!khg5293AllowedLanguages.includes(project.language)) {
throw new Error("Unsupported language");
}
return true;
}
const khg5293Project = {
name: "khg5293-json-formatter",
language: "JavaScript"
};
validateKhg5293Project(khg5293Project);
The client may perform similar checks before sending the request.
The server should still perform them again.
The simple rule
A useful rule is:
Never trust the client.
Client side validation improves usability.
Server side validation protects the application.
The browser can help users submit the right data, but the server has to decide whether that data is actually acceptable.
Keeping that distinction clear is one of the fundamentals of secure web development.
This is another technical note from khg5293 covering practical programming and application security concepts.
TAGS:
webdev
security
javascript
cybersecurity
Read original: https://dev.to/khg5293/client-side-validation-is-not-a-security-boundary-4fhl
← Previous
My automation read another site's page: the active tab belongs to the browser, not to your session
Next →
Domain Watchlists Aren't Drop-Catchers (and WHOIS Refresh Isn't Monitoring)
Related
🗺️ The Complete Limn Engine Learning Roadmap: From Zero to Game Developer
Frontend
0
Dev.to (EN Zone)
Understanding Key Web APIs: Fetch API, WebSockets, and Service Workers
Frontend
0
Dev.to (EN Zone)
I Built a Real-Time Train Tracker for Pakistan Railways
Frontend
0
Dev.to (EN Zone)
I got tired of re-recording broken tests, so I built my own testing tool
Frontend
0
Dev.to (EN Zone)
Comments0
No comments yet — be the first