Main

April 14, 2009

Should AIR Support Application Installs Without Admin Rights?

In my previous post, I explained that installing an AIR application sometimes requires admin rights. This begs the question: Should AIR take pains to avoid those parts of application install that sometimes require admin rights? Some applications do support this, including recently Google Chrome.

We considered this when designing the AIR install experience and ultimately decided this would be a mis-feature. It breaks down to two cases:


  1. You're the admin for the machine on which you're installing software. (This is the typical consumer scenario.) You don't need to install without admin rights because you've got them.
  2. You're not the admin, and you don't have admin rights. You want a non-admin-rights install because otherwise you can't install the application. (This is a typical enterprise scenario.)

In this second case, however, your machine is locked down for a reason: the admin doesn't want you to install anything. If they knew you were avoiding this restriction by installing without admin rights, they'd probably close that loophole, too. See, for example, this article about stopping users from installing Google Chrome.

So any specific support in AIR for installing applications without admin rights would be temporary at best, as admins could still prevent it. Worse, it makes extra works for admins who have to jump through hoops to keep their machines locked down. Since we're interested in making sure AIR stays friendly for enterprise deployments, and this feature has no value for non-enterprises, well, it just doesn't seem to make much sense.


April 8, 2009

Does Installing an AIR Application Require Admin Rights?

Today I was asked not once but twice about whether or not installing an AIR application requires admin rights. If that's not a sign that the topic needs some explanation, I don't know what is.

Surprisingly, it's not a yes or no question. The problem is that you have to know what you mean by admin rights, which may not be as easy to know as you'd think it should be.

A more satisfactory answer can be had by coming at the problem the other way around: Which rights are required to install an AIR application?

In general, there are two requirements: You must have rights to write to the install location on disk, and you must have rights to update any other system state that's modified as part of the install—i.e., the registry on Windows.

The first item, install location, depends in part on the selected location. AIR defaults to a machine-wide location, which may or may not have restricted permissions. If you can't install there, you can certainly try installing elsewhere, such as in your own user folder. You're more likely to have rights to do that, although it's still not guaranteed.

On Windows, however, the registry entries created as part of the application install are always written to the machine-wide portion of the registry. If you don't have write access to c:\Program Files you probably don't have the necessary write access to the registry, either, and so you'll find that choose an alternate install location won't be sufficient to make things work. And no, there's no way to avoid writing these keys.

Mac OS is much friendlier in this regard: not only does it define ~/Applications as the per-user install location, but it requires nothing but write access to install an application.

So, does installing an AIR application require admin rights? Not always—but sometimes it does.

December 5, 2008

Changes to HTMLLoader.loadString() in AIR 1.5

For AIR applications bound to version 1.5 and later, the default behavior of the method HTMLLoader.loadString() has changed. This may impact your application; here's the how and why of the change. (For Flex users, the following discussion also applies to setting the HTML.htmlText property.)

AIR applications are desktop applications and, consistent with that fact, AIR does not prevent you from doing dangerous things like fetching remote content and running it locally. However, it's rare that such things are desirable and, when they are, they should be done explicitly and carefully. AIR APIs are therefore generally designed to make doing safe things easy and dangerous things hard.

Prior to the AIR 1.5 behavior, HTML content loaded via HTMLLoader.loadString() was placed in the application sandbox. This content has full access to the local machine. Whether or not this is reasonable depends on where you get the string that you load from and what that string contains. Since it's easy for that string to come from untrusted sources, this provides an easy path for injecting untrusted code into your application.

To address this, starting in AIR 1.5, loadString() defaults to loading content into the browser sandbox. This is the safe thing to do since untrusted code, when running in the browser sandbox, is unable to operate with the same permissions as are otherwise granted to your application.

If you want the old behavior, you can set HTMLLoader.placeLoadStringContentInApplicationSandbox = true. If you do this, remember that you are taking on responsibility for dynamically loading code into the application sandbox and all of the risks that entails. Ethan Malasky's blog has some great posts in this area. Still, I don't generally recommend it—it's hard to get right.

One final note: This change will not break your existing applications. The new behavior is bound to the namespace used in your application descriptor file. Applications using the 1.0 or 1.1 namespaces will operate as before. You will have to take this change into account when you update to the 1.5 (or later) namespace.

September 30, 2008

Why AIR Applications Auto-Exit on Mac OS

