You Want to Implement Content Security Policy (CSP). Read Now.

Like any conscientious developer, I am implementing Content Security Policies to protect me site from Cross-Site Scripting (XSS) and data injection attacks. So i decided to run Google Lighthouse to give it a thorough analysis. This time, I really paid attention to the report rather than just glancing at my Web Core Vitals score.

Lighthouse CSP Warning
Lighthouse CSP Warning

While reviewing the Best Practices section, specifically under Trust and Safety, I noticed that I hadn’t implemented the Content Security Policy. Armed with my 25 years of experience in development, I turned to ChatGPT and searched for “wordpress hook to add script-src and object-src metas to the header”. Voila! The following code popped up.

// Add custom meta tags to the header
    function add_custom_meta_tags() {
        ?>

        <meta http-equiv="Content-Security-Policy" content="default-src 'self'; script-src 'self'; style-src 'self'; object-src 'self'">
    
        <?php
    }
    add_action('wp_head', 'add_custom_meta_tags');

In this CSP configuration:

  • default-src 'self': Sets the default source for all resource types to the same origin.
  • script-src 'self': Allows scripts to be loaded from the same origin ('self') .
  • style-src 'self': Allows stylesheets to be loaded from the same origin ('self').
  • object-src 'self': Allows embedded objects to be loaded only from the same origin ('self').

So, I followed the advice and added the suggested code to my “functions.php” file in my child theme, using the Astra Theme. After saving the file, I cleared the entire cache using the LiteSpeed Cache Plugin. Excitedly, I reloaded my website, hoping to see the annoying message gone. And indeed, the message was nowhere to be found! But to my dismay, I noticed that most of my images were also missing. Oh no!

So before I started debugging the issue, I reverted my website back to before the changes. Next I took the following steps to address the issue:

  1. Review Your Content Security Policy: Check the CSP directives you added to your functions.php file. Ensure that the img-src directive allows images to be loaded from your domain. If it’s not specified, consider adding 'self' to allow images to be loaded from your own domain.
  2. Check for CSP Violations: Use the developer tools in your web browser to check for any CSP violations. This will help you identify if the CSP is indeed blocking the loading of images and which directives are causing the issue.
  3. Adjust CSP Directives: If you find that the CSP is blocking images, adjust the directives accordingly to allow images to be loaded from your domain while still maintaining security.
  4. Test and Iterate: After making changes to your CSP directives, be sure to test your website thoroughly to ensure that images are loading correctly and that the CSP isn’t causing any other issues.
  5. Consider Using a Content Security Policy Reporting Endpoint: Implementing a CSP reporting endpoint can help you monitor and troubleshoot any CSP violations that occur on your website. This allows you to receive reports when the CSP is violated, helping you identify and address any issues more effectively.

After spending about 30 or 40 minutes combing through my code and searching for any potential issues, I couldn’t find anything suspicious. Then it hit me: the Gutenberg blocks I was using had images with relative paths, and those were the ones missing. After doing a bit more digging, I discovered that my changes were indeed blocking images with relative paths.

To resolve the issue, I simply added ‘unsafe-inline’ to the directive, and voila! All of my images started to show up perfectly fine. So the new code looked like:

// Add custom meta tags to the header
    function add_custom_meta_tags() {
        ?>

        <meta http-equiv="Content-Security-Policy" content="default-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline'; style-src 'self' 'unsafe-inline'; object-src 'self' 'unsafe-inline'">
    
        <?php
    }
    add_action('wp_head', 'add_custom_meta_tags');

However, every action comes with a reaction. I realized that including ‘unsafe-inline’ in your CSP allows inline styles and scripts, which can potentially introduce security risks if misused. It’s worth considering other methods like nonce or hash to mitigate these risks if possible.

Scroll to Top