Data input validation always was quite an internal struggle to me.
On the verge of adding a real security framework and code to our legacy application rewrite project (which so far pretty much keeps the card-castle-strong legacy security code and data validation), I'm wondering again about how much should I validate, where, etc.
Over my 5 years as professional Java developer, I created and refined my personal rules for data input validation and security measures. As I like to improve my methods, I'd like some hear some ideas from you guys. General rules and procedures are fine, and Java-specific ones too.
Summarized, these are my guidelines (exposed on a 3-tier web application style), with brief explanations:
1st tier client side (browser): minimal validation, only invariable rules (mandatory email field, must select one item, and the like); use of additional validation like "between 6 and 20 characters" less frequent, as this increases maintenance work on changes (may be added once the business code is stable);
1st tier server side (web communication handling, "controllers"): I don't have a rule for this one, but I believe only data manipulation and assembly/parsing errors should be handled here (birthday field is not a valid date); adding further validation here easily makes it a really boring process;
2nd tier (business layer): rock solid validation, no less; input data format, ranges, values, internal state checking if method cannot be called anytime, user roles/permissions, and so on; use as little user input data as possible, retrieve it again from database if needed; if we consider retrieved database data as input too, I would only validate it if some specific data is known to be unreliable or corrupted enough on the DB - strong typing does most of the job here, IMHO;
3rd tier (data layer/DAL/DAO): never believed much validation is needed here, as only the business layer is supposed to access the data (validate maybe on some case like "param2 must not be null if param1 is true"); notice however, that when I mean "here" I mean "code that access the database" or "SQL-executing methods", the database itself is completely the opposite;
the database (data model): needs to be as well thought, strong and self-enforcing as to avoid incorrect and corrupt data on the DB as much as possible, with good primary keys, foreign keys, constraints, data type/length/size/precision and so on - I'm leaving triggers out of this, as they have their own private discussion.
I know early data validation is nice and performance-wise, but repeated data validation is a boring process, and I admit that data validation itself is quite annoying. That's why so many coders skip it or do it halfway. Also, every duplicated validation is a possible bug if they are not synchronized all the times. Those are the main reasons that I'm nowadays preferring let most of the validations up to the business layer, at the expense of time, bandwidth and CPU, exceptions handled on a case-by-case basis.
So, what do you think about this? Opposite opinions? Do you have other procedures? A reference to such topic? Any contribution is valid.
Note: if you are thinking the Java way of doing things, our app is Spring based with Spring MVC and MyBatis (performance and bad database model rule out ORM solutions); I plan to add Spring Security as our security provider plus JSR 303 (Hibernate Validator?)
Thanks!
Edit: some extra clarification on the 3rd layer.