Last updated 7 April 2017. Created on 10 May 2013.
Edited by GoZ, senzaesclusiva, greggles, kbos2hm. Log in to edit this page.

Drupal 7 added a new feature into core that is not user facing directly, but is sometimes called poor man's cron. The feature triggers the periodic tasks of a Drupal site like emptying log files, sending e-mails, and clearing out caches. This feature, when combined with dynamic detection of the "base url" (added in Drupal 4.7), can lead to some screwy situations. This article is a description of some of those screwy situations that occur with either module or both of them and what you can do to prevent them. The comments below assume some default configurations - I'll discuss at the end how to break away from those defaults to prevent these problems.

Scenario 1: Getting/sending user emails that appear to be for another domain

This behavior is pretty easy to replicate:

  1. Point a new domain at the IP of an existing site - let's call the existing site http://www.example.com and the new name pointed at that IP is http://other-site.example.org
  2. Visit the url: http://other-site.example.org/user/password
  3. Submit a username that is likely to be used on the site

The result is that in step 2 the $base_url detection thinks that your site is http://other-site.example.org and all the tokens for the e-mail like [user:one-time-login-url]that contain links to your site will be changed to use http://other-site.example.org as the base url. The user who receives this email will see their username and e-mail for example.com are now somehow in use on http://other-site.example.org which is usually just confusing. Two bad scenarios could come from this, though:

  • In a worst-case scenario could lead to them click on the password reset link which the evil site could then use to login to the site as that user
  • They might enter their username/password into http://other-site.example.org - a so-called social engineering attack - which could then be used on the main site

Scenario 2: Cache entries containing the wrong domain

A similar problem can occur when a user uses the wrong domain to make a request and that happens to be the request that primes a cache entry with dynamic, fully qualified domains in it. Subsequent visits that retrieve information from that cache will get the wrong domain name. Drupal core's page cache uses the domain as part of the cache ID, preventing this problem, but other caching mechanisms may not be as robust against this problem.

Scenario 3: Notification mails containing the wrong domain

Yet another problem can occur on sites that use modules that send e-mails during cron runs. This scenario requires the poor-man's-cron with the dynamic base_url detection. If a user happens to trigger the poor man's cron when there are notifications in the queue by visiting the wrong domain name then notifications will be sent with that incorrect domain. Users will be very confused about why the mail they expect to receive coming from an e-mail address at example.com includes links to the http://other-site.example.org domain.

Solutions to confusing experiences with Drupal's dynamic base_url detection

There are at least four potential solutions to this problem, though not all are necessary to stop the problem from happening. You should pick and choose as appropriate for your environment.

  1. You can set a specific domain as your $base_url in sites/default/settings.php. While the dynamic detection can be a handy feature it can also cause problems. One way to stop that is just to set a permanent value.
  2. Use a specific sites/example.com/settings.php and let $base_url be detected dynamically - this has the implication of letting Drupal respond to all subdomains of example.com which may or may not be a benefit.
  3. Configure your webserver so that the default page served when an incoming request is something other than your default Drupal installation, such as an error page.
  4. Configure your webserver to redirect all requests that reach your server that are not for the appropriate domain to forward to the right domain name.

Trusted host security setting in Drupal 8

As of January 2015, Drupal 8 supports "trusted host patterns", where you can (and should) specify a set of regular expressions that the domains on incoming requests must match. Example configuration in settings.php would read:

$settings['trusted_host_patterns'] = [
  '^www\.example\.com$',
];

See the above change record for more details. Note that, if you're doing local development, you might get (temporarily) locked out of your site by the above configuration on its own. You should add a trusted host pattern for '^localhost$' in this case.

MAMP exception

About local development, MAMP (3.5.2) '^localhost$' setting give the error message "The provided host name is not valid for this server" and doesn't load the site. Found a solution changing it with site name without port number. In my test site "drupal8":

$settings['trusted_host_patterns'] = [
'^drupal8$',
];

made Trusted Host active.

Looking for support? Visit the Drupal.org forums, or join #drupal-support in IRC.

Comments

ZNCologne’s picture

Hello, first of all I had to explain, that I have rudimentary knowledge of english. I tried to translate this into german, but two sentences are not clear for me (I think because of my lacks):
1. "Submit a username that is likely to be populated." Do you mean, to try to find a popular username?
2. "Use a specific sites/example.com/settings.php and leave dynamic $base_url - this has the implication of letting Drupal respond to all subdomains of example.com which may or may not be a benefit." I couldn't understand wether "leave" in german means to skip something or to left something.

greggles’s picture

Good questions. I've tried to edit the document to make it clearer to understand because it wasn't that clear in English really.

To address your questions:
1. Yes, your understanding is correct. A popular username or one likely to exist for any reason (e.g. a site like drupal.org is likely to have an account named drupal and drupalfan but that is not a popular username anywhere else).
2. Leave it (do not hard-code a value) so it has the default behavior where it is dynamic.

--
CARD.com :)

ZNCologne’s picture

Thank's a lot.

kbos2hm’s picture

