Web Application Security Guide/(Un)trusted input

(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.