Fixing "LUA Bugs", Part II

Fixing “LUA bugs”, Part II

If (and only if) items #1 through #3 (a, b and c) from Fixing LUA bugs, Part I don’t allow your apps to work as normal user, then – and only then – move on to items #4 and #5, which are described in this article, along with their respective benefits and drawbacks.



#4:  Loosen ACLs


The usual reason for LUA bugs is that the developers (and often, the testers) always ran as admin.  They didn’t explicitly set out to require that the end-user run as admin, but things crept into the code that depended on admin access, such as writing to files in the root folder of the C: drive, in the app’s installation folder under %ProgramFiles%, or in %windir%.  The app worked correctly until you ran it on your machine as a regular User.  The app wasn’t designed to handle that scenario gracefully, and barfed.  (See What is a LUA Bug…).


Option #4 is to change the Access Control List (ACL) on objects to grant your User the access that the program requires.  Typically the objects that need tweaking will be in the registry or in the file system (if using NTFS).  This must be done very carefully, though, and only after all of the more-preferred options have failed.



  1. App-specific resources only:  ACL changes should only ever be considered on application-specific resources, not on OS-wide resources.  While it might be OK to change the ACL on %ProgramFiles%\VendorX\AppX\DataFolder, you should never change the ACL on %SystemRoot%\System32 – to loosen or to tighten access.  (See KB article 885409 for more information.)


  1. Not used by admins:  Avoid changing ACLs on resources – particularly executables such as .exe and .dll files – that are ever used by administrators or services.  Doing so increases the risk of elevation of privilege leading to compromise of the entire system.  (Even so, the attack surface would remain far smaller than it would be with everything always running as admin.)


  1. Avoid binaries:  Avoid changing ACLs on program code (e.g., exe, dll, or ocx files) if at all possible, to prevent malware from infecting or replacing them.


  1. Single non-admin user (ideal):  Ideally, the resource should be one that is only ever accessed by a single non-admin user.  If the resource is accessed by multiple non-admin users, there is increased risk of one user causing another user’s account to be compromised.  As described above, if it is ever used by an admin user or a service, risks are increased further.


  1. Least additional privilege:  You should grant the least amount of additional access to the smallest possible number of resources and to the smallest possible number of users in order to allow the app to work.  Granting Full Control to Everyone on a big chunk of the file system or registry should never be necessary. 

    Granting the additional access only to the computer’s primary user is optimal, but that may be difficult to manage across a large number of systems when each computer has a different primary user (e.g., grant MARY the permissions on one system, STEVE on another, etc).  If you can define a set of users who need to use the program, add them to a group and grant the access to that group.

    Another alternative to consider is to grant access to the built-in INTERACTIVE pseudo-group.  This will grant the additional access only to whoever is interactively logged on at the time, without also granting any additional remote access to the resource.   Note that in a terminal server or Fast User Switching scenario there can be multiple simultaneous users on the computer with INTERACTIVE in their tokens.


Benefits of this approach:


Big return on the investment of your time – most of the LUA bugs that my colleagues and I have seen revolve around file and registry permissions.  This approach will probably fix a larger share of your LUA bugs than any other approach.


Drawbacks to this approach:


  1. It’s #4 on the list for a reason.  This approach allows otherwise-constrained users to change shared resources – for good or evil, and makes it easier for one user (or malware unintentionally run by that user) to affect others.  If the affected user is an admin, the entire system can be compromised.


  1. As with items #3a and 3b, it is not easy, with today’s tools, to identify precisely which resources should be opened up and by how much.  (More on this in upcoming posts.)


  1. It can be difficult to know for certain whether opening access to a resource will inadvertently expose an avenue for elevation of privilege, allowing system takeover.



#5:  Run the one app with elevated privileges


As a last resort, after all else fails, consider running that one app with elevated groups and/or privileges.  Some apps, for example, “address” their LUA bugs by explicitly checking for admin group membership on startup and displaying an error message insisting that you simply have to be an admin to use the program.  This may be due to developer laziness, incompetence or arrogance (or all three), but these apps will be resistant to any other workarounds available to you.


Typically, this approach means running the app as admin.  You could instead run the app elevated but less-than-full-admin – for example, as a member of Power Users or with a specific privilege such as SeLoadDriverPrivilege.  Note, though, that with a little more work many of these other groups and privileges can still be used to take over an entire system.


Benefits of this approach:


It’s better than always running everything as admin.  That’s it – that is the only benefit of this approach.


Drawbacks of this approach:


