Vraag:
Voor mijn website maak ik gebruik van diverse security headers om de beveiliging te verhogen. Een daarvan is “content-security-policy” waarmee ik precies kan bepalen welke interne en externe bronnen door mijn website ingeladen mogen worden. Zo kan ik voorkomen dat er schadelijke JS bestanden ingeladen worden.
Alleen gebruik ik WordPress met diverse plugins. Hierdoor kan het bijvoorbeeld voorkomen dat plugins overstappen van interne naar externe JS bestanden of van CDN (Content Delivery Network) wisselen om hun CSS bestanden in te laden.
Om het nog vervelender te maken heb ik ook advertenties van Google AdSense. Deze worden van vele verschillende wisselende URL’s ingeladen. Dit verschilt ook telkens omdat er wisselende advertenties worden getoond. Daarom kan het zo zijn dat tijdens mijn testrondjes ik alleen Google Adsense advertenties te zien krijg via URL’s die al ingesteld zijn in mijn “content-security-policy”.
Fouten in de instellingen kunnen ervoor zorgen dat mijn website niet meer juist werkt. Kan ik niet een melding krijgen wanneer er problemen zijn met mijn “content-security-policy”?
Antwoord:
Bij toeval kwam ik een tijdje geleden uit op de pagina over de “report-uri” directive op developer.mozilla.org. Deze directive is eigenlijk deprecated en vervangen door zijn opvolger “report-to” maar die wordt nog niet door alle browsers ondersteund. Daarom gebruik ik voorlopig nog even de “report-uri” directive.
Op de pagina stond ook een voorbeeld PHP script die problemen met de “content-security-policy” de eerste keer mailt en daarna in een logbestand op de server opslaat. Hiermee voorkom je tientallen mails van jouw eigen website.
Het voorbeeld script heb ik op een aantal punten aangepast en ziet er nu zo uit:
// Configuration: $log_file = $_SERVER['DOCUMENT_ROOT'] . '/csp-violations.log'; $log_file_size_limit = 1000000; // bytes $email_address = 'jouwnaam@jouwdomein.nl'; $email_subject = 'Jouwdomein.nl > Content-Security-Policy violation'; // Generate domain and subject for e-mail. $current_domain = preg_replace('/www\./i', '', $_SERVER['SERVER_NAME']); $email_subject = $email_subject . ' on ' . $current_domain; // Set response code to HTTP 204 No Content http_response_code(204); // We pretty print the JSON before adding it to the log file $json_data = file_get_contents('php://input'); if ($json_data = json_decode($json_data)) { $json_data = json_encode($json_data, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES); // If the file doesn't exist, sent a mail. if (!file_exists($log_file)) { // Compose mail. $message = "The following Content-Security-Policy violation occurred on " . $current_domain . ":\n\n" . $json_data . "\n\n" . "Further CSP violations will be logged to the following log file, but no further email notifications will be sent until this log file is deleted:\n\n" . $log_file; $headers = 'Content-Type: text/plain;charset=utf-8' . "\r\n" . 'From: ' . $email_address . "\r\n" . 'Reply-To: ' . $email_address . "\r\n"; // Send mail. mail($email_address, $email_subject, $message, $headers); } // If the file is bigger then the limit stop adding data. if (filesize($log_file) > $log_file_size_limit) { exit(0); } file_put_contents($log_file, $json_data, FILE_APPEND | LOCK_EX); }
Aantal opmerkingen over bovenstaand bestand:
- Het bestand heb ik in de root van mijn website gezet (htdocs of public_html).
- Als het logbestand niet bestaat wordt dit aangemaakt.
- Data wordt toegevoegd totdat het logbestand de 1024KB in omvang overschrijdt.
Content-Security-Policy voorzien van “report-uri” directive:
Vervolgens heb ik mijn “Content-Security-Policy” in het .htaccess bestand aangepast zodat deze weet naar welk endpoint geconstateerde problemen gestuurd moeten worden.
In dit geval is het endpoint het PHP bestand van hierboven. Dit PHP bestand mailt of bewaard de problemen in het logbestand. Eigenlijk heel simpel dus.
Header set Content-Security-Policy "default-src; report-uri https://www.jouwdomein.nl/jouw_bestandsnaam.php "
Conclusie:
Het goed afstellen van een “content-security-policy” is belangrijk en kost tijd. Met bovenstaande PHP script + report-uri wordt ik in ieder geval op de hoogte gehouden van URL’s die voor problemen zorgen. Dit zorgt ervoor dat mijn website juist blijft functioneren.