DEV Community

Cover image for DO NOT trust your frontend validators

DO NOT trust your frontend validators

Thomas Hansen on August 18, 2022

Trusting frontend validation logic is like trusting a thief when he says he won't steal your wallet. Frontend validation is for convenience, to red...
Collapse
 
aarone4 profile image
Aaron Reese

Don't do your validation in the API/middleware either! To be truly robust all constraints should be built into the database and APIs will call stored procedures for writes and stored procedures or views for reads. Whatever you do don't use the Repository pattern or ORMs for connecting to the database. At the end of the day the database is your one source of truth.
You should however carry out validation and give feedback at front end and API levels as sending data you know to be bad across the network is expensive, but ultimately when using a REST protocol you are unable to know if your data interaction is still valid until you try and hit the data store.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Don't do your validation in the API/middleware either! To be truly robust all constraints should be built into the database and APIs will call stored procedures

I love the idea of moving validation logic as close to my data storage as possible. However, I also don't like putting business logic directly into my database. Yes, it's an oxymoron, I know :D

But this is a matter of taste I guess. I see your point here, especially when you've got multiple APIs accessing the same database - However, I suspect it's difficult to prevent users from using raw insert and update statements anyways, which of course would bypass the stored procedure inserts and updates ...

However, I think this is a matter of taste tbh with you, and you're definitely "closer" to my personal opinion than the guys simply adding frontend RegEx validators to the mix ... ;)

Collapse
 
jackmellis profile image
Jack

This is kinda my take too. I know the most robust way is to build validators and constraints directly into the database. But in reality, you should only need to validate data at its contact point.

Once I've validated the request payload, I (as the developer) should know that my data is "safe" and the only person who can screw it up is me ๐Ÿ˜…

Thread Thread
 
danjelo profile image
danjelo

I usually use constraints for at least PK/FK keys. I have gotten in serious mess a few times when there were none and data migrations and faulty logic put wrong ids as keys :)

As a side note, some ORM's such as EF Core have some nice code first functionality where validation in models are reflected in db as constraints.

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

As a side note, some ORM's such as EF Core have some nice code first functionality where validation in models are reflected in db as constraints

The problem I've got with EF is the disparity between the RDBMS and its "OOP circus". For instance, it's very tempting to just do myObject.Save(). This model of using a database increases bandwidth consumption (passing in whole object during updates for instance), it increases chatter towards DB, and it makes it harder to synchronise access, resulting in the need for "locking records" either logically, or physically somehow ...

Thread Thread
 
danjelo profile image
danjelo

Yes agree. Have to say I am not really a fan of ORM's in general for the OR impedance mismatch for one thing and its tendancies to generate hellish SQL :) Recently troubleshooted a slow EF Core query. Could not find the issue, likely some sort of "parameter sniffing" issue where the query plan was not used.

Collapse
 
joelbonetr profile image
JoelBonetR ๐Ÿฅ‡ • Edited
Phone numbers would be written like; "John Doe", or "foo@bar.com".

The dev throwing raw queries directly into the database:

๐Ÿ˜‚๐Ÿ˜‚๐Ÿ˜‚๐Ÿ˜‚

I agree 100% on the topic, front-end validations were always for convenience and there's not one but two reasons for adding validations in the client side as I already commented here:

Yes sure!
The same way you can disable JS in your browser, send a request using Postman directly to the endpoint or anything else.

Client code is loaded and running inside third party machines, hence you can't rely in frontend validations in any app. You'll need to re-validate the whole in backend anyway.

Validations in the frontend have 2 purposes:

  1. Give feedback to the user as soon as possible.
  2. Avoid requests to your server if the data that the user is about to send is not valid.

So yes, it's usable in a real product. If you do that and submit wrong data, the backend will throw an error about that and we should be good ๐Ÿ˜‚

Original post for reference.

So at the end, the benefits are better UX and saving costs and server load of the requests that will necessarily fail in the back-end validation.

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Word!! ^_^

However, what I find difficult is the fact that when using frontend validation, the code duplicates. As I update code, I've got two places I need to touch, possibly two different roles on my team too, to ensure they're both applying the correct changes. However, I do (mostly) agree on that frontend validation is necessary - Just don't TRUST it ... :)

Collapse
 
joelbonetr profile image
JoelBonetR ๐Ÿฅ‡

Yes sure! the same way that adding a column in the database (DATA) also demands some changes in the server (BACK-END) and in any client consuming this information (FRONT-END).

I hear a noise far away that says "Decouple your system building blooooocks!"
Wait I'm hearing something else "*slap* Dependencieeeees!"

Never mind, must have been the wind ๐Ÿ˜

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

Hahahahaha :D

Well, there is a difference, because one is duplicating logic, while the other is not really duplicating things, but simply allowing for field to move back and forth - But I see your point ^_^