A user on the Adobe AIR forums recently requested that we change the default behavior of AIR applications running on Mac OS so that they don't exit when the last window is closed. This changed behavior would, of course, be consistent with the majority of Mac OS applications.

Contrary to what you might suspect, the current behavior was not an oversight on our part; nor was it a result of porting a Windows design to Mac OS. (We have several individuals on our team with significant Mac OS experience and I assure you they wouldn't stand for that kind of thing.)

The decision makes more sense if you think about it in light of some observations about actual AIR application development:


  • Although the default behavior of Windows applications is to exit when all windows are closed, many developers want to write Windows applications that keep running in this case.
  • Although the default behavior of Mac OS applications is to keep running when all windows are closed, many developers want to write Mac OS applications that exit in this case.
  • An application running without windows open is often a stumbling block for developers coming up to speed on the platform because, when they try to launch the application again, nothing happens by default.

From this one can, I claim, reasonably conclude that defaulting to platform-specific behavior in this case is not worthwhile: most applications either want to keep running on all platforms or exit on all platforms. Second, to ease that developer stumbling block, the default had better be to exit. Thus, NativeApplication.autoExit defaults to "true" on Mac OS, Windows, and Linux.

Any chance we'll change this in a future release? Not likely. Although patterns of development change, to insure forward compatibility we'd have to keep the current behavior for old applications and introduce the new behavior only for new applications. Even just the switch would introduce yet another thing for developers to learn—and another potential stumbling block. In practice the cost of changing an API's behavior is quite high, and I don't think this change would make the cut.

June 18, 2008

AIR API Tip: Don't write to File.applicationDirectory

As a number of AIR developers have discovered, it's hard—but not impossible—to write files in the application's install directory. That's the same location given by File.applicationDirectory.

Granted, it's often a tempting thing to do. For example, many applications include a database or configuration file with some pre-filled data. Once installed, they often want to update that file, say with user-specific data or preferences.

The first problem with this is that it's not reliable. On some operating systems—Vista, for example—the installation directory is protected by the operating system. Even if AIR lets you write to this location Vista won't. So if you want to write portable applications, don't do this.

The second problem with this is that it's not safe. Any code written into this directory runs with application privilege, which can compromise your application, which can compromise the user's machine. That's why Vista protects these directories.

The third problem is that it invalidates your application's signature. Among other things, that means you won't have access to the encrypted local store any more.

It's also unnecessary. A safe and allowable alternative is to write somewhere into the user's directory. If you still want a starter file, it's easy to copy one from your install directory to the per-user location. Note that this also avoid problems if there are multiple users on the same machine.

In order to help developers avoid this pattern, AIR will prevent write access to this directory in most cases, and even when the underlying operating system allows it. There are currently ways around this, as it's advisory—not mandatory. However, the ability to go around this restriction is often misinterpreted as a defect, and we may close this off in a future release. You've been warned.

May 20, 2008

Why AIR Doesn't Ask for Permission

Commenter Tek suggests that AIR should warn the user each time an application tries to do something potentially dangerous, like access the file system.

Here's just a few reasons why we don't do this:

  • It's annoying. No one likes to deal with these dialogs all the time. And if everyone just suppresses them, then what's the point?

  • It's insufficient. Accessing the file system alone or the network alone is often ok, but approving the combination is sufficient to let someone upload all your data.

  • It's unanswerable. Unless you wrote the application or studied its source code, you probably don't have enough information to answer, anyway.

  • It's broken. If you say no to any of these dialogs, the application will most likely stop working.

Ultimately, choosing to run a desktop application is about trust. Virus scanners, firewalls, and the like don't ask you about what applications are doing because they're trying to protect you from those applications. On the contrary, they're notifying you about behavior that might be the result of software you didn't install. That's an altogether different question: if you didn't install the software, say no!


May 11, 2008

AIR's Unrestricted System Access Warning

[Update 2009-07-30: This dialog has been revised for AIR 1.5.2.]

If you've ever installed an Adobe AIR-based application--you have installed one, right?--then you've probably noticed the installation screen warning that the application you're installing will have unrestricted system access. I'm frequently asked by developers how they can get rid of this warning, lest it scare off some of their customers. The short answer: you can't.

When we developed the installation screens for AIR, one of our major goals was to make sure they were informative. Installing an application on your machine is a big deal. You're trusting code that someone else wrote to not steal or destroy your information. If you're going to do this, you ought to be well-informed regarding what you're installing and what risk you're taking.

The "unrestricted system access" warning is there to make sure you know that, once you install this application, you're trusting it to behave. No one else is going to keep an eye on it for you.

Some future release of AIR might offer to perform this function for you--that is, restrict the system access of certain applications. With that capability, you might make different decisions about which applications to install. But that's all theoretical for now. Right now, all application are unrestricted. Even if they don't need to, say, access the filesystem, they still can. So that warning shows up every time.

How do you know, then, which applications to trust? I recommend making that decision based on the publisher's identity--the other major piece of information on that first installations screen.

April 4, 2008

The AIR Browser API and User Events

The AIR browser API lets web applications detect, install, and launch AIR applications. There are some restrictions on its use, however:


  • Applications have to opt-in to the detect and launch capability. This is done by specifying <allowsBrowserInvocation> in the application's descriptor.
  • Installing and launching applications can only be performed in the context of a user event

"In the context of a user event" means that the method is called during an event handler for some event, such as a mouse click, that's initiated by a user action, such as clicking on a button. Note that this doesn't mean all mouse events qualify, as they can also be dispatched programmatically.

Why this restriction? To protect the user against malicious (or just really annoying) web pages. WIthout this restriction, pages could install and launch applications as soon as the page is loaded, over and over again, until you give up in disgust and quit using the Internet.

This restriction occasionally trips people up when using the browser API because it's tempting to wait for a user event, then call getApplicationVersion() to determine whether or not the application is installed, and finally call installApplication() or launchApplication(). But this won't work because the getApplicationVersion() call is asynchronous; when the specified callback function executes, the code is no longer part of the original user event.

Note that getApplicationVersion(), however, need not be called during a user event. The trick, then, is to call this method right away, when your web page loads. By the time the user clicks on the button, you'll already know whether you need to install or launch and can do either immediately within the context of the user event.

One final note: consider calling getApplicationVersion() periodically from a Timer. That way, if the application install state does change while the page is open, subsequent clicks on that button will continue to do the right thing.

November 29, 2007

Version Numbers and the Updater API

AIR applications can update themselves via the Updater API. It's straightforward to use: you just provide an AIR file containing the new version of your application and the version number you're upgrading to. Downloading the AIR file and displaying any appropriate UI is left to the application.

When we designed this API, I thought we'd get a lot of questions about why the version number had to be provided. After all, the version was itself embedded in the AIR file. Surely we could just grab the version number from there, right?

Disappointingly, few have asked.

Disappointing because that argument exists to help you protect your application from downgrade attacks. Downgrade attacks work like this: some earlier version of your application has a vulnerability, but has since been patched. The attacker tricks your update mechanism into using the Update API to install that old version, thus re-introducing the vulnerability. Then they attack the vulnerability.

To protect against this attack, the application must validate before it begins the update that the version it's updating to is, in fact, a newer version. During the update process itself, AIR will validate that the version number you've validated and passed to the update call does in fact match the version in the AIR file. If they don't match exactly, the update will fail.

Why doesn't AIR check that the version is newer? Because we didn't want to impose a version numbering scheme on anyone.

November 27, 2007

Parameterized Application Install

I've been asked a couple of times if it's possible to parameterize the application identifier, etc. for an AIR-based application during the installation process. The scenario is usually something like this: A developer has created an application that they publish through different vendors. Each vendor stamps some unique branding, etc. on the application but the underlying code is the same. The developer doesn't want to produce a different AIR file for each vendor. Instead, they'd like to parameterize things like the application identifier, application name, logo, etc. during the installation process.

The problem with this is that it's directly at odds with secure delivery of the applications. Secure delivery is designed to establish the trusted identity of the publisher of each application via digital signatures. If any part of the application can be changed at install time then it's (by definition) not covered by that signature, and we can no longer establish the authenticity of the application. Maybe you got assigned a correct parameter, or maybe you got a malicious one that will open you to an attack. How do you know?

In these scenarios it's the vendor, not the developer, who is actually publishing the application. They're the ones who should be signing the application; this will insure that it's their name that appears during application install. And of course they should only be signing it after any re-branding, etc. has been applied.

Too much work for the developer? It shouldn't be. Packaging can be fully automated via the adt tool provided for free in the SDK. Create a script that uses it to produce all of your unsigned, parameterized, intermediate AIR (.airi) files. Hand this file off to your vendor and have them sign it, again using adt, to produce the final AIR file for distribution. Voila.