Dr Clèm's Blog

Captain's Log #2

Tuesday Nov 21, 2017 17:38
To Do List

I am working on TootLine, the PHP code that allows you to share your TootLine on your blog, like the one there is on the right or bottom, depending on the size of your screen. I have couple of issues to address before publishing it, which are proper word wrapping, create a cache for the media in order to solve CSP issue, handle the NSFW content that is displayed so far.

Tags' categories

I am planning on adding click-able tags to fetch all articles with matching tags.


I already published a note in French and I began to write couple of drafts in French, so I would like to make a French version of this blog, with most of the articles translated.

Content Security Policy (CSP) headers

I added Content Security Policy (CSP) headers.

RSS feed

I added few elements to MySQLiToRSS, I add proper end of file to the generated RSS feed and I used the fact that I made tags click-able to add domain to the category element.

Better looking links

I changed the URL of some links to make them better looking.


I addition to what remains on the To Do List, I want to add couple of improvement.

More restrictive CSP headers

I want to rewrite some part of the web site to be able to provide more secure CSP headers.


I am planning on adding a RSS feed for each commentary section so it will be easy to follow. I will also add a cookie to auto fill the fields Name and Website. I will put a check box if you want to add the cookie when you comment.


I will add the list of all tags on the right panel.


I will add proper Open Graph protocol and Twitter cards in the headers. I already updated the MySQL database, so everything is ready on this side, I just need to rewrite the headers that I include to make them dynamic.

Better looking links

I already changed the URL of some links to make them better looking, but I did not finish yet. The rewriting rules are not as simple as I expected, if you want to make them SEO compliant.

Better CMS

My work-flow is not the most efficient. Each article points to an actual file, which is not so good, because I need to create a file each I add an entry in this blog. I will improve this soon.

Trackback, impossible?

I tried to add trackback, but the most up to date page about it is more than 5 years old and all links are dead links, including the sample codes to make it work. If someone can explain me how to implement it, I will be pleased :)

How to set up Content Security Policy headers?

Tuesday Nov 21, 2017 04:45

I think a have a simple methodology to build Content Security Policy (CSP) headers. I did it with Apache HTTP Server and Firefox, but it is a generic methodology. I assume that you know what are CSP headers.

Before we start

First, you might want to disable most of your extensions. Indeed, some will add scripts or rewrite part of the displayed HTML code making it hard to distinguish warnings and errors form your code than from the extensions. I kept Test Pilot , Multi-Account Containers and Firefox Lightbeam by Mozilla, Privacy Badger and HTTPS Everywhere by the Electronic Frontier Foundation, and DuckDuckGo Plus by DuckDuckGo.

A useful tool

Laboratory by April King is an extension that allows you to record your website in order to provide a ready CSP header. But it is no fun and it does not push you think about how to rewrite some parts of website in order to improve security. You can also enforce CSP, which is useful if you add another component, for example if you add your Twitter timeline, you will need to adjust your CSP headers. With this tool, it is easy to check, try, add CSP headers, that you can later add to you web server. But for the purpose of this small how to, do not use this extension. If installed, please make sure that none of the check boxes are enabled and that Generated CSP configuration: is set to default-src 'none' if not, click on Delete All Settings or it will be a nightmare.

Laboratory extension

Always keep Developer Tools opened

Another step to avoid spend plenty of time looking at irrelevant answers on Stack Exchange is to open the Developer Tools, go on the options tab and check Disable HTTP Cache (when toolbox is open), and then keep it open at all time. Otherwise, some requests can be cached and you will not understand why your brand new configuration is not taking into account.

Building your CSP headers without blocking content
Report only

We will use the Content-Security-Policy-Report-Only header. When the web browser receive the content of a web page, it will display warnings for each violated CSP directive. We will see later that it can be used in a better way.

Be verbose

I strongly advise to add all possible directives to the header because any warning or error not related to an explicitly defined directive will be reported as violating default-src. This is because directives inherit from default-src if not explicitly set. If you only have something like default-src 'none'; style-src 'self';, then an unsafe-inline for script-src will be reported as violating default-src.

So our starting point will be default-src 'none'; child-src 'none'; connect-src 'none'; font-src 'none'; frame-src 'none'; img-src 'none'; manifest-src 'none'; media-src 'none'; object-src 'none'; script-src 'none'; style-src 'none'; worker-src 'none'; base-uri 'none'; frame-ancestors 'self'; and from this, we will allow one by one what we need.

Send report to your website

We will use a very nice feature of CSP, report-uri. It makes web browsers send a JavaScript Object Notation (JSON) file to the web server at the specified Uniform Resource Identifier (URI). This file will give you the basic instructions to build the correct CSP header. In my case, I created a folder /csp/ with the proper ownership and write rights containing one file index.php

