Whitelist technical domains to limit admin roles to access and interact only on those.
It is a common security measure to allow admin operations only on a technical (sub)domain (admin.example.com) that is different from the URL of the publically available site (example.com). It uses the same database as it points to the same Drupal docroot folder but mitigates XSS and cross-site request forgery vulnerabilities, the most commonly needed protection.
Furthermore, a technical domain can be made more secure than the production domain with an additional Htaccess password protection (aka shielding). Even if one could get hold of a Drupal admin user's credentials, on the production URL those would not work in any case and even on the technical admin domain only in combination with an Htaccess password. If credentials shared over an insecure channel are intercepted or found written on a sticky note (a classic user mistake), this module is an extra hurdle to keep out the malicious users that try to use them.
In case an Htaccess password is set up, the browser is caching the extra password, so the admin user will not be asked to re-enter these extra credentials on each visit. Only if they change to another computer or clear their browser cache. They still use their Drupal credentials as normal on each login.
This module:
- adds a "permission" Block access on non-technical domain. For the above-described use case, any role having permission for an operation you do not want to be performed outside of the technical domain should be blocked.
- provides a configurable whitelist of technical domains to limit admin roles to interact only on those.
There are other advantages using a technical domain for admin operations, for example, it is easier to exclude admin visits from the web analytics service.
How it works
Whenever a login from an admin role is detected on a non-technical domain through hook_user_login() that runs right after log in, it forces log out of the current user with the core function user_logout | user.module | Drupal API. This will destroy the current session, and reset $user to the anonymous user (uid=0).
Other than normally resulting in an Access denied page, no extra message is given to not give away info about the existence of a technical domain to a malicious user. Internally you should provide clear instructions to webmasters and content managers that they should always access through a technical domain.
FAQs
Why not having a permission Allow instead of Block?
One would expect the permission to be Allow access on non-technical domain instead of Block access on non-technical domain but doing it this way a user having multiple roles from which one with admin permissions would be blocked as expected. Furthermore, it avoids that the Administrator role can opt-out, having all permissions selected by default and greyed out (not editable).
How to set up the technical admin domain?
The technical domain is actually the same website as the production domain. As an admin, all your changes will be on the production website, even if you do all operations in the technical domain. The only thing to do is to have your virtual host file pointing to the same Drupal document root.
Additionally, you should limit access to that domain. Most common is to set up Htaccess password protection (aka shielding) for the technical domain.
How to harden the security even more?
Get even a higher level of security by defining the whitelisted domains in the settings.php file instead of using the common configuration. This gets priority as it is a higher-level method (needs commit rights) and would disallow defining technical domains on the regular settings page, in that case being disabled for editing but still showing the detected values. This might be preferred as it disallows users with an admin role to change the defined technical domain to the public one to circumvent the system.
Add for example the following to the settings.php file or a custom module (comma-separated, asterisk wildcards (*) are allowed):
$config['limit_domain_access_by_role.settings']['technical_domains'] = '*local*,*.dev,admin.example.com';
Not working on my local machine?
The configurable whitelist of technical domains does by default include *local* and *.dev to allow access on a local development environment. It accepts wildcards, so *local* would allow access on e.g. example.localhost. Make sure to leave the defaults in place and add your own technical domain to the bottom of the list. The whitelist is only configurable for roles with the "administer site configuration" permission, if not defined already in the settings.php (recommended, see above).
I am locked out. Now what?
The best is to define the whitelisted domains in the settings.php file, as described above. If you have access to that (commit rights), you will never be locked out. You can define the used technical domain directly there. Furthermore, it is the highest level of security offered by the module. If you insist on using the regular settings instead, allowing admin users to change the used technical domains from the UI, then read on.
Important when enabling the module, the superuser will also get blocked when not on a technical domain (UID #1 having the administrator role is getting all permissions by default). That means that when enabling the module the correct technical domain should immediately be added in the whitelist to avoid being locked out. So, to perform that task, make sure you are logged in as an administrator user before enabling the module. Also, export the configuration as usual and commit the modified configuration files.
It can also be set through the terminal with drush (in case you are locked out):
drush cedit limit_domain_access_by_role.settings
Then change:
technical_domains: "*local*,*.dev,[add-tech-domain-here]"
Related: Set nano as a default editor over Vim - Super User (restart needed). Alternatively use Drupal Console that has an editor option:
drupal ced limit_domain_access_by_role.settings nano
Note that drush cset can not be used due to a Drush bug passing a literal string into drush config-set - Drupal Answers. Drupal Console (config:override) suffers a similar issue.
After enabling the module and setting the technical domain, you might want to "throw out" all currently logged-in admin users to force them to log in on the technical domain. You can do this by just saving the module's settings form with the option selected ' Terminate all open sessions on form save'. It only "throws out" users, apart from yourself, that have 'block access on non-technical domain' applied to them (admin users). It will not affect others.
Alternatively, but applying for all users, you can use:
drush sqlq "TRUNCATE sessions"
Make sure you communicate in advance with all users with an admin role that they should use the technical domain.
How to change the execution order?
If you have other authentication modules using hook_user_login() and you want to control the execution order:
Changing the Order of Hooks in Drupal
Project information
- Project categories: Security, Access control
7 sites report using this module
- Created by lolandese on , updated
Stable releases for this project are covered by the security advisory policy.
There are currently no supported stable releases.