Running an app with elevated privileges exposes far more risk than any of the options described earlier.  It becomes very difficult to defend the system against a malicious user or malicious software when there’s an app running as admin.  A simple example:  Run “Notepad” as admin, then choose File/Open – that dialog is now a little Explorer-like window that gives you full, admin-level access to the entire file system, and even the ability to launch programs as admin.  That can be exploited by a malicious user, or by malware pumping keystrokes or window messages into the elevated program.


How to do it:


If you trust the user with the admin password or to otherwise make security and trust decisions:

If you don’t trust the user with the admin password:

  • PolicyMaker Application Security by DesktopStandard uses a Group Policy extension to configure rules for modifying process tokens.  PMAS mitigates some of the drawbacks described above.  For example, it can be configured so that child processes launched by a targeted app do not inherit its modified token, and can perform granular token modification, raising (or lowering) permissions, and/or adding (or removing) privileges.
  • Protection Manager by Winternals (the for-profit side of SysInternals) uses a lightweight client-server application and a whitelist approach to block all untrusted applications – while also allowing applications that to have their process tokens and privileges elevated to that of an Administrator or reduced to that of a User (in cases where end users are non-Administrators or Administrators, respectively).  Protection Manager also doesn’t allow a child process of an elevated app to run elevated unless it is also explicitly configured as an elevated app.  Conversely, all process children of reduced privilege processes are reduced automatically (to also minimize security risk). Applications can be allowed, blocked, elevated, or reduced as specified by an administrator via Digital Signatures, Hashes, NTFS File Ownership, or Path.


Trying to “hide” the admin password:


The DesktopStandard and Winternals products determine in kernel-mode code whether, when and how to modify a process token.  Passwords are not used and are therefore not at risk to exposure, and the modification decision cannot be interfered with by non-admins.  By contrast, there are various tools available that perform RunAs-like operations with the admin account credentials encrypted (or sometimes just obfuscated).  Even though this raises the bar and will stop some users from getting the admin creds, those passwords still have to be decrypted within the user’s security context, and so are exposed to a user with the right tools.


A frequently asked question is whether the RunAs.exe /savecred option would let one create a shortcut to run a single app as admin using a saved password and not requiring further password entry.  There are several issues you should be aware of:

  • The credentials are not tied to any one shortcut – once the creds have been saved they can be used to start any app
  • While the password is securely encrypted with a user-specific key, it will still be decrypted in the user’s security context and at least briefly exposed
  • The /savecred option is not available on XP Home Edition.


//TODO:  Discuss my thoughts about the SRP/DropMyRights approach.  (Bottom line:  I dislike it.)


Much thanks for help and insight for this post goes to Eric Voskuil and Kevin Sullivan of DesktopStandard, and to Mark Russinovich and Wes Miller of Sysinternals/Winternals.

