Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOC Document warning for allowed hosts #692

Merged

Conversation

GuySartorelli
Copy link
Member

Also some reworking on the related configuration to improve clarity, make sure everything is fully documented, and updates to the reverse proxy docs which was just wrong in some cases.

Issue

@GuySartorelli GuySartorelli force-pushed the pulls/5/warn-allowed-hosts branch from f0c5954 to 8a61f4b Compare February 13, 2025 20:20
Comment on lines 36 to 54
### Logged warning if allowed hosts have not been configured {#allowed-hosts-warning}

If [`Director.alternate_base_url`](api:SilverStripe\Control\Director->alternate_base_url) is not set, the "host" header is used by Silverstripe CMS to determine what the host name is for your project. This is useful when creating absolute URLs, e.g. for use in emails.

Notably this is used in [`Director::host()`](api:SilverStripe\Control\Director::host()), which in turn is called by many methods including [`Director::hostName()`](api:SilverStripe\Control\Director::hostName()), [`Director::protocolAndHost()`](api:SilverStripe\Control\Director::protocolAndHost()), [`Director::is_site_url()`](api:SilverStripe\Control\Director::is_site_url()), and [`Director::absoluteURL()`](api:SilverStripe\Control\Director::absoluteURL()).

Ideally your hosting will reject invalid host headers. For example Apache allows you to define valid hosts as part of the virtual host configuration, and a Web Application Firewall (WAF) can also be configured to validate the host header. However if your hosting is set to allow *any* host header, your project might be vulnerable to host header injection attacks.

You should configure Silverstripe CMS to validate the host header, which is an extra layer of protection against this type of attack. While you should have appropriate validation at a hosting level, it is best practice to also configure this in your project.

This configuration has existed since 2016, but we've been alerted that many projects still have not configured their hosting nor their project to adequately validate host headers. To help prompt developers, we've added a warning which will be logged if the configuration is not set.

If you haven't configured your allowed hosts, then the new warning will be logged once for each request.

