Problem/Motivation
Just to re-hash the past here. At one point, Drupal core introduced an inline script to address a flickering issue in the toolbar. This module addressed the CSP issues from that
π
Disable toolbar anti-flicker inline JS
Fixed
. Then, core moved that script to a file
Toolbar anti-flicker JavaScript is no longer added inline β
, and this module followed suite by removing the unnecessary fix
π
Remove code to disable inline anti-flicker js
Fixed
.
The new script introduced by core however now adds a new CSP issue, by adding an inline style. With a basic CSP installation on a fresh install under the standard profile, I get this error:
Refused to apply inline style because it violates the following Content Security Policy directive: ... . Note also that 'style-src' was not explicitly set, so 'default-src' is used as a fallback.
(anonymous) @ toolbar.anti-flicker.js?v=10.3.2:62
The corresponding code in toolbar.anti-flicker.js
if (activeTray) {
// These styles are added so the active tab/tray styles are present
// immediately instead of "flickering" on as the toolbar initializes. In
// instances where a tray is lazy loaded, these styles facilitate the
// lazy loaded tray appearing gracefully and without reflow.
const styleContent = `
.toolbar-loading #${activeTabId} {
background-image: linear-gradient(rgba(255, 255, 255, 0.25) 20%, transparent 200%);
}
.toolbar-loading #${activeTabId}-tray {
display: block; box-shadow: -1px 0 5px 2px rgb(0 0 0 / 33%);
border-right: 1px solid #aaa; background-color: #f5f5f5;
z-index: 0;
}
.toolbar-loading.toolbar-vertical.toolbar-tray-open #${activeTabId}-tray {
width: 15rem; height: 100vh;
}
.toolbar-loading.toolbar-horizontal :not(#${activeTray}) > .toolbar-lining {opacity: 0}`;
const style = document.createElement('style');
style.textContent = styleContent;
style.setAttribute('data-toolbar-anti-flicker-loading', true);
document.querySelector('head').appendChild(style); // Error happens here.
Steps to reproduce
Under a standard installation on any page while logged in as a user with access to the toolbar. Tested in core 10.3.2, and CSP 2.0.2
Proposed resolution
Site builders would need to add the "unsafe-inline" attribute to their style or default CSP directives. Most of them probably do already, since the need for this seems rather ubiquitous. But we can certainly strive for CSP perfection, right? I'm not really sure what the best practice here for a proposed resolution should be. replace the core script with a version in CSP that uses the nonce?
I assume it would need to add something like this:
style.setAttribute('nonce', drupalSettings.csp.nonce);
Edit: ... Except we can't access drupalSettings in this anti-flicker script, because it's included before everything else.