Thread Thread
 
joelbonetr profile image
JoelBonetR ๐Ÿฅ‡

Well it's like in security at the end, you've different layers (data security, endpoint security, application security network Security...) and at the end you won't be trusting any ๐Ÿ˜… and develop a contingency plan "just in case" everything fails.

If we going strict, you don't need to add validations in frontend "as is", just in the backend; But if you do, you earn the benefits (lower cost by lowering the requests and happier customers) so it's not doing job for nothing ๐Ÿ˜

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

I agree, I guess I'm just spoiled with Hyperlambda HTTP requests never using more than 100ms before returning ... ;)

Collapse
 
christiangroeber profile image
Christian Grรถber

I desperately hope this isn't news to anyone that's been in code for more than a month

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Hahahaha - You wish ... ^_^

I've seen stuff like this in companies with thousands of employees, handling sensitive financial data, and the paradox is that these parts was the good parts of the codebase ... ;)

There's a reason why I'm writing about it ...

Collapse
 
christiangroeber profile image
Christian Grรถber

Yikes! I was seriously shocked when I saw the title of your post, guess I had every reason to be...

What do you do where you get such insight?

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO

I can't disclose actual employers for obvious reasons, but I've been an enterprise software developer for 25+ years, working for companies having software development as a secondary function. I've worked with FinTech, Health, Streaming, and everything really. The problem at such companies, at least those I've been working for, is that as long as the software works, it's good enough.

One project I was working for added a Guid to all HTTP requests as a query parameter. I couldn't understand why, before I started looking at its code. The Guid was the "authorisation mechanism", and was actually the primary key of the roles the user had to belong to in order to invoke some backend endpoint. This wasn't a small company either, it was a large company with 500+ employees, handling extremely sensitive data.

The above is just the tip of the iceberg. There's so much garbage code out there you wouldn't believe it if I told you.

Thread Thread
 
christiangroeber profile image
Christian Grรถber

"Never touch a running system" is often taken way too literally.

I'm working with a major insurance company and when I look at how terrible their internal communication is, it makes me question how they're able to make any money. But then they're one of the most profitable companies in their field. That made me question all other companies as well, and has really been an eye opener. And what you're telling me only enforces this new understanding I have of how businesses work, thank you.

Completely unrelated, how bad 1-10 would you rate it if a system were to, say, use the hashed password as an API key? It feels extremely dirty, but I can't see how it could be of any security risk.

Thread Thread
 
polterguy profile image
Thomas Hansen AINIRO.IO • Edited

Completely unrelated, how bad 1-10 would you rate it if a system were to, say, use the hashed password as an API key?

I wouldn't do it myself, but in theory, assuming you don't allow for authenticating somehow using the raw hash, it should not be any directly security risk. If I was to "fix" such a system, I'd double hash it, but it might be impossible due to integrations with other systems, where all systems needs to be updated, etc ...

Maybe creating "transition code" where the thing is double hashed, and both double hash and single hash is considered a "match", then log all single hashes, and slowly weed out single hashes over time. However, if this is your largest security issues, you're in a good place compared to some of the places I've been ... ;)

However, of course the correct way to create API keys is to create them dynamically, having them being completely unrelated of users and passwords, allowing admins to revoke them with time. That train has probably "left the station" for your current system ... :/

Edit - It depends upon how the password was hashed. I kind of assumed BlowFish and individual per record based salts. If this is not the case, the hash is almost as good as having raw access to password, due to rainbow dictionary brute force attacks ...

Collapse
 
elsyng profile image
Ellis

Agreed, plus... :)

Frontend & backend are both software and they are both apps, but they are two very different beasts, and should be judged and optimised differently:

  1. Validation, indeed ๐Ÿ‘
  2. Strict type definitions and safety, for which reason I think typescript is much overhyped and taken far too religiously. It's just a tool, i use parts of it.
Collapse
 
iway1 profile image
iway1

The solution is always to do both. Front end validation is a significant UX improvement, backend validation is the only way to ensure data integrity.

Collapse
 
mcsee profile image
Maxi Contieri

Objects should always valid

No matter if they come from the frontend. backedn api, imports etc
Business rules should be in the object itself

Collapse
 
aarone4 profile image
Aaron Reese

Only if you are really specific about your objects. E.g. a customer object can't have an email property as a string, it would need to be a type of email object because email needs special validation and is used also on suppliers, users, prospects etc. Before long you have a horrible DX where you are constantly writing order.dispatch.shipaddress.zipcode, order.dispatch.shipaddress.country

Collapse
 
polterguy profile image
Thomas Hansen AINIRO.IO

Assuming you believe in OO ofcโ€ฆ ๐Ÿ˜‰

Collapse
 
mcsee profile image
Maxi Contieri

I am guilty as charged