You can learn more about the relevant configuration in the [secure coding](/developer_guides/security/secure_coding/#request-hostname-forgery) documentation.

Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
### Logged warning if allowed hosts have not been configured {#allowed-hosts-warning}
If [`Director.alternate_base_url`](api:SilverStripe\Control\Director->alternate_base_url) is not set, the "host" header is used by Silverstripe CMS to determine what the host name is for your project. This is useful when creating absolute URLs, e.g. for use in emails.
Notably this is used in [`Director::host()`](api:SilverStripe\Control\Director::host()), which in turn is called by many methods including [`Director::hostName()`](api:SilverStripe\Control\Director::hostName()), [`Director::protocolAndHost()`](api:SilverStripe\Control\Director::protocolAndHost()), [`Director::is_site_url()`](api:SilverStripe\Control\Director::is_site_url()), and [`Director::absoluteURL()`](api:SilverStripe\Control\Director::absoluteURL()).
Ideally your hosting will reject invalid host headers. For example Apache allows you to define valid hosts as part of the virtual host configuration, and a Web Application Firewall (WAF) can also be configured to validate the host header. However if your hosting is set to allow *any* host header, your project might be vulnerable to host header injection attacks.
You should configure Silverstripe CMS to validate the host header, which is an extra layer of protection against this type of attack. While you should have appropriate validation at a hosting level, it is best practice to also configure this in your project.
This configuration has existed since 2016, but we've been alerted that many projects still have not configured their hosting nor their project to adequately validate host headers. To help prompt developers, we've added a warning which will be logged if the configuration is not set.
If you haven't configured your allowed hosts, then the new warning will be logged once for each request.
You can learn more about the relevant configuration in the [secure coding](/developer_guides/security/secure_coding/#request-hostname-forgery) documentation.
### Logged warning if allowed hosts have not been configured {#allowed-hosts-warning}
If your site does not have one of the following configured, then a warning will now be logged on every request:
- `SS_ALLOWED_HOSTS` environment variable
- [`AllowedHostsMiddleware.AllowedHosts`](api:SilverStripe\Control\Middleware\AllowedHostsMiddleware->AllowedHosts) property
- [`Director.alternate_base_url`](api:SilverStripe\Control\Director->alternate_base_url) property
If one of those is not set, then the "host" HTTP request header is used by Silverstripe CMS to determine what the host name is for your project. This is used when creating absolute URLs, e.g. for use in emails that link back to the site.
Ideally your hosting will reject invalid host headers. For example Apache allows you to define valid hosts as part of the virtual host configuration, and a Web Application Firewall (WAF) can also be configured to validate the host header. However if your hosting is set to allow *any* host header, your project might be vulnerable to host header injection attacks.
You should configure Silverstripe CMS to validate the host header, which is an extra layer of protection against this type of attack. While you should have appropriate validation at a hosting level, it is best practice to also configure this in your project.
This configuration has existed since 2016, but we've been alerted that many projects still have not configured their hosting nor their project to adequately validate host headers. To help prompt developers, we've added a warning which will be logged if the configuration is not set.
You can learn more about the relevant configuration in the [secure coding](/developer_guides/security/secure_coding/#request-hostname-forgery) documentation.

Copy link
Member

Choose a reason for hiding this comment

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

The most important info should be up the top, in this case it's saying that if you are missing some configuration then you'll get logged warnings

Copy link
Member Author

@GuySartorelli GuySartorelli Feb 13, 2025

Choose a reason for hiding this comment

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

[`Director.alternate_base_url`](api:SilverStripe\Control\Director->alternate_base_url) property

Not relevant here. The warning is still logged if you have that set. All that changes is whether the host header is used by Director::host() or not.

If one of those is not set, then the "host" HTTP request header is used by Silverstripe CMS to determine what the host name is for your project.

Not quite. The host header will still be used if you have allowed hosts set too - that's kinda the whole point.

I've moved that one bit to the top - the rest I've left the same as it already is. If you want to change a specific paragraph, please suggest changes to each paragraph individually so it's easy to comment and respond to. Changing all of it in a single diff is really hard to respond to - let alone see what specific changes you're suggesting.

Copy link
Member

Choose a reason for hiding this comment

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

Not relevant here. The warning is still logged if you have that set.

OK, so if that makes it so that host header is not used by Director::host(), then won't that mean that host header injection isn't possible because the host headers aren't used? i.e. links in an email back to the site will just use alternate_base_url ... or in that instance do they still use the host header?

Copy link
Member Author

Choose a reason for hiding this comment

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

In theory they will use the alternate base URL instead of the host header when using Director::host() - which is an important caveat.

If the host header is accessed anywhere else, an injection attack could still be possible, so I think we should continue to warn about not having allowed hosts config set even if alternate_base_url is set.

Copy link
Member

Choose a reason for hiding this comment

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

I honestly think there's too much nuance in Director.alternate_base_url / Director::host() and it does more harm then good mentioning them. It's very distracting, particularly since they're at the top.

The key thing that people need to know is that you host header injection may be possible is some scenarios, therefore you need to set either an env variable or some yml configure in your application to limit allowed hosts

Copy link
Member Author

Choose a reason for hiding this comment

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

I've removed the note about alternate_base_url

@GuySartorelli GuySartorelli force-pushed the pulls/5/warn-allowed-hosts branch from 8a61f4b to 5dfc55d Compare February 13, 2025 21:39
Comment on lines 43 to 45
If [`Director.alternate_base_url`](api:SilverStripe\Control\Director->alternate_base_url) is not set, the "host" header is used by Silverstripe CMS to determine what the host name is for your project. This is useful when creating absolute URLs, e.g. for use in emails.

Notably this is used in [`Director::host()`](api:SilverStripe\Control\Director::host()), which in turn is called by many methods including [`Director::hostName()`](api:SilverStripe\Control\Director::hostName()), [`Director::protocolAndHost()`](api:SilverStripe\Control\Director::protocolAndHost()), [`Director::is_site_url()`](api:SilverStripe\Control\Director::is_site_url()), and [`Director::absoluteURL()`](api:SilverStripe\Control\Director::absoluteURL()).
Copy link
Member

Choose a reason for hiding this comment

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

Suggested change
If [`Director.alternate_base_url`](api:SilverStripe\Control\Director->alternate_base_url) is not set, the "host" header is used by Silverstripe CMS to determine what the host name is for your project. This is useful when creating absolute URLs, e.g. for use in emails.
Notably this is used in [`Director::host()`](api:SilverStripe\Control\Director::host()), which in turn is called by many methods including [`Director::hostName()`](api:SilverStripe\Control\Director::hostName()), [`Director::protocolAndHost()`](api:SilverStripe\Control\Director::protocolAndHost()), [`Director::is_site_url()`](api:SilverStripe\Control\Director::is_site_url()), and [`Director::absoluteURL()`](api:SilverStripe\Control\Director::absoluteURL()).
If [`Director.alternate_base_url`](api:SilverStripe\Control\Director->alternate_base_url) is set then it is often used instead instead of the "host" HTTP request header for determining the URL of the website. However there may be some scenarios where the host header is still used, so having `alternate_base_url` configured by itself will not prevent a warning be logged if allowed hosts are not configured.

Maybe this?

Copy link
Member Author

@GuySartorelli GuySartorelli Feb 13, 2025

Choose a reason for hiding this comment

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

Based on #692 (comment) it sounds like referencing alternate_base_url was confusing, so I've removed that and left the rest.

I.e. it doesn't matter that sometimes some methods won't use the host header if alternate_base_url is set - but it is useful to know some of the common methods that do usually use the host header.

@GuySartorelli GuySartorelli force-pushed the pulls/5/warn-allowed-hosts branch from 5dfc55d to a1b29ba Compare February 13, 2025 23:51
@emteknetnz emteknetnz merged commit bb72cd7 into silverstripe:5 Feb 16, 2025
3 checks passed
@emteknetnz emteknetnz deleted the pulls/5/warn-allowed-hosts branch February 16, 2025 21:21
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants