Dec 10 2013

Using Content Security Policy From a <meta> tag

Here's an esoteric little discovery. You probably won't find yourself in this situation — but if you do, maybe I can save you hours of struggle.

Content Security Policy is a good thing for web security. If you're not familiar with CSP yet, here's a great introduction.

You can also use CSPs to disable browser features in situations where you don't have much control. I just found myself wanting to do that, to prevent javascript from executing in small, locally stored bits of HTML that need to be rendered inside a UIWebView in a native iOS app. There are other ways to solve that problem, but like me, you might find that you wish to avoid parsing and modifying the markup directly.

You'll find some advice on the web to disable JS by subclassing NSURLProtocol and adding the CSP header via the URL loading system. This approach has a big disadvantage: it forces you to use UIWebView's -loadRequest: method, which asynchronously begins the load on a background thread. WebKit rendering is always asynchronous, nothing you can do about that. But if you use -loadHTMLString:baseURL:, in practice you'll see much shorter delays before your content is fully rendered.

Luckily, it turns out there's another way to set the policy: use a meta tag. As of iOS 7.0, this tag will be respected:

<meta http-equiv="Content-Security-Policy" content="script-src none">

So prepend that to your markup and you should be set. I haven't tested, but suspect this will work in iOS 5.0 and later. (If you know for certain, let me know and I'll update this post).

There are a bunch of other policy directives. Maybe there are other interesting ways to modify content rendering. If you find one, I'd be interested in hearing about it.