Didier Fabert (tartare): WordPress et CSP: unsafe-inline et unsafe-eval (script-src)

Ou comment supprimer unsafe-inline et unsafe-eval de script-src dans l’en-tête HTTP Content-Security-Policy avec WordPress et obtenir un A+ sur securityheaders.io.

Déjà, autant prévenir, ça va être long et pénible… Cela se fera à coup de petite modification, test, re petite modification. Oui modification est au singulier, car on ne change qu’un paramètre à la fois entre chaque test.

WordPress seul est dans l’ensemble assez propre, dans le sens où il n’embarque que très peu de javascript inline. Il n’y a donc que quatre problèmes à résoudre

  1. Désactiver les emojis, avec un plugin pour ne pas toucher au code
  2. Choisir un thème n’utilisant pas de javascript inline
  3. N’utiliser ques des plugins sans javascript inline
  4. Ajouter une exception pour la partie admin

Ça parait simple dit comme ça, mais dans la pratique, le moindre plugin (surtout ceux de galerie d’images) peut venir violer la politique de sécurité du contenu (Content-Security-Policy). De plus, pour avoir les rapports de violation des CSP, il va falloir un script qui enregistre tout ça.

Prérequis

  • On s’écrit un petit script PHP perfectible qui enregistrera les violations. Vu le peu de sécurité offert par ce script, il est préférable de le durcir et de mutualiser l’enregistrement des rapports: Expect-Certificate-Transparency (ect) et Public-Key-Pins (pkp). Ou bien de simplment le supprimer une fois nos tests effectués.
    Fichier /usr/share/wordpress/report.php
    <?php
    date_default_timezone_set('UTC');
    $LOGPATH = "/var/log/httpd";
    $ROWS = array(
      'violated-directive',
      'effective-directive',
      'blocked-uri',
      'document-uri',
      'line-number',
      'status-code',
      'referrer',
      'disposition',
      'original-policy',
      'script-sample'
    );
    
    $header = date("Y-m-d H:i:s");
    $raw = file_get_contents('php://input');
    
    if ( ! isset( $raw ) or empty ( $raw ) or strlen( $raw ) >= 2048 ) {
      exit( 1 );
    }
    
    $rows = json_decode( $raw );
    $message = $header . ' csp-report' . PHP_EOL;
    foreach( $ROWS as $row ) {
      $message .= "  $row: " . $rows->{'csp-report'}->{$row} . PHP_EOL;
    }
    $message .= PHP_EOL;
    
    $file = file_put_contents( $LOGPATH . "/report.log", $message, FILE_APPEND | LOCK_EX );
    
    echo "For reporting Content-Security-Policy violation";
    exit( 0 );
    
  • On va commencer en mettant une définition très restrictive dans la configuration apache.
    Header always set Content-Security-Policy "default-src 'self' data: ; script-src 'self' ; style-src 'self' 'unsafe-inline' ; font-src 'self' data: ; img-src 'self' data: ; report-uri https://blog.example.com/report.php"
    
  • On désactive tous les plugins WordPress

On verra apparaitre au rechargement de la page, les premiers rapports, dans le fichier /var/log/httpd/report.log

Premier test

