Security in Longhorn: Focus on Least Privilege
2003 Professional Developers Conference (PDC) "Longhorn" preview build
Summary: Longhorn promises to be a great platform for least-privilege applications. Get started today by writing managed code, first of all. When building desktop applications, make them LUA-compliant (and use the Windows Application Verifier to help check your work). (11 printed pages)
Application and Deployment Manifests
LUA: Least Privilege User Account
The (Deprecated) Power Users Group
AIM: Application Impact Management
PA: Protected Administrator
Managed Applications on Longhorn
The "No Risk" Permission Set
I have long been an advocate of running with least privilege. Many who know me have heard my rant that developers should quit running with administrative privileges while they are developing code, if only to help encourage more applications to be written to run in least-privilege environments. So I was very happy to hear at the 2003 Microsoft Professional Developers Conference (PDC) that one of the main goals of the next version of the Windows® operating system, code-named "Longhorn," is to make it easier for users to run with least privilege.
When you buy a copy of Microsoft Windows XP® Professional at your local software shop and install it on a PC, the setup wizard creates accounts for you and anyone else who will use the computer. After Windows XP boots, it displays a pretty welcome screen that shows each user's name and allows them to log in. Each of these users is by default an administrator of the machine. Why? Because the user experience would be poor if it weren't this way.
Users expect to be able to install software on their machines, but you can't install 90 percent of today's software unless you're an administrator. Users expect software to run without crashing, but 70 percent of software won't run properly unless the user is an administrator, and that's an optimistic number. Sadly, a large number of these applications fail in a non-administrative environment simply because they make poor choices about where to save application state. The Program Files directory is not intended as a place for storing state. It's a place for storing programs—executable files. The place to store application state is called the user profile, and for storing shared user state, the "All Users" profile suffices quite nicely. The Windows Logo Program guidelines explain this, but the vast majority of Windows software today was developed without consideration for Windows Logo guidelines.
But why, you might ask, should users want to run as non-administrators, especially home users? Well, if it were actually easy to do, the home user would reap loads of benefits. Malware (a virus, worm, or other malicious code) loves having administrative privileges. Surfing the Web or reading e-mail as an administrator is just plain dangerous these days. What about your kids? Wouldn't it be nice to allow them to install and play games on your home computer knowing that they won't accidentally break something, install spyware, or remove the content rating limitations you've imposed? Think about it this way: running as an administrator effectively turns off most of the security protections provided by Windows. Home and corporate users alike shouldn't be turning off these protections, especially when connected to the Internet, which has become a rather dangerous neighborhood.
Getting users and the programs they run to live happily in a least-privilege environment is going to significantly increase the security of the Windows platform.
One important feature that Longhorn introduces is the notion of application and deployment manifests. The former allows application developers to indicate the permissions their application requires to function properly, and the latter allows administrators to specify how much trust they place in the application. There's much more than this to these manifests, but I want to point out that they are available for use by both managed and unmanaged applications alike, and a large reason for their existence is to help users run applications with the least possible privilege.
To learn more about these manifests, take a look at Chapter 1 of Brent Rector's book Introducing "Longhorn" for Developers.
LUA, or Least-Privilege User Account, is an acronym I'm sure you'll see repeated over and over in Microsoft presentations from now on. The PDC 2003 presenters often pronounced the acronym as "looah." It's nothing fancy, not even anything really new. LUA refers to the practice of using non-privilege user accounts, both for interactive users and for services.
The Longhorn team wants to simplify security. They believe that there should be two levels of access to the system: least privilege, and administrative. They've even deprecated the Power Users group (referred to in some circles as "admin-lite") in Longhorn.
With the Power Users group gone, application developers really need to make a choice. They need to decide which of the two levels of privilege (LUA or administrative) their application needs for Longhorn. If the application doesn't need administrative privileges, then it should be carefully written to work under a least-privilege account. That means testing (and, one hopes, even writing the code) using normal user accounts. For example, a LUA application should write data files in a safe place, such as the user profile, as opposed to the Program Files directory tree. But what happens to applications that aren't rewritten for Longhorn? What if those applications don't run well under least-privilege accounts even on Windows XP? A Longhorn feature called Application Impact Management (AIM) might be able to help those apps run under LUA anyway, as you'll see shortly.
If you think of an administrative account having "high" access, and a normal user account having "low" access, a Power User account can be said to have "medium" access. The Power Users group is allowed to read and write parts of the file system and registry that are normally off-limits to least-privilege accounts (that is, normal user accounts that don't hold membership in privileged groups such as Administrators or Power Users). Many people who tried running as normal users found that so much software failed that they decided to add their accounts to the Power Users group, which fixed nearly all the problems they were having. But they weren't truly running with least privilege anymore. For example, on Windows XP, any malware that runs with this "medium" level of privilege will be allowed to compromise other applications stored in the Program Files directory, replace trusted COM components with Trojans, and so on. The next time the user runs under her administrative account on such a compromised machine, you can be sure that the malware will run as well through a previously installed Trojan. Therefore you are not getting any real protection running as a Power User.
The Longhorn team believes that running with least privilege is important. They want that pretty welcome screen to contain a list of user accounts that primarily consists of least-privilege accounts. But they also have their feet grounded in reality. Just as lots of major software today completely ignores the Windows Logo Program, much major software in the Longhorn timeframe may ignore the LUA initiative as well. Uninformed application developers will continue to write software that reads and writes data files from the Program Files directory tree. They will also continue to write registry data to HKEY_LOCAL_MACHINE instead of HKEY_CURRENT_USER. The former is off limits for writing by normal users, so the latter is preferable for storing application settings, if the registry must be used at all.
When Windows XP can detect that an application needs more privilege (this is rare, but happens occasionally with setup programs), it will inform the non-privileged user that the application requires administrative privileges to run, conveniently popping up a dialog to collect the user name and password of an admin account. The program then runs under the specified account. But this doesn't always work because many applications aren't written to be installed under one account and used under another.
Longhorn takes a completely different approach. Instead of encouraging the user to elevate privileges so the application can function properly, Longhorn prefers to run the application under LUA. But what happens when the application attempts to write to HKEY_LOCAL_MACHINE or the Program Files directory tree? Longhorn gives the application its own virtualized view of the resource it's attempting to change, using a copy-on-write strategy. When the application attempts to write to a file in the Program Files directory, Longhorn will give the application its own private copy of the file and it can party on. In this way, any malware that gets loose in an AIM scenario might try to overwrite a commonly used executable under the Program Files directory tree, perhaps WINWORD.EXE. But what it will end up overwriting is a private copy that only the malware can see. The version of WINWORD.EXE the user sees will still be the original, untainted version.
Don't rely on AIM to save you. Write your application to run under LUA from day one.
Even if every application were to be fixed in the Longhorn timeframe to run under LUA, there will still be applications that really do require administrative privileges. They include utilities such as backup software, hard drive defragmentation and repartitioning software, enterprise management software, and the list goes on. So at some point the user will need to use an administrative account to get certain work done. And let's face it, a lot of folks will ignore the advice to create LUA accounts and simply run as administrators all the time.
The Longhorn team has devised a neat scheme to help protect you when you're running under an administrative account. It's a feature called Protected Administrator, and when it's turned on, you can always run under an administrative account and feel reasonably safe, because the vast majority of applications that you run will be run with a special restricted token, a token similar to what you'd have in a LUA scenario. Only an application that you have "blessed," or that your company has deployed and designated as trusted, will run with your full administrative token. One way to designate an application as trusted is by signing its deployment manifest. Why is this useful? Let me give you an example.
A user who normally runs as an administrator opens her Longhorn e-mail client and starts browsing e-mail. She comes across a piece of mail that came from someone she knows, and opens an attachment. Little does she know that her friend was recently infected by an e-mail worm, and this message contains malware. When the malware runs, it finds that it has very little privilege on the system. It can't modify anything in the Program Files directory tree. It can't change COM object registrations under HKEY_LOCAL_MACHINE. This isn't to say it can't do anything bad, but the situation is a heck of a lot better than it would have been if the malware found itself running with administrative privileges.
But wait, didn't I say the user was running as an administrator when she ran the e-mail application? Yes, that was in fact the case. But the e-mail application was not designated as a "blessed" admin app; in fact it was written as a LUA application. Thus it received a restricted token, and so did the malware as a result. This is the whole point of least privilege. If you lose control of the system (perhaps because you accidentally ran some evil software, or perhaps because you just clicked the wrong menu item), the damage will be constrained or perhaps completely prevented.
Some security conscious administrators already implement this policy today. I'm one of them. I have two accounts, a normal one and an administrative one. I login as a normal user and occasionally switch to my administrative account when I need to administer my system in some way, for instance to add a virtual directory on my machine, create a database in Microsoft SQL™ Server, and so on. (In case you were wondering, I end up spending about 95 percent of my time running as a normal user, even when developing software.) The Longhorn team has formalized this approach, an idea often called "right privilege at the right time" in the Protected Administrator (PA for short) feature. This means I can just run as an admin all the time but still be running with least privilege. No more switching back and forth, juggling two user profiles, and so on.
If this sounds like a neat idea, and you want to help make it possible for people to actually use this feature, then you are going to need to get serious about writing applications that run with least privilege. Because if this feature is enabled, an application that requires more privilege than it really needs will break unnecessarily even if an administrator runs it, unless it's been designated as a trusted admin application. Of course, AIM might come to your rescue, but you shouldn't rely on it, because Microsoft is estimating that 20 percent of applications probably won't be able to be made LUA compatible through AIM. If you happen to fall in this 20 percent, your application will fail to run. If this happens enough, nobody will use the Protected Admin feature, and that would be a very sad thing indeed.
Other benefits will emerge as more applications are written that run with least privilege. For example, corporations will finally be able to lock down their workstations, allowing employees to run under least-privilege accounts. This will significantly simplify administration and reduce costs. Now more than ever it's important to be writing applications that run with least privilege. You can make a difference on this platform.
One of the messages from PDC 2003 was that managed applications are the future. By writing managed code, you can take advantage of the latest revolution in security on the Windows platform: security via code identity. The evidence-based security system provided by the common language runtime (CLR) and often referred to as CAS, or "code access" security, allows the CLR to place extra restrictions on code based on where it came from, who signed it, and so on. This added dimension of security opens up new avenues for software distribution. By running code in a secure sandbox, clients can now confidently run code downloaded from a central server, which makes features such "no touch" and "click once" deployment feasible, further reducing administration costs. And who wouldn't prefer a real Windows application running on their machine to a browser-based application, if the deployment and security risks were similar?
In Longhorn, each managed application can indicate the specific permissions it needs in order to function via the application manifest. Code listing 1 shows an example manifest generated when I built a default wizard-generated "Longhorn Application" project. Note the TrustInfo section and the set of permissions expressed there. These are the permissions that the application needs to run.
Code Listing 1. An application manifest
<?xml version="1.0" encoding="utf-8"?> <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:schemas-microsoft-com:asm.v1 assembly.adaptive.xsd"> <assemblyIdentity name="MyLonghornApp" version="126.96.36.199" processorArchitecture="x86" asmv2:culture="en-us" publicKeyToken="0000000000000000" /> <entryPoint name="main" xmlns="urn:schemas-microsoft-com:asm.v2" dependencyName="MyLonhornApp"> <commandLine file="MyLonghornApp.exe" parameters="" /> </entryPoint> <description asmv2:iconFile="App.ico" /> <TrustInfo xmlns="urn:schemas-microsoft-com:asm.v2" xmlns:temp="temporary"> <Security> <ApplicationRequestMinimum> <PermissionSet class="System.Security.PermissionSet" version="1" ID="SeeDefinition"> <IPermission class="System.Security.Permissions.FileDialogPermission" version="1" Unrestricted="true" /> <IPermission class="System.Security.Permissions.IsolatedStorageFilePermission" version="1" Allowed="DomainIsolationByUser" UserQuota="5242880" /> <IPermission class="System.Security.Permissions.SecurityPermission" version="1" Flags="Execution" /> <IPermission class="System.Security.Permissions.UIPermission" version="1" Window="SafeTopLevelWindows" Clipboard="OwnClipboard" /> <IPermission class="System.Drawing.Printing.PrintingPermission, System.Drawing, Version=1.2.3400.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a" version="1" Level="SafePrinting" /> <IPermission class="MSAvalon.Windows.AVTempUIPermission, PresentationFramework, Version=6.0.4030.0, Culture=neutral, PublicKeyToken=a29c01bbd4e39ac5" version="1" NewWindow="LaunchNewWindows" FullScreen="SafeFullScreen" /> </PermissionSet> <DefaultAssemblyRequest PermissionSetReference="SeeDefinition" /> </ApplicationRequestMinimum> </Security> </TrustInfo> <dependency asmv2:name="MyLonghornApp"> <dependentAssembly> <assemblyIdentity name="MyLonghornApp" version="0.0.0.0" processorArchitecture="x86" /> </dependentAssembly> <asmv2:installFrom codebase="MyLonghornApp.exe" hash="28c18a303c7fb7e9fe43a32b456f0932f52125a9" hashalg="SHA1" size="110592" /> </dependency> </assembly>
A LUA-compliant managed application will always include a section like this, and the trust manager in Longhorn will use this information to determine whether to allow the application to be installed on the machine. If the application is coded carefully, it might be able to run with such low privilege that the trust manager can assign it a score of "no risk," and the application can be installed immediately and run without user intervention. However, if the application scores a more dangerous risk rating based on the permissions it requests, the user will be prompted with a dialog describing the potential dangers the application poses. The user can then choose whether to allow the application to be installed and run.
Stating your intentions up front in the manifest is a good idea, because if you don't, the trust manager can only assume the worst about your application, and the risk rating expressed to the user will seem all the more sinister. So it's a really good idea to express the permissions you need in your manifest. Don't skip this step.
In a study mentioned at PDC 2003, Microsoft found that 40 percent of users always click "No" when presented with security dialogs such as ActiveX control download warnings. It's clear that if you want to distribute your software to users over the Internet, you're going to be hoping for a risk rating of "no risk" from the trust manager in Longhorn, so the user won't be prompted before installing and running your application. So you might be wondering whether there is a documented set of permissions that will always be scored "no risk." It turns out that there is such a definition, and it's known as the SEE permission set.
You may have heard this referred to at PDC 2003 as SEE (Secure Execution Environment), but most people find that term rather confusing, so I'm going to simply call this the no-risk permission set. Longhorn will ship with a special permission set that will always score "no risk" with the default trust manager in Longhorn. If you write an application whose permission requirements fall entirely within the no-risk permission set, it can be installed and run without showing any trust warnings at all. Code that is granted permissions only within this set (at least as it's defined by Microsoft initially) should not be able to harm your machine intentionally or accidentally.
So if you want your application to install and run without the user being prompted with a scary-looking dialog, you'll want to restrict yourself to activities that are allowed by this permission set. You should know that the Longhorn team is considering making this permission set configurable by administrators, so what's considered "no risk" at one site might be different at another. But for the vast majority of Longhorn installations, the no-risk permission set will be the default one that ships with the operating system.
What does it look like? Have another look at the manifest in Code Listing 1. Note the ID given to the PermissionSet defined in the TrustInfo section, "SeeDefinition".
Here is what the no-risk permission set looks like for the PDC 2003 preview build: Unrestricted FileDialogPermission allows you to read or write files of the user's choosing via the standard OpenFileDialog and SaveFileDialog classes, but you are not allowed to learn anything about the structure of the user's file system, including the name of the file the user chose. The IsolatedStoragePermission allows an assembly to read and write up to 5 megabytes of user-specific state on the user's hard drive without having to prompt her with a file dialog. The SecurityPermission allows your code to execute in the first place. The UIPermission allows you to draw on the screen, but only in your own windows, and grants you limited access to the clipboard (you can't read its contents programmatically, but the user can paste from the clipboard into your controls). PrintingPermission allows you to print, but only if you do it through the print dialog. Your code can't silently start print jobs without the user knowing you're doing it. The "Avalon"-specific permission allows your code to create full screen windows as long as they have a border that's controlled by the operating system (so you can't spoof the login screen, for example).
Keep in mind that this definition will almost certainly change over time; it may even change before the Longhorn beta ships. So take my description here with a grain of salt. Hopefully this article will help motivate you to start looking at some of the least-privilege features in the .NET Framework such as isolated storage and common dialogs, because the final definition of the no-risk permission set will very likely require you to use these features to avoid a trust dialog.
Defining a no-risk permission set is not a trivial task. The Longhorn team knows that if its definition is too restrictive, not enough applications will be able to use it. But if it's too permissive, malware will definitely misuse it. One hopes that the team can find the sweet spot. Figure 1 is a diagram that shows the range of privilege for Longhorn applications, from a blessed admin application all the way down to applications designed to run with the SEE permission set.
Figure 1. Types of applications
Building least-privilege applications has never been trivial. You need to have guidelines and tools to help. We saw some examples of these tools at PDC 2003, the first of which is Visual Studio® 2005 (code-named "Whidbey" in the PDC 2003 timeframe).
This new development environment provides a number of features that help make it easier to target a least-privilege environment. For example, you can choose a permission set you'd like enforced when you debug your application. A great place to start for Longhorn applications would be the SEE permission set. For existing applications, your best bet is to target the Internet permission set, which is pretty close to how the SEE is defined today.
Once you start debugging with reduced permissions, you're certain to run into some unexpected SecurityExceptions. Figure 2 shows a classic example where the developer uses a file dialog to prompt the user for a filename, and then tries to read the filename that was given. If you're granted FileDialogPermission (as you are in the SEE permission set), that allows you to prompt the user for a file, but you specifically are disallowed from seeing the filename the user picked. Instead, you must call a method (OpenFile) to open a stream that you can then use to read from the file. Visual Studio 2005 provides advice to help the developer find the correct way to use the OpenFileDialog class to avoid the security exception.
Figure 2. Better tool support
Another useful tool that was announced at PDC 2003 is called PermCalc. This is a command line tool that evaluates an assembly and determines via heuristics the permissions it needs to run. This feature is also planned for inclusion in Visual Studio 2005. This is a great way to target least-privilege environments. A similar tool that exists today is called the Windows Application Verifier, part of the Windows Application Compatibility Toolkit. This tool can help you detect when your application violates rules such as writing to protected parts of the file system or registry.
Longhorn promises to be a great platform for least-privilege applications. Get started today by writing managed code, first of all. When building desktop applications, make them LUA compliant (and use the Windows Application Verifier to help check your work). If you can, target the Internet permission set for now, and you'll likely fit right into the SEE when Longhorn ships.
For More Information
Read Brent Rector's book, Introducing "Longhorn" for Developers.
About the author
Keith Brown is an independent consultant specializing in application security. He authored the book Programming Windows Security (Addison-Wesley, 2000) and is writing a new security book for .NET programmers. Read the new book online at http://www.develop.com/kbrown.