Comments (34)

  1. Suite (et fin ?) des articles d’Aaron Margosis…

    Ces articles sont en anglais, mais fournissent énormément…

  2. Anon says:

    "This may be due to developer laziness, incompetence or arrogance (or all three)"

    How can you blame developers for this? Microsoft were the ones who’ve spoiled developers in the first place. So it was your incompetence that has caused people to neglect support for limited accounts.

  3. Anon:  I’m not assigning blame to developers for causing the entire LUA problem – there’s a lot more involved (future blog post perhaps).  The slap here is when an app fails to run as LUA, and the developers’ "fix" is just to add a hard admin check on startup and insist that you have to be admin to run the app.

  4. Ryan says:

    I’m curious, what are your suggestions for LUA interaction for an app that is self-updating?  (It downloads both updates to the main app as well as ‘plugins’)

  5. Access to a page’s head element using ASP.NET

    2.0 [Via: Scott Guthrie ]

    Architecting and using ASP.NET…

  6. Jose Carlos says:

    Hi Aaron, I found this article very interesting. There is however something I can’t understand.

    You said "Avoid changing ACLs on program code (e.g., exe, dll, or ocx files) if at all possible, to prevent malware from infecting or replacing them."

    Could you please tell me why would it be easier for malware to infect ACLs on program code if they are changed?

  7. Jose – the last "them" in that sentence refers to the program files, not to the ACLs.  If you make a file modifiable by changing its ACL, then malware can infect the program file or replace it with a program file of its own choosing.

  8. Jason says:

    Also, another useful program if you don’t trust the user with the admin password is TQCRunas. This program uses Microsoft Crypto API to securely encrypt the password in a file and will allow you to perform runas commands.

  9. Jason, TQCRunas falls into the category I described with this text:  "… there are various tools available that perform RunAs-like operations with the admin account credentials encrypted (or sometimes just obfuscated).  Even though this raises the bar and will stop some users from getting the admin creds, those passwords still have to be decrypted within the user’s security context, and so are exposed to a user with the right tools."

  10. Ryan – that’s a tough question (re self-updating apps).  Your question implies other questions – are we talking about what the guidance should be for app developers who want to write self-updating apps?  Or are we talking about how IT admins should deal with existing ones out there today?  (I’ll assume the latter since that’s most of what the Fixing LUA Bugs posts are about.)  The choices would seem to be:

    1.  No changes – the app can’t be updated;

    2.  No local changes – the IT infrastructure can push out the security and other required updates as needed;

    3.  Make ACL or other changes to allow the app – running as the user – to update itself.

    #2 is the best, if you can do it.  #1 introduces risk that users may run vulnerable code even after exploits start showing up – but at least the exploits won’t run as admin.  #3 introduces risks as described in this post.

    Ultimately you need to determine what your specific exposure is to which threats, what is at risk – the costs associated with those threats, vs. the pros and cons of the alternatives.

    Hope this helps!

  11. Permutor says:

    This advices on this blog are very useful. It does not give me a clue how to solve this problem. I have set up, from scratch, a Windows XP prof SP2. I have installed Office XP SP3. The system is fully up to date with Windows update.

    I have set up accounts for users to run the Office XP programs. For some reason Office XP requires that these accounts have full admin rights. It refuses to run with a LUA account. All Office programs will give a cryptic message that I traced back as error 197. I will give a free translation into english since the original is in dutch: "The operating system currently is not properly configured to run this application". There is no clue what is misconfigured, or how to fix it. There is no hint on the installation disk either. I have searched the Internet to no avail. Since the problem concerns all office programs (not just one in particular) it does not make much sense to determine from scratch which authorizations are required.

    I have tried to fix it with the repair function on the Office XP disk, but it has not helped. The idea of giving the users admin rights just to run Word or Outlook does not appeal to me.

    Can you help me out here ?

  12. David says:


    Interesting articles, I am involved with a company at the moment that wants to move Least Privelege principles applied to it’s 4000 workstations but also doesn’t want to fork out the money to upgrade it’s legacy apps that require admin access.

    So far the most attractive option to us is that of PolicyMaker Application Security, which you mentioned in your post. Are you aware of the technical details of this program? It seems to me that modification of the process tokens would be in violation of the windows security model, or am I missing something here? I searched for how to do this and it only seems possible using NtCreateToken and NtSetInformation… Any thoughts on this?

  13. redxii says:

    We can only hope that Vista’s virtualization doesn’t further encourage such behaviors.

    Vista is supposed to allow a non-admin to view the clock and calendar, and not assume that just because you open that applet you want to change something, right? Are there any plans to fix this in XP? It seems rather crazy to put down a few hundred bucks just so I can view the calendar without admin or the change time privilege. Other than falsifying timestamps does allowing a user to change the time present any other security risks? The Date and Time applet is the only part of the entire OS that I can think of that is inconsistent with the behavior of the rest of the OS: If you can’t do it, it’s greyed out and unable to interact with it.

  14. redxii – I wouldn’t expect to see any significant changes to XP’s UI at this point.  But a few other things:

    1. The Date&Time applet (timedate.cpl) was designed to allow the user to change the date/time, not to browse the calendar or see the pretty timezone map.  It turned out that people ended up using it that way, but prior to Vista it was not designed to be used as a read-only interface.  See Raymond Chen’s post:

    2. I hope you’ll find more reason to upgrade to Vista than just to view the calendar as a non-admin!

    3. The main security and reliability risks involved in granting SeSystemtimePrivilege are falsifying audit logs, and breaking Kerberos.

  15. David – I would suggest contact the vendors of the 3rd party products mentioned in order to better understand how their implementations work and whether they are suited to your environment.  I will point out that both PMAS and Protection Manager do not change the process token after the process has started running, and I do not believe that either causes any Common Criteria issues.

  16. Permutor – I have no idea what might be causing the WinXP+OfficeXP problem you’re reporting.  I ran Office XP every day as a non-admin until I upgraded to Office 2003, and I don’t remember any breaking issues.  I’d suggest making sure that while logged on as admin you have installed all the Office components you will need.  The installer dialog will probably come up each time a user uses a component for the first time, but that should be only to install per-user stuff.

  17. David says:

    Ok thanks Aaron, I will contact the company for more information.

    ps. Lets see a post on the politics of LUA implementation in corporate culture 🙂

  18. redxii says:

    Aaron, that is rather backwards. Outlook is cost prohibitive if you want just a calendar. Otherwise the Time and Date applet could have been reduced to atleast more than 50% its current size by just including a field to change the date in MM/DD/YYYY (depending on regional settings)

    Anyway, as far Office goes, I would try doing setup /a to do an administrative install and install using that source. I tried the non-administrative install way and it asks each user to insert the office cd. Earlier office versions simply failed. An administrative install hasn’t done that to me ever..

  19. richard says:

    Not sure if this is the right place to ask this but …

    Whenever I log into a limited user account on Windows XP I get a popup dialog with:

    (1) no title

    (2) the word "fAIL" – spelled that way!

    (3) OK button

    Is this some really bad Windows message?

    Or a misbehaving application?

    Or some infection that has problems running under a limited user account? (this is a new system, only a week old, and noticed it the first night – anti-virus programs have not detected anything)

    Windows XP

    Media Center Edition

    Service Pack 2

    AMD Athlon 64 X2

  20. AC says:

    Why didn’t you mention the possibility to install the offending app inside of the MyDocuments as the way to avoid "opening "c:Program Filesblah blah" for writing, which can then infect other users? Did MSFT consider expanding possibilities of something like this as the preferred solution to #4?

  21. AC – great question.  That is a possibility, but there are at least two significant drawbacks:

    1) Patch management becomes much more complicated;

    2) The binaries then are always writable (infectable) by malware running as the user.  (Infecting arbitrary executables is much more straightforward than infecting data files.)  If you can do #4 without changing the ACLs on executables, then it’s *probably* better to keep them in %ProgramFiles%.

  22. AC says:

    Aaron, I asked you because there are more applications which can be installed without problem in MyDocuments by user himself, and he doesn’t even need admin privileges for that, whereas the same installer doesn’t allow the user to install to the default "Program files" (or, as a second manifestation, after the installation the user can’t work with the program).

    So the user is even now able to install without needing admin privileges, if he just doesn’t accept the default location. And he is anyway able to run any new program.

    Do you want to say that the user in fact shouldn’t be able to install the new application at all if he doesn’t have the admin password, even if he’s the only one who uses it?

  23. AC – no, I’m not saying that users shouldn’t be able to – I’m just pointing out some caveats:

    1) Many applications won’t install correctly even to a folder the user can write to, because the installation may try to register COM/DCOM components (writing to HKCR) or write other configuration data to HKLM, etc.

    2) Many organizations do not want end users installing unauthorized programs due to legal, licensing, security or compliance issues.

    3) As I mentioned before, binaries that the user can write to increases attack surface – at least for that user.

  24. More info on the risks of changing access control lists to fix LUA bugs.

  25. John Bokma says:

    Hi Aaron,

    Contacting the developer of a program in order to report a LUA bug might be a huge PITA. I did twice, and on both accounts the developers came up with wonderful stories why the application misbehaved. See:


  26. jjudeb says:

    We’re experiencing the same problem as Permutor, installing MSOffice 2003 Professional on a Citrix server.  Everything works fine for Administrator, but not for limited user.  Since Citrix Published Applications run under Anonymous user accounts, MSOffice cannot be used as a published application any more.  Everything worked fine for years with MSOffice XP, but it’s hosed with MSOffice 2003.

  27. "Why does Application XYZ need to run as admin?"

  28. One way of coping with the challenges corresponding with "the principle of least administrative privilege"

  29. On the second Tuesday of the month Microsoft introduces updates for it's products. As a system administrator

  30. Doug Deden says:

    Permutor –

    The Student Edition of Office 2003 did the same thing to me. The problem was access rights to a part of the Program FilesCommon Files directory structure. I think it was MSOCache, which Office uses to install parts as needed. Even though I did a full install as admin, apparently limited users still needed to see MSOCache. I think I just gave them read-rights, but I don’t have that PC handy.

  31. More info on the risks of changing access control lists to fix LUA bugs.

  32. PJ says:

    thanks for these informations.

    Reading this article i search for explanation why ‘cocreateinstance’ may fail when UAC is On…I did’nt find it.

    did you have some ideas?

    [Aaron Margosis]  Most likely it’s because the component you’re trying to instantiate is doing something that requires admin- or admin-like permissions.  Another possibility is that if you are running elevated and try to instantiate something that is registered in HKCUsoftwareclasses, COM ignores that hive when the caller is running elevated.