// Start configure
$log_file dirname(__FILE__) . '/csp-violations.log';
$log_file_size_limit 1000000// bytes - once exceeded no further entries are added
// End configuration
$current_domain $_SERVER['SERVER_NAME'];
http_response_code(204); // HTTP 204 No Content
$json_data file_get_contents('php://input');
// We pretty print the JSON before adding it to the log file
if ($json_data json_decode($json_data)) {
$json_data json_encode($json_dataJSON_PRETTY_PRINT JSON_UNESCAPED_SLASHES);
// Do not write is file size exceeded
if (filesize($log_file) > $log_file_size_limit) {
file_put_contents($log_file$json_dataFILE_APPEND LOCK_EX);
It is a simplified and adapted version of the code you can find here. It will log errors and warnings in /csp/csp-violations.log.

All together

In your virtual host, add the following line

Header set Content-Security-Policy-Report-Only "report-uri /csp/; default-src 'none'; child-src 'none'; connect-src 'none'; font-src 'none'; frame-src 'none'; img-src 'none'; manifest-src 'none'; media-src 'none'; object-src 'none'; script-src 'none'; style-src 'none'; worker-src 'none'; base-uri 'none'; frame-ancestors 'self';"
Mind the ' and the ". The set of directives must start and end with ". All arguments of each directive must be surrounded by ' if, and only if, they are keywords. The corollary is do not use ' to surround Uniform Resource Locator (URL) and URI.

Restart Apache HTTP Server

# systemctl restart apache2


Visit your website. You should see in the Console tab of the Developer Tools.

In the /csp/ folder of you virtual host, you should see the csp-violations.log file. It contains lines like

     "csp-report": {
         "blocked-uri": "self",
         "document-uri": "https://clementfevrier.fr/images/r3.svg",
         "original-policy": "report-uri https://clementfevrier.fr/csp/ https://clementfevrier.fr/images/default-src https://clementfevrier.fr/images/'none'; child-src 'none'; connect-src 'none'; font-src 'none'; frame-src 'none'; img-src 'none'; manifest-src 'none'; media-src 'none'; object-src 'none'; script-src 'none'; style-src 'none'; worker-src 'none'",
         "referrer": "https://clementfevrier.fr/articles/11_rand.php",
         "script-sample": "onclick attribute on g element",
         "source-file": "https://clementfevrier.fr/images/r3.svg",
         "violated-directive": "script-src 'none'"
original-policy displays the CSP header. It is useful to ensure that it matches what you set in our web server. violated-directive tells you with directive you should adjust, in this example script-src and it also remind you its arguments 'none' because it is our starting point. blocked-uri tells you what it blocked, here it is self. So, you just need to replace script-src 'none' by script-src 'self' and the warning will disappear.

Repeat this for each violated directive.

Notice that without explicitly setting all directives, violated-directive will always report to default-src which makes it more difficult to debug.

For each directive that I set, I restart the web server, delete the log file, reload a page from my website in my web browser, and look at the new log.

Don't forget to check different pages of your web site to check all cases.

Your CSP log file does not report anymore violated directive? Let us add the real header.

Apply your CSP

Your header should look like

Header set Content-Security-Policy-Report-Only "report-uri /csp/; default-src 'none'; connect-src 'self'; font-src 'self'; frame-src 'none'; img-src 'self' data: https://toot.forumanalogue.fr; manifest-src 'none'; media-src 'self'; object-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; worker-src 'none'; base-uri 'none'; frame-ancestors 'self';
Just remove the -Report-Only and you are done.
Header set Content-Security-Policy "report-uri /csp/; default-src 'none'; connect-src 'self'; font-src 'self'; frame-src 'none'; img-src 'self' data: https://toot.forumanalogue.fr; manifest-src 'none'; media-src 'self'; object-src 'self'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; worker-src 'none'; base-uri 'none'; frame-ancestors 'self';

Restart Apache HTTP Server

# systemctl restart apache2

Final checks

First, check that your website renders as you wish.

Then, there are couple of useful tools to perform checks on you CSP headers.

Check their recommendations and the links, they are full of useful informations.

As you can see, I still have to work to achieve a good CSP, but I know you to eliminate most of the so-called insecure inline code. I say so-called because for most of it, if not all of it, it is perfectly secure since I am not in the cases where it can be potentially insecure.

Changing you website and modifying your CSP headers

You can have both Content-Security-Policy-Report-Only and Content-Security-Policy at the time. It is useful to make a more restrictive CSP without blocking content. You can have one report-uri for the block content and one for the report only, which will simplify debugging.

Further reading

MDN Web Docs, by Mozilla, is the only website that I found with proper explanation and reference of CSP.

Dr Clément Février

Bonjour, Je suis Clément Février, docteur en physique théorique de l’université de Grenoble Alpes, ingénieur Recherche et Développement dans le domaine de l’imagerie médicale et de la chirurgie mini-invasive chez Surgivisio et soutien du mouvement La France Insoumise.

Coucou les mastopotes sur #Toulouse : le fiston commence son stage lundi, et il attend une réponse du CROUS pour un logement étudiant (il faut la convention signée, qu'il n'aura que lundi).

Il aurait donc besoin d'un hébergement temporaire, de dimanche soir à mardi/mercredi au plus tard.
Si vous avez un petit coin pour l'accueillir, avec un accès métro / bus, ce serait super sympa.

Je précise : il est un peu geek mais propre et bien élevé, et très ami avec les chats :D

RP bienvenu !

RT @clement
Boite spécialisée dans la chirurgie du rachis (orthopédie et neurologie). Nous avons commercialisé (1000 chirurgies) un appareil d'imagerie intra opératoire (X-Rays et tomographie) et de navigation.

Job : Tous ^^ On doit avoir 50 postes ouverts. Mais on cherche surtout des ingés et en particulier dev C++. Tout niveau, de l'architecte expérimenté à la personne cherchant un stage de fin d'étude. Du développement applicatif au développement bas niveau de driver.

Me contacter en MP

C'est quand la dernière fois que vous avez utilisez un lecteur pour lire le contenu d'un CD, d'un DVD, d'un Blu-ray (ou même de HD DVD, MiniDisc ou autre support de ce type) ?

(Je me rends qu'une personne ayant utilisé ce type de support il y a tout juste cinq ans ne saurait pas forcément quelle réponse cocher, pour lever cette embéguinée :
- les bornes « moins de x » sont inclusives, la valeur x est donc inclue dedans,
- la borne « plus de x » ne l'est pas.)