How Not To Whitelist

I started using Fluid for site-specific browsers on my Mac. As the name implies, Fluid SSBs only allow you to visit pages on a single site, but allows you to extend the site with your own scripts and stylesheets to integrate web apps into Mac OS X, effectively transforming them into desktop applications. For instance, I have a SSB for Campfire with a script that updates the dock badge whenever a new message is received, and puts up a Growl notification when my name is mentioned.

I should note that I’m trying out SSBs after reading up a bit about the security benefits they may or may not provide. The thought is that if your browser can’t be redirected to a malicious site, then it will be harder to pass your credentials to an attacker. Combined with Choosy (which I haven’t tried yet), SSBs may be a large step towards preventing account theft through cross-site scripting and request forgery attacks.

Unfortunately, after spending a few minutes with Fluid’s whitelisting I determined that it won’t do any good in it’s current state. I’ll illustrate with an SSB for viewing Apple’s website:

fluid-create

Above shows the UI for generating a SSB; it’s fairly self-explanatory. Clicking “Create” generates a new application bundle on my desktop, which launches and takes me to Apple.com. Now let’s look at the whitelist Fluid set up for me:

fluid-filter

As you can see, it converted my original URL of http://www.apple.com to a whitelist pattern of the form *apple.com*, where asterisks represent wildcards. This is to allow me to visit any subdomain (e.g., support.apple.com) and any file (e.g., apple.com/macosx/), rather than limit me to just the homepage.

The problem with this approach is that it’s too general; the whitelist permits too much. Not only can I get to http://www.apple.com/, but I can get to http://www.snapple.com/ as well. An attacker could buy up any that ends with apple.com and Fluid would happily load it.

You may have guessed that this particular whitelist pattern has other deficiencies. The following URLs all work as well:

  • http://www.microsoft.com/#apple.com
  • http://apple.com.example.com/
  • http://apple.com@rgov.org/

In each of the above examples, I’m not limited to just domains ending with apple.com, but I can in fact load any page on any domain I choose, as long as it includes the whitelisted string somewhere within it.

Now that we’ve demonstrated that the default whitelist setting is flawed, what’s a better whitelist? I propose this:

  • http://*.apple.com/*
  • https://*.apple.com/*
  • http://apple.com/*
  • https://apple.com/*

It allows only hosts which are proper subdomains of apple.com. (It’s important to include the / after the hostname, or else the last two example bypass URLs I gave would still work.)

Unfortunately, one would be wrong to assume that when you set up the whitelist as above, you can no longer access any URL not owned by Apple. It seems that Fluid has a few implicit whitelists to allow certain features. The two that I’ve found so far are *userscripts.org and www.google.com*www.apple.com*. As with our original pattern, these aren’t adequate for proper filtering, and from what I can tell there’s no way of disabling them.

I’ll keep using Fluid for the time being, but I have no illusions that it’s doing anything to keep me particularly safe.


Discuss on Ryan's Blog


App Store Rejections, where's the line?

Gruber summarized the rejection of the Commodore 64 emulator as:

Looks like an awesome app — a working C64 emulator with a gorgeous UI.

But while I hope this gets worked out and allowed into the store (I’d buy it in a heartbeat), it should not be considered a bogus/outrageous/controversial rejection. The rejection notice cites sections of the SDK guidelines (forbidding code emulators) which the app clearly violates.

While I agree that this app clearly violates that clause, I think we're crossing an interesting line with iPhone OS 3.0 with in-app purchases. The most common example is most likely going to prove to be "levels" for games -- race tracks, new RPG dungeons, etc.

I can't speak for all game engines, but in a few engines I've used in the past, logic can be built into the levels themselves. For example, an RPG dungeon might require you to push a block onto a switch before a door is unlocked.

Code Interpretation

Interpreting code is often a vague term, so I want to define it as the steps required:

  1. Parse input: Scan "code" to determine its structure and order
  2. Make decisions based on input: Based on the structure, perform the actions indicated

Now I posit that there are already clear-cut violations of this agreement (assuming Apple abided by their own agreement) if taken absolutely literally. What are they?

  • Safari: Downloads, parses, and interprets (compiles in 3.0, from my understanding) Javascript code.
  • Calendar: Parses CalDAV "commands" as to delete, insert, or update your calendar items. Think it's a stretch? I almost guarantee you that this code is written using a state machine with the equivalent of a switch statement.
  • Calculator: You may think this is a stretch, but think about it: what's the first compiler or interpreter anyone ever writes? RPN calculator. In case you aren't familiar, a calculator is a classic example of parsing structured input (order of operations) and performing the operations specified by the input.
  • MIDI players: These little musical machines are state machines that know several commands, like how to switch between instruments, how loud to play a pitch, and when to stop a pitch.
  • Terminal/Shell Applications: Seriously, you're bring up a shell prompt which by their definition execute commands that you type in.

The key here is that with Safari, Apple cannot abide by their own agreement.

Clearly, all third party browsers should be banned if they don't disable Javascript. All terminal applications should be banned.

By not having a clear definition of what defines "code," the agreement puts all applications that download or take user input, parse it, and do something special based on it. That's all a programming language does -- it takes input, parses it, and does something based on that input. Thus nearly any program that parses a file and does something interesting with it should be banned.

How can levels be viewed as interpreting code?

As I mentioned before, logic can be built into the levels themselves that the host application is blissfully unaware of. This actually is another classification I would use to call something an interpreter or compiler: the application loads up unknown input, parses it, and performs actions based on the context of when the input was loaded.

Now we can get into semantics, but remember that code isn't always imperative. There's a whole world that can be called declarative programming. A common example of declarative programming is HTML. The author of HTML declares the content, and the browser must make sense of the content and display it. However, the HTML author is blissfully unaware of how it happens.

This perfectly describes an add-on level. The level declares what it will contain. The program knows how to parse this declarative model of a level, and thus it interprets it and runs the level.

What's the point

Most people would assume that Apple has this clause for security: you don't want programs to download code that would break your phone. However, I think this clause is actually more malicious than protective. I'm going out on a limb to accuse Apple of putting this clause in here to prevent Adobe from creating a stand-alone Flash player.

With this in mind, it makes perfect sense why this would be disallowed. But think about what we're missing out on (naming a couple off the top of my head):

  • LOGO app: The ability to teach kids how to program using a simple language like LOGO.
  • Mindstorms app: Think about the possibility of programming LEGO Mindstorms on an iPhone.

I really feel that the code execution/interpretation clause is hurting the iPhone more than it's helping. There is a minimal security risk, but there's already the same security risk with Javascript and media playing. Beyond that, if any bug in a programmers code can exploit the phone, the kernel and sandboxing aren't doing their job already.

This really boils down to the language of the agreement. The agreement is too open to interpretation that it's rendered useless. Apple needs to either get very specific in its definitions, or it needs to remove the clauses. There is nothing to be gained from pissing off developers. There is everything to gain from being the company who provides products that everyone loves developing for. Be that company, Apple.


Discuss on Jonathan's Blog


The New Alacatia Labs

We've relaunched a simplified site that we're going to integrate each of our individual blogs together, as well as post unique content here for all to read.

We're still getting situated here, and we will be open sourcing CalendarKit shortly here. Stay tuned.


Discuss