Content-Security-Policy: How to add inline CSS to HTML Documents in Icinga Modules

by | Oct 4, 2023

Since the Icinga Web 2.12 release we have added a setting to enable content security policy in Icinga Web.

This provides security against Cross-Site Scripting (XSS) attacks when the setting is enabled. This is done by adding Content-Security-Policy in our HTTP response header.

By default Content-Security-Policy header prevents execution of any inline scripts and inline styles. But in certain scenarios the css properties might change dynamically where inline css is a must. In this case a style element for this part of HTML document with a nonce attribute is added with corresponding styles configured. We also need to add `style-src` policy directive to `Content-Security-Policy` header with a nonce-source (hash-source) matching the inline style block. The nonce value is a random secure code that is dynamically generated and acts like an one time code. If you are interested to know more about more about content security policy checkout this link.

In this blogpost I would like to demonstrate how we add the style element to our HTML document with nonce attribute. For this demonstration both ipl-html and ipl-web libraries are required.

If an inline style is a necessity for one of our Icinga modules. Previously we used to add it using style attribute to an HTML element as below.

$htmlDocument = new \ipl\Html\HtmlDocument();
$htmlDocument->add(\ipl\Html\Html::tag('h1', ['style' => 'color:white;background:black;'], 'Inline Style'));

Since Icinga Web 2.12 and ipl-web 0.13.0 we do the following to conform with Content-Security-Policy.

$htmlDocument = new \ipl\Html\HtmlDocument();
$style = (new \ipl\Web\Style())->setNonce(\Icinga\Util\Csp::getStyleNonce());
$style->add('.header' => ['color' => 'white', 'background' => 'black']);
$html = \ipl\Html\Html::tag('h1', ['class' => 'header'], 'Inline Style');
$htmlDocument->add([$html, $style]);

Now the style for the header of the HTML document will be rendered even when the content security policy setting is enabled in Icinga Web GUI.

Moreover, you could also wrap the `header` class with some parent class selector to increase the specificity as shown below.

$style->setSelector('.parent1 .parent2');

In addition you could also style the element directly as following.

$style->addFor($html, ['color' => 'white', 'background' => 'black']);

Thanks for reading. Learn more about what is new in Icinga Web 2.12 here.

You May Also Like…

Subscribe to our Newsletter

A monthly digest of the latest Icinga news, releases, articles and community topics.