Last updated December 4, 2016. Created on May 10, 2013.
Edited by senzaesclusivagreggleskbos2hmkeeganhr. You can edit this page, too.

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'] = array(
  '^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'] = array(
'^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.

ZNCologne’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$',

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

ZNCologne’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

ZNCologne’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

ZNCologne’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..

ZNCologne’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.

ZNCologne’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.

ZNCologne’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

ZNCologne’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

ZNCologne’s picture

hi..
your WWW is missing
should be like this

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

ZNCologne’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$',
);

ZNCologne’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

ZNCologne’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
ZNCologne’s picture

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

mmjvb’s pictureNEW

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

Margutis’s pictureNEW

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$',
);



来自  https://www.drupal.org/node/1992030