Erik Romijn

Why and how I get 100% test coverage for my Django projects, and you should too

Automated testing has become axiomatic in the Python community. The Django tutorial, for example, explains testing Django projects before even explaining how to deal with CSS. A common measurement for tests is test coverage: the percentage of lines, branches or files of the code that are executed when the tests are run. How high this number should be is a frequently debated subject, but general consensus is to aim for 90-95%, with 100% being utopian unrealistic and not worth the time it may take. Some don’t care about test coverage at all, because high test coverage doesn’t guarantee the tests are any good.

"100% test coverage by @bloerwald"

For my own projects, I’ve adopted a new rule: all code must have 100% test coverage. I am not done done until the unit tests have 100% coverage. How is this not utopian, unrealistic, and a waste of time? Because I count test coverage after exclusions. Although even that won’t help you to catch every scenario.

Read on →

Secure Django: security reviews for your Django projects

In the last few years, I’ve aimed to make security more accessible, understandable, and less scary for ordinary developers. I mostly focus on Python/Django and iOS. In 2012, I spoke about Django security at Djangocon EU. I wrote Erik’s Pony Checkup to help developers get quick and free basic checkups. Lately, I’ve been writing about security, ranging from the intricacies of cookie domains to a basic guide on when and how to deploy HTTPS. The latter made #1 on HackerNews some time ago, and I hope it helped many to improve their configuration.

Today, it’s time for the next step: I am launching Secure Django, where I’ll be offering in-depth security reviews for your Django projects. You’ll get your projects reviewed with specific Django expertise, with results that are understandable and actionable for any developer. And all with clear advance pricing.
Erik’s Pony Checkup will remain as it is, free and open source.

Perhaps it seems an odd choice to focus on security reviews for Django projects. Isn’t Django secure by default? Doesn’t Django protect developers from XSS, CSRF, SQL injection, clickjacking, session fixation, and many more issues? Yes, Django offers well designed protection methods for these issues. And, Django definitely makes it easy to write secure web applications.

However, Django can’t foresee everything. Are you vulnerable to the heartbleed bug? Are you enforcing SSL correctly? Did you set the proper flags for your cookies? Did you remember to disable weak ciphers? How are you managing your secret keys? Are you sure you authorise users correctly? Are you generating a bit of HTML in your view, and using mark_safe to make sure it does not get auto-escaped? In general, that’s a good approach, but you could also be introducing an XSS vulnerability. Is the Django ORM not powerful enough for a query, and you use raw() to write your own SQL? Not at all uncommon, but you could be introducing a SQL injection.

In other words, Django provides an excellent start, preventing many of the basic mistakes in security. But with the requirements of modern web applications, the fact that you’re using Django does not guarantee safety by itself. Would you like to know more about the security of your project? Set up your Secure Django review today. See an example first? Have a look at the sample report.

Needless to say, the Secure Django site itself meets all recommendations I might make. Do you think you found a vulnerability anyways? See the responsible disclosure policy.

Phishing out iOS URL schemes

In iOS, there are limited options to communicate with other apps. One of the most common choices is custom URL schemes. Like Safari picking up most links beginning with http:// or https:// (http(s) being the URL scheme in that case), opening a URL with the facetime scheme starts a FaceTime call.

Many third party apps that want to offer integration into their app do this with URL schemes. There are several lists of apps and their URL schemes. Using URL schemes is a good choice. It’s officially supported, and it’s trivial to integrate into an app. If I would want to open the Schiphol Airport venue in the Foursquare app, I would do:

UIApplication *app = [UIApplication sharedApplication];
NSString *path = @"foursquare://venues/4a84e798f964a520defd1fe3";
NSURL *url = [NSURL URLWithString:path];
[app openURL:url];

URL schemes are just like normal links, so you can also include them in a website. If you have Foursquare installed and are reading from iOS, this link should open the app, showing Schiphol Airport.

As a developer, it’s simple to register a URL scheme as well. There is no registration required with Apple. All you have to do is declare it in your Info.plist:

Now, hold on there: I’m not actually the maintainer of the foursquare app. What happens when both their app and mine claim to respond to foursquare://, and both are installed on a user’s device? Apple writes:

Read on →

A plea for open personal data

I wrote an article on (in Dutch), on opening up personal data. In the last few years, the available open data in the Netherlands has grown tremendously. But, in accordance with the law, datasets containing personal data are excluded from this.

However, this means we miss out on many opportunities for reuse of personal data. It’s time to start working on open personal data. Not open to everyone, but open only to the owner of the data: the person the data is about. And for them, and only them, to distribute to those they choose, real-time and computer readable.

Read my full article on, in Dutch.

The definitive guide to cookie domains and why a www-prefix makes your website safer