I have tried a few ways with setting this for a UK based site but just can not figure it.

$settings['trusted_host_patterns'] = array(
  '^www\.example\.com$',
);

So for the UK for example

$settings['trusted_host_patterns'] = array(
'^www\.example\.co\.uk$',
);

I have tried a few different ways but it always knacks the config i get 50 errors
If nothing else it would be useful for other continents as well.

triple5’s picture

From your question I guess you did not get the point of the trusted host patterns. Only if your site is reachable at www.example.co.uk it would work, but if you site would be for example http://oxfam.org.uk for example, then of course you need to set the trusted_host_pattern to '^www\.oxfam\.org\.uk$', and NOT to '^www\.example\.org\.uk$',

usama009’s picture

Hi sir
But when i put this in setting.php,
$settings['trusted_host_patterns'] = array(
'^www\.aklimos\.com\.au$',
);
It gives me that error i.e.
"The provided host name is not valid for this server"
and my domain name is http://aklimos.com.au
please help?

mmjvb’s picture

add line '^aklimos\.com\.au$',
and both would be allowed. Replace to only allow without www.

usama009’s picture

It work
Thank you...... :)

agostinho-pereira’s picture

After installation, this error occurred which says that Trusted host setting is not enabled. I see above your post;
here is your explanation;

$settings['trusted_host_patterns'] = array(
'^www\.example\.com$',
);

if I use localhost and want to change it, does it look like this for localhost?
$settings['localhost'] = array(
'^localhost\.maloco$',
);

Note: maloco is the folder that my drupal site is located.

Thanks

shylock’s picture

should just be like this:

$settings['trusted_host_patterns'] = array(
'^localhost$',
);

this works fine for me.

pinueve’s picture

+1, it works on localhost D8

jayly’s picture

If you just work locally.Just add this.

$settings['trusted_host_patterns'] = array(
'^localhost$',
);

If your OS is Ubuntu and you use docker containers.And this is the method of mine.
$docker ps
$docker exec -ti drupalContainerName bash
root@yourContainerID:/var/www/html# cd /sites/default/
vim settings.phpAnd if your DrupalContainer not exit vim,you should install it in your container.
apt updateapt install vimAnd check installation.vimAnd exit.\
Then open the file settings.php.
vim settings.php

$settings['trusted_host_patterns'] = array(
'^localhost$',
);

With the command :wq!save and exit.
And now refresh http://localhost/admin/reports/statusYou will find the Trusted Host Settings is Enabled.

sudishth’s picture

$settings['trusted_host_patterns'] = ['^example.com$', '^one.example.com$', '^two.example.com$', '^my.example.com$', '^thisexample.com$',];

mitkompm’s picture

On XAMPP 7.0.13 on Win 10 for me worked
$settings['trusted_host_patterns'] = array(
'^127.0.0.1$'
);

albigin’s picture

Hi,
I just added:
$settings['trusted_host_patterns'] = array(
'^www\.MYSITE\.com$',
);
at the end of the file settings.php but nothing happened. The settings.php I found was located at: /public_html/core/lib/Drupal/Core/Site/. Is there another file with the same name elsewhere?
Thx

deanflory’s picture

You should have created a copy of "default.settings.php" to be named "settings.php" at /public_html/sites/default before attempting to install Drupal.

Read the /public_html/core/INSTALL.txt file.

mmjvb’s picture

No, there is no need to create settings.php, done by the installation!
Only when that fails to INSTALL.txt tells you to do it manually!

b. Missing settings file.

Drupal will try to automatically create a settings.php configuration file,
which is normally in the directory sites/default (to avoid problems when
upgrading, Drupal is not packaged with this file). If auto-creation fails,
you will need to create this file yourself, using the file
sites/default/default.settings.php as a template.

For example, on a Unix/Linux command line, you can make a copy of the
default.settings.php file with the command:

cp sites/default/default.settings.php sites/default/settings.php

Next, grant write privileges to the file to everyone (including the web
server) with the command:

chmod a+w sites/default/settings.php

Be sure to set the permissions back after the installation is finished!
Sample command:

chmod go-w sites/default/settings.php

Obviously, your webserver is not configured properly when this happens! Suggest to fix that problem, rather than the symptoms.

shylock’s picture

Hi..
I'm on wamp test server and mine is at /Drupal/sites/default
there is no "Core" in my path.
Try at settings file @
/public_html/sites/default
... assuming your files are directly in public_html (as it looks like from your path)

