Content Security Policy is hard, and then there’s Pinterest and AddThis

Over the past month, I’ve embarked on an update of my blogging sites to make them secure. All told, I maintain three, all using GraffitiCMS as the backend: this site, 64SAINT.com, and my wife’s crafting site.

This site? Well, yes, it’s going to be a complete bear to do, mainly because it’s in two parts: the current GraffitiCMS blog (which you’re reading now, hosted on blog.boyet.com) and my old static blog site (hosted on www.boyet.com). I’m still unsure as to how I’m going to do this, or even how it is going to pan out, so I first concentrated on the other two.

When I set up my wife’s site, I made sure it was hosted on Azure, the other two being hosted on GoDaddy. Because of that decision, the basic update to using HTTPS via an SSL certificate was, I’d have to say, pretty damn simple. I’ve written about the process here and here with regard to static websites. However, for my wife’s site, catering for CSP (Content Security Policy) was such a bear, I put it aside for a week.

The biggest pain by far was her requirement for the ability of visitors to her site to click on a simple button on a blog post to share it on Pinterest, or Facebook, or even Twitter. Sounds simple enough, and Pinterest (to name but one) has a bit of JavaScript you can include in the page to do it. Except that blob of JavaScript is hosted on Pinterest’s site, it does some frankly weird things when it runs, and then even uses a base64 image for the Pinterest logo. All of which triggered CSP like crazy. And then there was the whole AddThis add-in for exposing icons to share posts to other social sites. And that bit of JavaScript even uses eval() FFS, as well as a sh*t-load of assets across (count ’em) four subdomains.

Making CSP happy was redolent of writing unit tests for code. You write a bit of code, write a test, get it to pass, then it’s on to the next bit of code. I found that getting CSP to work with these external JavaScript files was a cycle of load a page in the browser, check the console in the browser’s developer tools, copy the new domains that had triggered a CSP warning to the web.config file, FTP that updated file to the site, refresh the page. Eventually, this is the CSP rule I’d configured in web.config for her site:

        <rule name="CSP">
          <match serverVariable="RESPONSE_Content-Security-Policy" pattern=".*" />
          <action type="Rewrite" value="
            default-src 'self' https://assets.pinterest.com https://s7.addthis.com https://m.addthis.com; 
            script-src 'self' https://code.jquery.com 
                https://s7.addthis.com https://m.addthisedge.com https://m.addthis.com https://api-public.addthis.com
                https://log.pinterest.com https://assets.pinterest.com 'unsafe-inline' 'unsafe-eval'; 
            img-src 'self' https://www.gravatar.com https://log.pinterest.com data:; 
            style-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.googleapis.com 
                'unsafe-inline'; 
            font-src 'self' https://maxcdn.bootstrapcdn.com https://fonts.gstatic.com;" />
        </rule>

Now, yes, I’ll totally agree that the unsafe directives annoy the crap out of me, but, to be honest, there’s not a lot I can do about them, given that I’m using these add-ins. The data: reference is to allow the base64 Pinterest icon, and, in fact, as I discovered later, I could in fact replace all the absolute HTTPS domain names with a simple https: to make the whole thing easier to read (and to process).

The web.config for 64SAINT.com is much cleaner (and was quicker to create) since it doesn’t use these add-ins. The biggest issue there was, because of GoDaddy’s cost for an SSL certificate (plus the requirement for a much higher-price hosting plan to implement it), I decided to first move the site-plus-blogengine over to Azure, and then make it secure. The fun bit for that site was to add web.config rules to redirect the old blog.64saint.com references to plain old 64SAINT.com, and then also to remove GoDaddy’s need for a subfolder to hold an ASP.NET app (that one was called web, the one here is called blog).

      <rules>
        <rule name="Remove the old blog prefix">
          <match url="(.*)" ignoreCase="true" />
          <action type="Redirect" url="https://64saint.com/{R:1}" redirectType="Permanent" />
          <conditions>
            <add input="{HTTP_HOST}" pattern="^blog\.64saint\.com$" />
          </conditions>
        </rule>
        <rule name="Remove the old web folder">
          <match url="web/(.*)" ignoreCase="true" />
          <action type="Redirect" url="/{R:1}" redirectType="Permanent" />
        </rule>
      </rules>

(I will note here that the rule to remove the blog prefix is only there for completeness’ sake. For it to become active I shall have to get an SSL certificate for it. Maybe next month.)

With each CSP rule finally set, both sites get an A from securityheaders.com. The only reason for not getting the coveted A+ is those damn unsafe references. Oh well.

The other big thing about finally getting these two sites fully secure is that, oh my god, I should retire GraffitiCMS as my blogging engine. The “audience-facing” bit is fine, it’s the admin part that’s hopelessly hosed when it’s being used for an A-graded secure site. And unfortunately part of the admin side of the engine is a couple of DLLs that Telligent never open-sourced. Either I rewrite them (I know the output they produce, and it doesn’t have to look pretty since I’m the only one who’ll look at it), or I move to another blog engine entirely. My preference at the moment is Orchard Core. But for now, time to relax…

Locks on Bridge - banner

Loading similar posts...   Loading links to posts on similar topics...

No Responses

Feel free to add a comment...

Leave a response

Note: some MarkDown is allowed, but HTML is not. Expand to show what's available.

  •  Emphasize with italics: surround word with underscores _emphasis_
  •  Emphasize strongly: surround word with double-asterisks **strong**
  •  Link: surround text with square brackets, url with parentheses [text](url)
  •  Inline code: surround text with backticks `IEnumerable`
  •  Unordered list: start each line with an asterisk, space * an item
  •  Ordered list: start each line with a digit, period, space 1. an item
  •  Insert code block: start each line with four spaces
  •  Insert blockquote: start each line with right-angle-bracket, space > Now is the time...
Preview of response