Erik Romijn

Vulnerability in Apple portal compromised iOS keychain access groups

When writing web applications, we make use of the many features of browsers to improve the experience, like javascript validation. But convenient as they may be, we can never ever rely on these features when it comes to protecting the data of other users. The browser is entirely controlled by a potentially malicious user, which means that whatever the browser does, our systems should be designed not to allow harm to any other user. The browser is not your friend.

A little while ago, I discovered a vulnerability in the Apple provisioning portal, where developers register App IDs and provisioning profiles. The portal made the mistaken assumption that it could rely on the browser. The impact was that any developer could submit an app that would be able to read the Keychain entries created by another app if the other app used Keychain access groups, a commonly used and widely recommended feature.

The end result is that it allowed any iOS developer to create an app that passes App Store validation and could read the secrets stored by specific third-party apps, such as Dropbox, PayPal or the Google Authenticator. I first noticed this vulnerability was fixed on October 10, 2014, over one year after my initial report to Apple.

Read on →

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 hackdeoverheid.nl (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 hackdeoverheid.nl, 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 foobar.erik.io.

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 www.erik.io instead of erik.io.

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 →