Content-Security-Policy vs Hugo's syntax highlighting in code blocks

I’m experimenting with Content-Security-Policy HTTP headers on my website (where I am writing a Hugo theme). I currently have the following header:

Content-Security-Policy: "default-src 'none'; img-src 'self' https://i.ytimg.com; script-src https://gc.zgo.at/count.v1.js; style-src 'self'; frame-ancestors 'none'"

Sadly, I’ve found a problem with Hugo’s syntax highlighting: it uses inline styles and is therefore blocked, with an error like this in Firefox: “Content Security Policy: The page’s settings blocked the loading of a resource at inline (“style-src”).”

Here’s a page where the problem occurs: Maximum Ethics | My Second Post

Does anyone have any ideas or tips for using CSP with Hugo’s syntax highlighter? Or is it hopeless?

It’s not hopeless. A quick and insecure solution would be to add the following:

in your inline style:

<style nonce="r@nd0m">
	.red { color: red }
</style>

in your CSP:

style-src something somethingelse 'nonce-r@nd0m';

The r@and0m can be anything.

Putting that into a custom shortcode should solve the issue.

OK, but you say it is insecure. How bad is this solution? Obviously I am using CSP because I am trying to take security seriously. Why is it insecure? Is it insecure because we should be trying to generate individual hashes for every inline style, and that’s ridiculous when there’s a new style block for every word?

I realise just now, that you can’t change the returns of highlighting… hmmm…

Does this link maybe help?

https://sean.burlington.me.uk/post/hugo-syntax-highlight-unsafe-inline.html

3 Likes

If it would work it would be as bad as the “hash” you choose. You would get securer by hashing each bit of content between the style-tags and use an individual hash per inline-style. But the easiest way would be to use one consistent hash for all of the inline hashes, so you don’t need to manipulate your CSP rules each time you change something…

but as I said - I don’t think you can change what the highlighting returns… This might be worth an issue on Github.

OK, disabling inline styles and moving those styles to an external CSS file (as recommended in that blog post) seems like the best solution for now.

I wouldn’t want hashes for every word in a code block, that doesn’t sound clean/elegant/attractive, and having one hash for all of the blocks sounds like mediocre security.

Here’s the commit where I implement this for my theme, which is now live on my site: ~skyfaller/maxethics-hugo: add optional stylesheet for syntax highlighting - sourcehut git

Now the relevant section of my config.toml looks like this:

[params]
# Use separate stylesheet for syntax highlighting.
# If you set noClasses = and don't set this, syntax highlight won't happen
# Also, then you must use the "highlight" shortcode at least once on a page to activate the stylesheet for that page
	syntaxCSS = true
# If you turn off in-line styling, this is where tabWidth gets set
	tabWidth = 2

[markup]
	[markup.highlight]
		noClasses = false
# The above setting disables in-line styling, so this won't do anything unless you set noClasses = true
		# tabWidth = 2

Thank you for your helpful suggestion and superior google-fu!

1 Like

This topic was automatically closed 2 days after the last reply. New replies are no longer allowed.