First some context :
I have several sites running Wordpress for which I want to be able to define a restrictive CSP, using nonce to allow inline scripts (WordPress plugins are nightmarish when it comes to plugin loading and a gazillion don't use the wp_enqueue_script, so you can't use a WordPress filter to do that at that level, pity because it can be done for properly enqueued scripts)
In order to do that I want to replace all '<script....>' tags with '<script nonce="12345ABCDE" ...>, a thing that I obviously cannot do by modifying each and every plugin that calls puts a script in the page.
I explored several possible solutions and while I can add the nonce, adding it before the DOM is loaded is where the rub is (after the DOM is loaded, it's too late the CSP wont allow execution because the nonce was not present at parsing time).
In the end I found something that might work by using Apache mod_ext_filter and another Apache module called cspnonce.
mod_cspnonce produces a nonce that it places ins a CSP_NONCE apache server variable, you just need to compile it and load it into your apache, works like a charm.
so I activated the Apache ext_filter module (and doubled checked that is was activated) after restarting my apache, then I created the filter:
<IfModule mod_ext_filter.c>
ExtFilterDefine nonceadder intype=text/html mode=output
cmd="/bin/sed 's/script/script nonce="'nonce-%{CSP_NONCE}e'" /g'"
</IfModule>
then added the output to the Directory directive:
<Directory /var/www/path/to/my/site>
Require all granted
AllowOverride All
Options -Indexes +Followsymlinks
SetOutputFilter nonceadder
</Directory>
(I also tied to set sit in a)
<Location "/">
SetOutputFilter nonceadder
</Location>
with the same result)
I tested the sed command itself with a fixed value for the CSP_NONCE on a terminal and is does what I want
restarted my Apache. and there... nothing. The filter is not executed, there is no apparent filtering taking place. (i tried with other sed coomands such as 's/a/o/g' just to test that it was the sed that wasn't executed.
Path of the sed command is right, (I've see others having problem with that, this is not the case here
apache2ctl -M produces the list of the following modules (ext_filter is there):
Loaded Modules:
core_module (static)
so_module (static)
watchdog_module (static)
http_module (static)
log_config_module (static)
logio_module (static)
version_module (static)
unixd_module (static)
access_compat_module (shared)
alias_module (shared)
auth_basic_module (shared)
authn_core_module (shared)
authn_file_module (shared)
authz_core_module (shared)
authz_host_module (shared)
authz_user_module (shared)
autoindex_module (shared)
cspnonce_module (shared)
deflate_module (shared)
dir_module (shared)
env_module (shared)
expires_module (shared)
ext_filter_module (shared)
filter_module (shared)
headers_module (shared)
http2_module (shared)
mime_module (shared)
mpm_event_module (shared)
negotiation_module (shared)
proxy_module (shared)
proxy_fcgi_module (shared)
reqtimeout_module (shared)
rewrite_module (shared)
setenvif_module (shared)
socache_shmcb_module (shared)
ssl_module (shared)
status_module (shared)
version details :
Ubuntu 18.04.5
Apache 2.4.46
So what did I forget ? What am I doing wrong ? I really am at a loss there any help would be welcome
question from:
https://stackoverflow.com/questions/66064940/apache-module-mod-ext-filter-does-not-filter-output-as-expected