put mine on line 727 just after where it tells you about this in that setting file @ lines 714 to 727
(might be slightly different for your? but that's where mine is..)

hope that helps you..

albigin’s picture

Hi shylock
thank you very much for your help. I found the settings.php file exactly where you said (/public_html/sites/default) but I wasn't able to edit it. It didn't help changing the file's properties from 444 (default) to 755 or 777. Any hint? Thanks again.

shylock’s picture

Think this may depend on what server structure you are on.. ie: windows server or Linux server and also if Apache has is set as your files Owner.. If you are only changing setting for Owner permissions wont work as you are not owner.. (or I believe is how it is)
So try setting to 665 this will give group read/write..

also don't know if you are going from desktop with filezilla ftp or similar, or going through your host control panel, may also make a difference, as I have had this with other forum software in past..

As I said I'm only testing Drupal on localhost on my computer so working ok there! and also I'm new to Drupal, so maybe someone with more knowledge of live Drupal can help you here.

albigin’s picture

Hi shylock
thank you so much for all the time you spent helping me out of my problem.
In fact I did change the settings.php's properties from my cPanel. Previously I was using CoreFTP.
Now everything runs smoothly.
Thanks again

netgenius.co.uk’s picture

I've written a utility which tests whether any given site appears to be vulnerable: Header Test - hope it might be useful. I'm pretty sure it works as intended, but no warranty!

It works by comparing the content obtained with and without setting an alternative host header. It does not require the target site to be running Drupal. As an example, if you try enter apache.org as the URL, it will report the site as vulnerable. Of course it's not actually vulnerable (I assume!), but could be if it were running Drupal (etc). Try entering drupal.org and it will report not vulnerable.

I'll put the source up on github on request.

gomorodion’s picture

I have tried all that you suggested I still do not have a solution can I have someone who can help me, I will send my cpanel user name and password I need assistance please

markagregory’s picture

My Drupal 8 redirects from www.mycompany.com.au to mycompany.com.au
so I put into the file and it stopped my site from working. Please let me know how to fix.

@code
$settings['trusted_host_patterns'] = array(
'^mycompany\.com\.au$',
);
@endcode

shylock’s picture

hi..
your WWW is missing
should be like this

$settings['trusted_host_patterns'] = array(
'^www\.mycompany\.com\.au$',
);

markagregory’s picture

Tried this and it did not work. Tried every combination with and without www and also with both options.

pinueve’s picture

these are my settings, is working on main domain and all subdomains, some subdomains are subdomain.mysite.com, others are mysite.com/subdomain, i have:

$settings['trusted_host_patterns'] = array(
'^mysite\.com$',
);

markagregory’s picture

thank you pinueve, I've seen other people report problems with .com.au and .co.uk

It appears to be ok for .com and .org

MirnaFalkner’s picture

I have tried everything and I still have the "Failed to get available update data" error for : DRUPAL CORE UPDATE STATUS & MODULE AND THEME UPDATE STATUS *uugh*

===WHAT I ADDED===
$settings['trusted_host_patterns'] = array(
'^hessociety\.org$',
'^.+\.hessociety\.org$',
'^www\.hessociety\.org$',
);

===NO DICE===
Any ideas?

BEGRAFX’s picture

I added the suggested code

$settings['trusted_host_patterns'] = array(
  '^www\.example\.com$',
);

into my Drupal 8 SETTINGS.PHP file, modifying it so it reads

$settings['trusted_host_patterns'] = array(
  '^www\.MYDOMAIN\.com$',
);

and when I refresh, I get,

Enabled
The trusted_host_patterns setting is set to allow ^www\.MYDOMAIN\.com$

It says it is working, but is it correct with all of the ^ and \ in there, if my site is www.MYDOMAIN.COM ?

dinesh_saini’s picture

yeah they are correct these are wild cards to provide exact mean to your setting:
for reference these means:

  • ^ : starts with
  • $ : ends with
BEGRAFX’s picture

I'm familiar with *.* but the others were new to me.

mmjvb’s picture

Suggest to have a look at PERL regular expressions, that is the pattern you have to provide.

Margutis’s picture

Hello
I have records in a way I act and localhost www:

$settings['trusted_host_patterns'] = array(
'^eduardo\.lt$',
'^.+\.eduardo\.lt$',
'^192.168.1.64$',
'^.+\.192.168.1.64$',
);

Mistah7’s picture

$settings['trusted_host_patterns'] = array(
'^example.dd$',
);

Works for me running a local site under Acquia Dev Desktop

deanflory’s picture

I've tried all sorts of variations and all of them make my D8 site go back to step 1 of installation, even after the site has already been installed. Is a clean wipe of the site required to reinstall just to set up this trusted patterns setting? Seems odd I wasn't able to get anything to work that didn't make my subdomain site need a reinstall.

I tried these variations individually (not all at once):

'^subdomainname\.domainname\.com$', <------this should be it, but requires a reinstall, same as the rest
'^www\.subdomainname\.domainname\.com$',
'^www\.domainname\.com$',
'^domainname\.com$',

Is this something that must be set before initial installation and cannot be changed? What happens if you want to change your domain name?

Mistah7’s picture

OK, on my own PC running under Acquia I use
$settings['trusted_host_patterns'] = array(
'^mydomain.dd$',
);
And Acquia is starting my site with http://mydomain.dd:8083/

Before fixing the Settings the site is running but with an error.
For me I just see it in the Status Report. Never had to reinstall!

deanflory’s picture

Sorry, I think I forgot that I'd uploaded a drupal core update and walked out of the room while it was uploading, then forgot to run it and something was off. My bust.