Needs review
Project:
Security Kit
Version:
2.0.3
Component:
Code
Priority:
Major
Category:
Feature request
Assigned:
Unassigned
Reporter:
Created:
17 Jan 2017 at 12:34 UTC
Updated:
27 Sep 2024 at 08:33 UTC
Jump to comment: Most recent, Most recent file
Comments
Comment #2
jweowu commentedImplemented in http://cgit.drupalcode.org/seckit/commit/?id=734e0d2 in the 7.x version, and that commit pre-dates 7.x-1.9 which was the starting point for the 8.x version IIRC.
Maybe the hook was removed in favour of some alternative D8 approach?
Comment #3
ogggg commentedActually it's a major issue, because you can't even edit views settings when CSP is enabled. (and unsafe-eval is disabled)
Comment #4
realityloop commentedNot being able to edit views settings I think makes this a major priority.
Comment #5
mfbRaven module needs to be able to alter the CSP and CT report-uri at runtime. This works fine in the Drupal 7 version of this module, but apparently isn't yet possible in the Drupal 8 version?
Comment #6
jweowu commentedI guess the D8 change record at https://www.drupal.org/node/1894902 is the place to start.
Comment #7
jweowu commentedThe change record's child issue https://www.drupal.org/project/drupal/issues/2301577#comment-10046822 says:
I'm not seeing any instances of
->alterin the D8 branch though, so I guess this really is unimplemented?Perhaps the above is sufficient for a patch to be provided.
Comment #8
jweowu commentedThis appears to be trickier than I'd hoped.
Invoking an alter hook is trivial enough -- I believe we can literally substitute the code
\Drupal::moduleHandler()->alter(...)in place of the originaldrupal_alter(...)to do that. Thealtermethod itself is described inModuleHandlerInterface::alter()The problem is that we're now (at least presently) dealing directly with the Drupal 8 configuration system, rather than indirectly obtaining the config via a
_seckit_get_options()function (which, in D7, read the options, merged with defaults where necessary, invoked the alter hook, and then cached and returned the results).So how does one provide run-time overrides to the Drupal 8 configuration system?
The place to start seems to be Configuration override system and to me that seems to suggest a couple of possibilities:
1. Providing overrides from modules shows how modules can override config without any kind of hook. That sounds great, but it's a bunch more code than a simple alter hook implementation (albeit also not an absolutely crazy amount of code). I have absolutely no idea how this works in detail, though -- are the alterations executed at run-time on every request? Or are they expected to be cached and not re-generated regularly? If the latter, this would provide a much lesser level of control over the SecKit options than
hook_seckit_options_alter()does, in which case I would suggest that it's insufficient. If the former... maybe this was how the authors of the D8 port of SecKit expected people to deal with this issue?2. Global overrides points out something which is definitely on the low-level side, but is also a lot simpler, and will (I strongly suspect) provide run-time overrides.
On that basis, a potential approach is to change
SecKitEventSubscriber::__construct()insrc/EventSubscriber/SecKitEventSubscriber.phplike so:(I've used the name "hook_seckit_settings_alter" instead of "hook_seckit_options_alter" just to follow the naming scheme used in the D8 code.)
Assuming that this gets executed on a per-request basis, that would seem somewhat similar to the Drupal 7 code.
Someone else will need to tell me whether it actually works, though.
Offhand (and notwithstanding my lack of exposure to D8 code) it didn't seem particularly Drupal-8-ish to be messing with the global variable like this; but on the other hand this is what they've documented, so perhaps it's fine. I don't know enough to say either way. I've only discussed it with one other developer, and they didn't like the idea, but it also wasn't clear to me that there was any practical alternative which facilitates arbitrary run-time alterations to the settings.
Naturally, with overrides in place, the SecKit config form will need to ensure that it is Avoiding overrides for the admin config forms.
In Drupal 7
_seckit_get_options()provides a boolean argument$alterto say whether or not the alter hook would be invoked, and so in the admin form we passFALSEfor that in order to obtain the un-altered configuration:Comment #9
jweowu commentedA third option is, of course, to revert to precisely that behaviour, and (re-)implement a function for returning all of the settings.
If the other options to alteration are considered undesirable, this might actually be the way to go.
Comment #10
berliner commentedI needed this for my current project as well, mainly to be able to define a per-request nonce and some additional CSP attributes that the module config does not support.
Without getting into the details to cover an override/alter mechanism for all settings, I'll provide a patch that only adds support for an alter hook, so as to modify the CSP directives that are build in
SecKitEventSubscriber::seckitCsp.It can be used like this:
Comment #11
mfbFor Raven module, I ended up going the ConfigFactoryOverride route to automatically override the Security Kit configuration - but still would be nice to see an easier way for modules to alter the CSP header...
Moving this to the 2.x branch, and adding Needs tests tag.
I noticed a couple minor issues, the new $module_handler parameter should be described in comment, and I guess a post_update is needed to force a rebuild for the new parameter.
Comment #12
jweowu commentedLooking briefly at this again, I am strongly in favour of #9: Do more or less exactly what we do in Drupal 7, and then invoke the alter hook from that function. AFAICS Drupal simply isn't providing any sane alternative to that (very simple) solution, which will add a fairly important feature that's been missing from the D8 version of this module ever since it was ported.
Note that as of https://www.drupal.org/project/seckit/issues/3052779#comment-14399405 the D7 hook_seckit_options_alter() enables users to add CSP directives as well as modify existing ones, so this ability should be maintained in the D8+ port.
Comment #13
mfb@jweowu: Sounds good to me. I'm setting this issue to needs work as the supplied patch works fine for altering CSP, but needs to support other seckit options.
FYI, CSP module has pretty nice developer experience, as a CSP event subscriber can call Csp::fallbackAwareAppendIfEnabled() - https://git.drupalcode.org/project/csp/-/blob/8.x-1.x/src/Csp.php#L318 - and it will take care of all the logic of adding a CSP directive. But just an old-fashioned hook_seckit_options_alter() would be good enough, as the issue summary proposed - I don't have any strong opinion on exactly how seckit architects this :)
Comment #14
jnlarHi @jweowu & @mfb, I've attached a patch which attempts to replicate (D9 style) how the D7 version of
seckitalters options via hook as mentioned in #12. Some of the patterns in the D7 still seem to make sense currently so some logic is replicated. An initial test is included, but could be expanded on.Since we're dealing with the configuration system and we don't want overrides appearing in the config form,
getSeckitConfig()interacts withImmutableConfig, and caches the overrides as advised since it runs more than once during the request cycle.Including the "Needs manual testing" tag :^)
Comment #15
jnlarComment #16
jnlarAh, wasn't using the same pattern for the report path seen in the other tests. Updated patch.
Comment #17
mfb@jnlar I tested out converting some code that used config.factory.override to use this hook instead, and seems to work fine. The one gotcha I ran into was that the
style-srckey is missing from the config install yml file, so my code has to check if it exists. We could open a separate issue for that.Looks like you have a test so I also removed the "Needs tests" tag.
To flush caches, I would suggest adding an empty post_update function, rather than a
hook_update_N()withdrupal_flush_all_caches(), reason being that the way you wrote it will AFAIK result in flushing the caches twice.You can remove the core_version_requirement key from the test module.
There are some coding standards messages for your patch, but looks like the 2.x branch already has plenty of those so not sure if it's an issue for the maintainers.
Comment #18
jnlar@mfb Thanks for reviewing.
Opening a separate issue for adding the
style-srckey in config install sounds good.The way I wrote it will indeed flush the caches twice. I've removed the
hook_update_N()in favour of an emptyhook_post_update_NAME().Wouldn't want to creep in more coding standards issues so I've looked at the ones in the modified files.
Comment #19
jnlarCreated an issue for adding the CSP setting
style-srctoseckit.settings.ymlComment #20
geoffreyr commentedWe've been using #18 to adjust the CSP to allow for some rich legacy experiences that take over the page. We're taking configuration from Composer files in separate repositories to adjust the CSP rules for particular page requests -- highly custom but very effective. This patch has been of great benefit to us; and given that the patch provides new tests for this case, and that they're all passing, I'm willing to RTBC this.
Comment #21
jackfoust commentedAs of 2.0.2 this patch no longer applies to 2.x
Comment #23
geoffreyr commentedI've tried rerolling #18 against the latest 2.x. It seems to work but I reckon it needs a bit of a look. If anyone else wants to check the branch out and make changes that's all good.
Comment #24
ibullockI've tried #22 and it seems to work well for my use case at least (Adding to CSP domains list)
Comment #25
jnlarHi all,
Pulled in #22 and the changes look OK on my end :^) CI is passing + I've done some manual testing of the hook with things such as per request nonces in the CSP and blocking based on the CSRF
Originheader.Comment #26
emielb commentedI've created a quick patch based on the merge request #22 as an interim solution.