Restricting access to cookies is essential for security in many web apps. For example, the session ID, the secret token used to identify a particular session, is typically stored in a cookie. Cookies have several important settings. Previously, I discussed the secure flag. This time, let’s dive into the cookie domain.

The cookie domain is an important security feature, probably even more important than the secure flag. It tells the browser that this cookie must only be sent to matching domains. Matching however, can happen in several ways. Perhaps domain is a bit of a misnomer: this can be any host name, like

With this in mind, I did some digging into the exact workings of cookie domains, and was surprised to find this less straight forward than I had expected. And, it turns out Internet Explorer’s RFC-incompliant behaviour makes it safer to host your websites with a www-prefix, so instead of

Update: this post was updated on April 9, 2014, to reflect that Internet Explorer misbehaves with domain-less cookies, as learned from this blog post. Previously, I concluded that a www-prefix makes no difference, with this new knowledge, a www-prefix is safer.

Read on →

Why your certificate authority rarely matters, and expensive certificates are not safer

When you deploy HTTPS, you’ll typically need to get an SSL certificate signed by a commonly trusted certificate authority. Certificates and authorities come at many different pricing levels with many different validation depths. A common misconception is that more expensive certificates provide better security. In reality, your choice of vendor rarely matters, and more expensive certificates do not make your website safer.

Read on →

Appsterdam lecture: chips: the engine beneath your apps

This Appsterdam lunchtime lecture was on Chips: the engine beneath your apps, by Marco Jacobs

This was a live summary and has not been reviewed by the speakers. Opinions reflected are the speakers’, not necessarily matching those of the author.

Chips: the engine beneath your apps

Marco has a software background, but has been working in silicon chips for many years. He shows a disassembled Nexus 5, showing plastic casing, PCBs, optics, battery, and so on, but most importantly, the chips.

A brief history of chips

The first transistor made by Bell Labs in 1947, was rather large. About ten years later, someone at Texas Instruments built the first integrated circuit prototype. They are now rather smaller, but still based on the same technique.

Read on →

Cocoaheads January 2014 meetup summary

The CocoaHeads Amsterdam January 2014 meeting was hosted by WappZapp, in Amsterdam. There were two speakers, talking about Appcelerator Titanium and CocoaPods.

This was a live summary and has not been reviewed by the speakers. Opinions reflected are the speakers’, not necessarily matching those of the author.

Wienke Giezeman: Building native apps with Javascript

Wienke works for WappZapp. WappZapp is a video discovery app that gathers video from many sources on the internet and provides them to users in a curated way. WappZapp builds it’s apps in Appcelerator Titanium. They chose for this both for their initial development, and for the rewrite after their funding round last year.

Read on →

But where is the decryption key?

Encrypting sensitive data is usually a good practice. You’ll see many organisations, like Dropbox, advertise this as part of their offering:

Or Apple iCloud:

This means that your data is protected from unauthorized access … when it is stored in the cloud. iCloud uses a minimum of 128-bit AES encryption …

Using strong AES for this situation is a good choice. There are some other technical details to be considered, like the block cipher mode. However, a more fundamental question is missing. The technology used, be it AES or DES, is only half the story when we wonder about the security of data. The other important question is: where is the decryption key?

The nature of encryption of data means there is always someone or something holding the decryption key. If nobody has the key, nobody can decrypt it. And to someone with the decryption key, the encryption method is largely irrelevant, as with the key, the data can be effortlessly decrypted.

Read on →

Watch that cache: Dropbox and Evernote insufficiently protecting iOS 6 user’s data

With the ever increasing ways to use our mobile devices in daily life, they also collect increasing amounts of sensitive personal data. Being mobile, these devices are easily misplaced or stolen. That makes it essential to protect the data stored on the device.

For iOS developers, Apple offers the Data Protection API (for files and databases) and Keychain (for keys and small data, like passwords). With these simple APIs, access to data can be tied to the device passcode. Although this is certainly not impenetrable, it adds a substantial obstacle at virtually no cost for the app developer.

A while ago, I took a look at the data storage security in two commonly used apps for iOS: Dropbox and Evernote. I tested them on iOS 6, as I required a jailbroken device to get reliable information. As one would expect, these apps get many basics right: passwords and keys, for example, are stored in the Keychain, where they belong. However, they’ve failed to apply data protection to their caches.

This means that a significant portion of my Dropbox files and Evernote notes are available to anyone who acquires physical access to my device for an hour or so, regardless of any passcodes I might have set, if I am running iOS 6, as 15-20% of users still are. The issue could be prevented with a few lines of code. Evernote has confirmed they will not resolve this, and Dropbox has stopped replying to me.

Update: I have verified that on iOS 7, this issue has been resolved, as the default data protection settings in the OS have changed.

Update 2: On January 14, I received a message from Dropbox, thanking me for my report and offering a 100GB account quota, and a t-shirt.

Read on →