Skip to content

Conversation

ranveer9
Copy link

Description of the Change

This pull request adds a warning and best practices to the Web Security documentation regarding the use of url_for(..., _external=True) without setting SERVER_NAME or trusted_hosts. The new section explains the risk of host header injection and provides recommendations for safer configuration. This aims to improve developer awareness and help prevent potential security vulnerabilities, as discussed in #5718.

How it Addresses the Issue

  • Documents the risk of host header injection when generating external URLs.
  • Recommends setting SERVER_NAME and using trusted_hosts.
  • References the ProxyFix documentation for further guidance.

Relevant Issue
fixes #5718

@BrookeYangRui
Copy link

Thanks for working on this! I really appreciate how clearly the risks and recommendations were described.

This patch aligns well with the concerns I originally raised in issue #5718, glad to see it resolved!

---------------------------------------

When generating external URLs using :func:`url_for` with the ``_external=True`` argument,
Flask constructs the URL using the requeust's ``Host`` header by default. If your application
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It always uses the Host header, not only by default. That's why the config needs to be set.

**Best Practices:**

- Always set :data:`SERVER_NAME` in your configuration for production deployments.
- Consider using :data:`trusted_hosts` to restrict which hosts are accepted.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Request.trusted_hosts attribute on the individual request is not the correct place to start. Instead, use the global TRUSTED_HOSTS config. The attribute is used to modify that per-request.

**Best Practices:**

- Always set :data:`SERVER_NAME` in your configuration for production deployments.
- Consider using :data:`trusted_hosts` to restrict which hosts are accepted.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't "consider" using it, do use it, it's the only thing that actually protects from the issue.

critical when generating links for password resets or other sensitive actions that may be
sent to users.

.. warning::
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same statement as the previous paragraph, just restated in a warning block and bold now.


**Best Practices:**

- Always set :data:`SERVER_NAME` in your configuration for production deployments.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

SERVER_NAME is only used outside of requests, where the injection isn't relevant because there's not request or Host header anyway.


When generating external URLs using :func:`url_for` with the ``_external=True`` argument,
Flask constructs the URL using the requeust's ``Host`` header by default. If your application
does not explicitly set the :data:`SERVER_NAME` configuration or use :data:`trusted_hosts`,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Both of these are wrong, see further on.

@davidism
Copy link
Member

Heads up, all this information is wrong in various ways. Do not use AI, especially in regards to information about security.

@davidism davidism closed this Aug 18, 2025
@davidism
Copy link
Member

#5798

@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 2, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Recommend Warning and Safer Defaults for url_for(..., _external=True)
3 participants