Validating the data that is input to your script once when it is first input ought to be enough to ensure the security of that data. Escaping only those fields that are allowed to contain characters that might be mistaken for part of the surrounding code also ought to be sufficient. The problem with that approach though is that if you make just one mistake in that code that results in the code containing a security hole then there is nothing else in place to prevent that security hole from being exploited.
A much safer approach is to not assume that the data that was valid at the time you ran the validation is necessarily valid at subsequent points in the processing. Apart from the possibility of the validation not working quite the way it is supposed to there are other possibilities. There may be another way that the particular data can be entered into the system where a different validation is applied so that depending on which way the data was entered there may be values that would have failed one validation that would pass the other. There is also the (slight) possibility of someone breaking into your system and being able to corrupt the data so that what was valid when it was first entered is no longer valid.
The solution to these possibilities and an acion that reduces the risk of a security hole managing to corrupt your entire system is to use defense in depth. What this means is that you include further processing that confirms that the data being processed will not be able to do any harm even if it has been corrupted.
It does no harm to escape all of the data that you are incorporating into HTML or even calling the strip_tags() function on those fields simply to be certain that the data cannot insert HTML. That way if a security hole in your input validation is dutilised to inject code into the field then the content of your database may be invalid but that garbage code is still harmless when you output it in HTML.
PHP includes not only a number of validation filters that make it easier to validate certain types of input data but it also contains a similar set of sanitising filters. The difference between these two is that the validation filters are used in if statements to test if the data passes validation while the sanitising filters simply strip out any invalid characters from the data. If you validate the data before writing it to a database or file then you know it is valid at the time it is first written. When you read back that data then sanitising it will have no effect provided that the data is still the same as it was when it was first input. If the data has been corrupted since it was input and would now no longer pass validation then sanitising it when you read it back in for subsequent processing will at least remove any invalid characters and thus limit the harm that the corrupted data can do.
After it has been validated your data should remain valid but by not assuming that it remains valid. We don't really want to validate it again in the subsequent processing since at that time there isn't really any opportunity for the data to be corrected but by running the data through processing that will strip out any invalid characters we can reduce or eliminate the harm that can be caused if anything does get past our initial validation.
Defense in depth means that we don't rely on one piece of code to prevent security breaches but instead we add further code at other places in our script to try to reduce the risk that a security hole in one piece of code will compromise the security of the entire application.
This article written by Stephen Chapman, Felgall Pty Ltd.