domains / security / pallets/flask
Sanitize untrusted client input
Treat all client-supplied data—HTTP headers (e.g. `Host`), query/path parameters, form data—as untrusted, and enforce strict validation or escaping before using it in security-sensitive contexts such as generating URLs or rendering HTML. Mitigations must be mandatory, correctly scoped, and precisely described rather than presented as optional suggestions.
Treat all client-supplied data—HTTP headers (e.g. Host), query/path parameters, form data—as untrusted, and enforce strict validation or escaping before using it in security-sensitive contexts such as generating URLs or rendering HTML. Mitigations must be mandatory, correctly scoped, and precisely described rather than presented as optional suggestions.
For host-derived URLs, Flask always builds external URLs (url_for(..., _external=True)) from the request’s Host header. Don’t describe this as a “default” behavior—state clearly that it always happens. To protect against Host header injection, require the global TRUSTED_HOSTS configuration (not the per-request Request.trusted_hosts attribute, which only overrides the global setting for that request) and document it as something you must configure, not something to “consider”:
app.config["TRUSTED_HOSTS"] = ["example.com"]
For user-controlled values rendered in responses, always escape them to prevent XSS, and keep example code self-contained (including necessary imports):
from markupsafe import escape
@app.route('/user/<username>')
def profile(username):
return '{}\'s profile'.format(escape(username))
When writing security documentation or code, be explicit and directive: state exactly when input is untrusted, which configuration or escaping mechanism actually mitigates the risk, and require its use rather than merely recommending it.</description>