Web Application Security Guide/(Un)trusted input
All user input is to be considered untrusted. Seemingly “trusted/safe” input, like some $_SERVER variables in PHP, can be easily manipulated by attackers.
To prevent this type of attack
- Thoroughly filter/escape any untrusted content
- If the allowed character set for certain input fields is limited, check that the input is valid before using it
- If in doubt about a certain kind of data (e.g. server variable), treat it as untrusted
- If you are sure, but there is no real need to treat it as trusted, treat it as untrusted
- The request URL (e.g. in environment variables) is untrusted
- Data coming from HTTP headers is untrusted
- Referer
- X-Forwarded-For
- Cookies
- Server name (!)
- All POST and GET data is untrusted
- includes non-user-modifiable input fields like select
- All content validation is to be done server side
Rationale
Escaping or filtering “trusted” input that should not contain any characters that require escaping will only give you a negligible performance penalty, but you will be on the safe side if the input turns out to be untrusted.
Validating input data using a character whitelist can avoid attacks using unexpected characters (null bytes, UTF-8, control characters used as delimiters in internal representations etc.). Ensure your validation is not too strict, for example you will need to allow both UTF-8 and characters like ' in person name fields.
An attacker is not constrained by the constraints a browser puts on him. Just because an input field is specified with maxlength=20
does not mean that an attacker cannot craft a request with 200 KB of data. The same goes for any JavaScript based constraints.