A simple question: I have a Model-View-Controller setup, with Models accessing a SQL database. In which part should I sanitize/check for malformed incoming data?
I would say it is the responsibility of the controller to validate the input and make sure the data is valid before passing on the data to the model.
If invalid data is found, the controller should redirect back to the view and display the relevant error messages.
Having validation in the view only could be bypassed if the user doesn't have javascript enabled or posts to the url directly, however some validation in the view is better from a user experience point of view since the user does not need to wait for a return from the server in a web application.
I tend to:
Put syntactic validation in the view ("this field is numeric", "that field is a date"). This is often very easy or even implicit in your choice of view design (eg: using a date picker for date fields).
Put semantic violation in a separate validator class ("this date field has to be after that date field", "this can be null if that is greater than zero") and call the validator from the controller, passing errors back to the view for display.
(for my own pseudo-correct definitions of syntax and semantics...)
I'd say the Controller should sanitize input.
The model should at most decline to store invalid data.
It's important to keep error handling as low as possible in the stack, but supplemental in other parts. If you keep the sanitizing in the controller, you could break the model by swapping out the controller with a looser one, but you can never break the model by being strict higher up in the stack. Keep the sanitizing low in the stack for consistency, and high in the stack for user feedback.
The model will validate business logic rules, i.e. password length requirements, if a user is allowed to perform an action or not.
The model should obviously also make sure interaction with the database is done in a safe way so that SQL Injection is not possible.
The controller should handle relaying business logic errors back to the view, but can also do some basic sanity checks, i.e. a field is not empty.
I would say output sanitization should also go in the Controller before being passed to the View.
I use two levels of checking. My controller will check what is supposed to be a date is a date, an int an int and so forth. Basically ensuring they can be used to set the values on my objects.
Then my domain has validation for things such as valid values and other business rules. These are ALWAYS checked before saving or interacting with an edited object.
All errors from either level get returned to the user so they can take remedial action as necessary.