Rapports de violation

  • C’est le seul problème du cœur de WordPress (hors partie admin) concernant la politique de sécurité du contenu: les emojis.
    2017-11-12 12:02:29 csp-report
      violated-directive: script-src https://www.tartarefr.eu
      effective-directive: 
      blocked-uri: self
      document-uri: https://www.tartarefr.eu/
      line-number: 12
      status-code: 
      referrer: 
      disposition: 
      original-policy: default-src https://www.tartarefr.eu data:; script-src https://www.tartarefr.eu; style-src https://www.tartarefr.eu 'unsafe-inline'; font-src https://www.tartarefr.eu data:; img-src https://www.tartarefr.eu data:; report-uri https://report.tartarefr.eu/report.php?type=csp
      script-sample: 
                            window._wpemojiSettings = {"baseUrl"...
    
  • Dans le CSS de notre thème, il y a une dépendance à https://fonts.googleapis.com
    2017-11-12 12:02:29 csp-report
      violated-directive: style-src https://www.tartarefr.eu 'unsafe-inline'
      effective-directive: 
      blocked-uri: https://fonts.googleapis.com
      document-uri: https://www.tartarefr.eu/
      line-number: 
      status-code: 
      referrer: 
      disposition: 
      original-policy: default-src https://www.tartarefr.eu data:; script-src https://www.tartarefr.eu; style-src https://www.tartarefr.eu 'unsafe-inline'; font-src https://www.tartarefr.eu data:; img-src https://www.tartarefr.eu data:; report-uri https://report.tartarefr.eu/report.php?type=csp
      script-sample:
    

Résolution

  • On ré-active (installe et active) le module Disable Emojis
  • On ajoute https://fonts.googleapis.com à notre en-tête Content-Security-Policy, dans la section style-src et on recharge Apache.
    Header always set Content-Security-Policy "default-src 'self' data: ; script-src 'self' ; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com ; font-src 'self' data: ; img-src 'self' data: ; report-uri https://report.example.com/report.php?type=csp"

Deuxième test

Rapports de violation

    • C’est la dépendance pour la police de caractère
      2017-11-12 12:06:52 csp-report
        violated-directive: font-src https://www.tartarefr.eu data:
        effective-directive: 
        blocked-uri: https://fonts.gstatic.com
        document-uri: https://www.tartarefr.eu/
        line-number: 
        status-code: 
        referrer: 
        disposition: 
        original-policy: default-src https://www.tartarefr.eu data:; script-src https://www.tartarefr.eu; style-src https://www.tartarefr.eu 'unsafe-inline' https://fonts.googleapis.com; font-src https://www.tartarefr.eu data:; img-src https://www.tartarefr.eu data:; report-uri https://report.tartarefr.eu/report.php?type=csp
        script-sample: 
      

Résolution

      • On ajoute https://fonts.gstatic.com à notre en-tête Content-Security-Policy, dans la section font-src et on recharge Apache.
        Header always set Content-Security-Policy "default-src 'self' data: ; script-src 'self' ; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com ; font-src 'self' data: https://fonts.gstatic.com ; img-src 'self' data: ; report-uri https://report.example.com/report.php?type=csp"

À partir d’ici, on reçoit plus de rapport de violation, sauf si on essaie la partie administrateur ou un plugin de galerie.

La partie administrateur

La partie administrateur du site ne fonctionne pas bien avec notre définition de Content-Security-Policy. On va encore l’adapter mais à la fin il faudra tricher pour la section script-src et modifier l’en-tête HTTP Content-Security-Policy pour la partie admin.
On va donc ajouter à notre définition Content-Security-Policy

  • https://code.jquery.com à notre en-tête Content-Security-Policy, dans la section style-src
  • https://code.jquery.com à notre en-tête Content-Security-Policy, dans la section img-src
  • https://secure.gravatar.com à notre en-tête Content-Security-Policy, dans la section img-src

Pour le reste, pas de recette miracle, hélas. La définition dans Apache devient ceci:

<Location "/wp-admin">
  ...
  Header always set Content-Security-Policy "default-src 'self' data: ; script-src 'self' 'unsafe-inline' 'unsafe-eval' ; style-src 'self' 'unsafe-inline' fonts.googleapis.com ; font-src 'self' fonts.gstatic.com data: ; img-src 'self' data: secure.gravatar.com ; report-uri https://report.example.com/report.php"
</Location>
Header always set Content-Security-Policy "default-src 'self' data: ; script-src 'self' ; style-src 'self' 'unsafe-inline' fonts.googleapis.com https://code.jquery.com ; font-src 'self' fonts.gstatic.com data: ; img-src 'self' data: https://code.jquery.com https://secure.gravatar.com ; report-uri https://report.example.com/report.php"

Test du site sur securityheaders.io

Bien évidemment, on ne teste pas la partie admin …


Source From: fedoraplanet.org.
Original article title: Didier Fabert (tartare): WordPress et CSP: unsafe-inline et unsafe-eval (script-src).
This full article can be read at: Didier Fabert (tartare): WordPress et CSP: unsafe-inline et unsafe-eval (script-src).

Advertisement


Random Article You May Like

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*