Closed (fixed)
Project:
Shield
Version:
8.x-1.x-dev
Component:
Code
Priority:
Normal
Category:
Bug report
Assigned:
Unassigned
Reporter:
Created:
23 Feb 2017 at 15:03 UTC
Updated:
20 May 2020 at 13:36 UTC
Jump to comment: Most recent, Most recent file

Comments
Comment #2
apugacescu commentedComment #3
apugacescu commentedComment #4
kevinquillen commentedWow, totally read my mind. Was just coming here to ask about this for this exact reason. I want to toggle functionality from settings.php for different environments.
Comment #5
apugacescu commentedJust found one possible issue with varnish cache when using IP whitelist. Varnish does not cache authorization requests as it should, but if an anonymous user requests a page and his/her IP is in whitelist a page without authorization is served, this page is saved in varnish and server for all anonymous users later.
Comment #6
spurlos commentedUpdated patch due to changes in install schema (commit f48a53f0d7a658abbdf4eb68f3877a6ee4d9227b)
Comment #7
philyThanks Spurlos, the patch #6 works
Comment #8
douggreen commentedThe whitelist functionality is fine. I don't like the idea of a configuration item to disable it. Shield is to protect a site. If shield is enabled, I expect the site to be protected. I might even add it to a core module info file to prevent it from being disabled. But if we introduce a configuration kill-switch, then this could easily be missed, if/when someone changes the configuration accidentally or maliciously.
Comment #9
apugacescu commenteddouggreen
The module can be disabled easily so the fact that "enable/disable" shield is a configuration in this feature request does not lower it's security feature. If you want to protect a site by specifying shield as hard dependency the same can be done using config override to force enable this config option.
In my case with multiple environments for the same site I need to have it enabled/disabled per environment, without this option the only way to have this functionality is write additional code in deployment process that will enable/disable the module after each deployment, using configuration it can be done easily using config override in settings.php
Enable shield option is also present in D7 version of the module (see https://cgit.drupalcode.org/shield/tree/shield.admin.inc#n17) so not having it here looks like a missed feature.
Comment #10
douggreen commentedIf I write a custom module and add shield as a dependency, it can't be disabled easily. With the enable/disable option though, it will be easy to disable and harder to prevent. I still don't like the feature. I think you can control it for dev/stage/prod simply in your settings.php (use a different one per environment) and set or don't set shield.user and shield.pass.
Comment #11
apugacescu commenteddouggreen First of all, there is a permission that limits users that have access to the admin page of the shield module so if you feel unsecure just keep this permission only for admins. As you noted shield will stop working if username/password is empty what is the difference for a "bad guy" between unchecking a checkbox and removing username to disable shield is it much easier? If you have a custom module that has shield dependency it does not make it harder to disable, it will just disable your module as well or half of the site if there are multiple dependencies.
Drupal is not about "like" or "don't like" and community should decide if this is a feature that is worth to be used or not.
Comment #12
manningpete commentedIP whitelisting for the shield module is a much needed feature for us, and was included in the D7 version of this module. We use config split to enable it on our dev and test environments (or under-development prod enviros) and we often to need to send folks to test features or enter content.
No matter how many times we explain the process, having to "login" to shield then "login" to Drupal is very confusing to virtually every single one of users (PhDs, MDs, and HS grads alike), so having the ability to whitelist our internal IPs makes my life easier. Plus 1 for this patch.
Comment #13
geek-merlinAs a maintainer i give a fullhearted placet to bringing back the enable setting.
Reviewed the code, looks totally straightforward.
Tested in #7, so RTBC.
(Will commit in my next console session.)
❤ Thanks everyone!! ❤
Comment #14
geek-merlinI think we need an update hook so that a protected site does not lose protection.
Comment #15
apugacescu commented@axel.rutz Good catch!
Updated the patch based on latest dev version, fixed some minor coding standards issues. Added hook update that sets shield_enable value to TRUE if username value is not empty because according to bypass cases empty username means shield is not active. Added warning info about reverse proxy caching not working as expected if whitelist option is used (see https://www.drupal.org/project/shield/issues/2855364#comment-12012601).
Comment #16
apugacescu commentedComment #17
amanire commentedDoes this whitelist only work for IP addresses? I'm looking at the use case of removing basic authentication for CDN requests so we can test it on the staging site.
Comment #18
apugacescu commentedamanire
Currently whitelist logic is implemented for end user's IP.
Comment #19
geek-merlinDo we really want getEditable (non-overridden config) here? I think it's a nontrivial question. What if an empty username is overridden with a nonempty one? What if a nonempty username is overridden with an empty one? In both cases i tend to take the overridden, effective value into account. Thoughts?
The rest is straightforrard and well-done!
I think if we settle this question, and someone does reasonable manual tests of the new functionalities and the update path, this can well go in!
Comment #20
RumyanaRuseva commentedIt was not a good idea to include two separate feature changes into the same issue. Now the IP white list cannot be committed before the "enable" switch is decided and vice versa.
Considering that nothing breaks if we check "enable" with an empty username, it's safer to enable than leave a site unprotected.
Please note that adding the "enable" option should also be described in the documentation, and it will conflict with enable/disable in settings.php
Comment #21
RumyanaRuseva commentedUpdated the patch as follows:
1. Changed the update hook to get the effective value instead of the stored value.
2. Added support for Network ranges. Now using Symfony\Component\HttpFoundation\IpUtils to check the IP.
3. Added trim() to allow whitespaces in the list. There is no need for validation of the input, because IpUtils::checkIp() handles that.
4. Changed field descriptions and added instructions in Readme. Added red color to the reverse proxy caching issue warning, because it's very important.
Interdiff file attached.
Comment #22
tcfunk commented+1 for the trim, was going to mention that as an issue.
I also wonder, how do you feel about a multi-line text field for the IP address, rather than one comma-separated line? I feel like this would be more consistent with how multi-value fields are presented throughout Drupal. It also is much easier to read than one long line of text.
This patch is working off #21, but changes the input to a textarea, and the delimiter to "\n". I've also moved the example values from the description into the placeholder, since it was getting a little messy having a multi-line example in the description.
Comment #23
RumyanaRuseva commentedThank you, I agree that a text area is better.
I assume that tcfunk has reviewed the patch from #21, and axel.rutz and I reviewed the previous versions, so I'm setting the issue RTBC.
Comment #24
apugacescu commented22tcfunk
I am concerned about multiple line text instead of commas because of new line separator issue on different OSes. As you might know on windows instead of LF, CR-LF is used, on mac there are cases when only CR is the line separator.
Comment #25
RumyanaRuseva commentedDifferent line endings should not be a problem when exploding by "\n".
When the input uses "\r\n", the lines will be correctly separated, and trim() will remove the "\r".
Line ending with "\r" alone is not standard, and it hasn't been used in Macs since 2001. There is no need to consider it.
There are plenty of examples in core where new lines are exploded by "\n", and nobody has ever complained :)
Comment #26
tcfunk commentedI did some digging through core source to see how Drupal handles the multiple-value fields. Looks like it uses the same explode by "\n" method. The method I'm looking at is here:
core/modules/options/src/Plugin/Field/FieldType/ListItemBase.php, line 173
If anything it could be worth adding the same
$list = array_filter($list, 'strlen');to our code to filter out empty items.Comment #27
RumyanaRuseva commentedIt's already there, just in a single line:
$whitelist = array_filter(array_map('trim', explode("\n", $whitelist)));Comment #28
anybodyConfirming RTBC. There are several RTBC'd issues for the D8 branch. Is there an active maintainer able to have a look and create a new release?
Comment #29
geek-merlinComment #30
geek-merlinComment #32
geek-merlin> It was not a good idea to include two separate feature changes into the same issue. Now the IP white list cannot be committed before the "enable" switch is decided and vice versa.
Yes.
Finally committed this. Please look into the followups. And a big ❤️ to everybody!
Comment #33
anybodyThank you very much Axel! That's really useful, love to see it back in D8.
Comment #35
kkohlbrenner commentedTested the patch in #22 https://www.drupal.org/project/shield/issues/2855364#comment-12576428 and observed the following:
This code doesn't check if whitelist is configured. If no Ip's are whitelisted/added to the configuration, $in_whitelist will always be false. Thus, the authentication will always be prompted. If $whitelist is empty, $in_whitelist should be true OR logic shouldn't be processed against it.
I think IpUtils::checkIP($request->getClientIp(), $whitelist) introduces unwanted complexity to checking if a ip is included in whitelisted ip configuration. Restrict IP implements similar functionality to whitelist IP's, see here. I've configured ip's successfully using Restrict IP and observed the expected whitelisting. I think there is room to adopt how that module checks ips, here
Next Steps
- Review similar fnctionality used in other contrib modules.
- Create patch
Comment #36
anybodyFollow-up: #3052723: Add whitelist default in shield.settings.yml