Click here to Skip to main content
15,867,568 members
Articles / Operating Systems / Windows
Article

Secure Coding Practices: Running with Least Privileges in Windows

Rate me:
Please Sign up or sign in to vote.
4.69/5 (26 votes)
8 Mar 200310 min read 220K   50   32
An article on developing software while running with least privileges in Windows

Introduction

There is an old rule in Unix environments, that you should never run a desktop environment as root. It makes sense; root is the super user that has complete control of everything in the operating system, and from a security perspective it makes no sense to expose such privileges as you work in the system unless you absolutely have to.

In the Windows world, as far as desktop environments go, there hasn’t been this same “rule of thumb”. Well, more to the point… no one is touting it. Well, this article is to do just that. Although many of us who are security conscience run our systems with least privilege as we do development, most of you do not. Hopefully I can show you a few reasons why developing in a least privileged environment is a good idea, and answer some of the issues people have when they try it, and it fails.

Understanding Least Privilege

If the term “least privilege” seems foreign to you, don’t fret. The term itself is a pretty good definition. Least privilege is a concept in the field of security where basically you give the absolute minimum amount of access rights and privileges to accomplish a task. Think about this concept in reflection of the old wives tale about fishing with dynamite. Perhaps you heard of it? You take a stick of dynamite, light it and throw it in the lake. BOOM! Now go collect the fish that float to the top. Ok, fishing complete. Yet it could have been done with a fishing hook, some line and a little patience. Both can do the job, but the dynamite is excessive… it’s just not the right tool. If something goes wrong, there is a bigger chance you will hurt yourself or others around you than if you used your fishing gear. The same analogy can be used with applications in any environment – they should only need enough privileges to do their job.

When you consider all the security compromises that relate to buffer overflows, privilege elevation, data destruction etc, an application ran in least privilege will do less damage than if it was ran as a super user like root or administrator. The injection of faulty data (malicious or not) makes it way to easy to wreak havoc on the system. As an example, a Trojan executed will spawn itself with the same privileges as the calling process. If your account is part of the local administrator group, a Trojan will now have complete system access which could open you up to virtually everything.

Outside of the issues that relate to application security, there is another good reason to not run as administrator on the local machine, especially if you are doing development. You should be doing your development in an environment as a normal user so your applications will be in the same security sandbox as your intended users. This may seem like a small point, but consider the outcome. If you write your code with full privileges, many conditions that your normal users will have imposed on them will never be seen in a development or QA environment.

I just finished installing an app today that had this problem and did not work for me. It is the whole reason I decided to write this article. No error conditions or alerts of any kind were shown during the normal operation of using the application. Yet every time I tried to click a button it just sat there. Finally I realized that maybe it was trying to read or write something in the registry in which I didn’t have access to. Sure enough, that was the case. It was trying to write to a registry key that I had no rights to. How did I get around this? I used a tool built within Windows XP/2000 to change my user credentials for this application only, so that it could set the required key. Once that was done, I could run the application fine as a normal user. Lets talk about that tool.

The "runas" command

Windows has a neat utility that can run application with other credentials called "runas"[1]. Runas allows a user to run specific tools and programs with different permissions than the user's current logon provides. This can be done through the command line, or through a graphical user interface. Lets give it a try. Here is the scenario. Lets assume you are a normal user without any administrative privileges on Windows XP. You need to check out some settings in HKEY_LOCAL_MACHINE\SECURITY. You do the following:

  1. Click Start->Run
  2. Type: regedit
  3. Expand the HKEY_LOCAL_MACHINE tree node.
  4. Expand the SECURITY tree node.
  5. Get prompted with “Error Opening Key” Dialog. Access is denied!

This is expected. As a normal user you shouldn’t be allowed to see this particular key. Now lets try accomplishing the same task using the runas command.

  1. Click Start->Run
  2. Type: runas /user:Administrator regedit
  3. Enter the administrator’s password at the prompt
  4. Expand the HKEY_LOCAL_MACHINE tree node.
  5. Expand the SECURITY tree node.
  6. Note you have access

Bingo. You started the process regedit as administrator on your local desktop running as a normal user. This gives you the flexibility of still being able to run administrative tasks and processes, but on your conditions, when you want it. Yet at the same time, you are restricting the possibilities of malicious code from gaining extra privileges than what is provides as a normal user.

Runas is a pretty good tool for this. But you don’t have to always use it from the command line. You could just as easy create a shortcut on your desktop to regedit, and set it up to run with different credentials. Here is how you could do it on Windows XP.

  1. Create a new shortcut on your desktop
  2. Right click and choose Properties
  3. Select the "Shortcut: Tab
  4. Click the "Advanced" button
  5. Select the "Run with different credentials" checkbox

  6. Click "Ok"
  7. Click "Apply"

When you double click on the shortcut, it will now prompt you with a graphical dialog on which account’s credentials you wish to launch regedit as. You could also get to this from any shortcut by right clicking and selecting "Run as…" from the popup menu.

Setting up Access Rights for Debugging

As a developer one key feature you will ultimately need is the ability to debug programs. One issue you will have as a normal user is that you cannot attach a debugger to processes that you don’t own. In the real world, I found that sometimes even when it IS your process there are issues in tools like Visual Studio .NET. Further to this, you will want to be able to terminate processes easily, which isn’t permitted as a normal user. These are all issues due to the SeDebugPrivilege flag not being available to you. No worries though, as you can easily increase your privileges for just local (or even remote) debugging by adding yourself to the "Debugger Users" group. This can be accomplished by:

  1. Click Start->Run
  2. Type: runas /user:Administrator "mmc compmgmt.msc /s"
  3. Enter the administrator’s password at the prompt
  4. When the Computer Management console starts up, expand the “Local Users and Groups” tree node.
  5. Select the “Users” folder
  6. Double click on your user name
  7. Select the “Member of” tab
  8. Click the “Add” button
  9. Enter in “Debugger Users” in the field provided (without the quotes)
  10. Click “Ok”

You will now be a member of the Debugger Users group, and will now have efficient privileges to be able to attach a debugger to any process in the system. Now, I would like to give you a word of caution if you decide to increase your privileges to include debug access. If an attacker can gain access to your account that now has debug privileges, it may be possible to execute malicious code within any running process on the system. There have been recent security proofs [4] in which you can use functions like OpenProcess() and CreateRemoteThread() to insert code in this manner. Even with this potential threat, it is still safer than running as a full administrator. By reducing the attack surface of your account privileges in the system, it is much harder for an attacker to maliciously elevate his (your) privileges in this way, compared to how easy he gets it if he compromises an administrator account.

Tracking down Least Privilege Issues

If any of you take my advice and remove yourself from the administrator’s group, you will probably come across some issues and will have trouble trying to get existing applications you wrote to work as a normal user. This should be expected. It’s not really your fault (Well, it is… but why dwell on it). You probably originally wrote it for Windows 98/ME which didn’t have such finite access control and although it worked fine in W2K/XP, it was because you ran as an administrator with full privileges. You just haven’t dealt with the security permissions and access control lists that you should be in newer Windows environments.

There is a way to help diagnose what may be causing your application to fail as a normal user. If you modify your computer’s logging policy, you can trap many issues your application may have as it dumps it to Event Viewer. Here is how you would configure your security policy to support this:

  1. Click Start->Run
  2. Type: runas /user:Administrator “mmc secpol.msc /s”
  3. Enter the administrator’s password at the prompt
  4. Expand the “Local Policies” tree node
  5. Click on the “Audit Policy” folder
  6. Double click the “Audit privilege use” item
  7. Check the “Faillure” check box
  8. Click “Ok”

Now when your application runs, failed privilege attempts will be logged to Event Viewer, and you can begin to figure out what and where your application may be failing.

Another issue that will come up will relate to access privileges to files, directories and the registry. Mark Russinovich and Bryce Cogswell over at SysInternals (http://www.sysinternals.com[^]) wrote two excellent tools that will aid you in diagnosing these types of issues. FileMon and RegMon will monitor access attempts to files and the registry respectively, and will report an access denied (ACCDENIED) if you application does not have the required privileges in the system.

You can use this approach with these tools to quickly find issues in your applications and address them before other users come up to these problems. Remember, if YOU can’t run it as a user, how can you expect them to be able to? Requiring to install as administrator is just not acceptable, unless of course the application REQUIRES administrator access. Don’t get lazy…. do it right. Trust me, you will thank me in the end.

Conclusion

It is easy to be lax with security when it comes to comfort in our development environment. We want to get our job done, without any constraints. Yet doing this exposes us to large risks we really don’t NEED to take. A combination of a normal user account with Debugger User group privileges can give us the same environment to write code as if we were administrator. With addition of the runas command, we can even run administrative tasks in our normal user environment. Hopefully you can see this. It is the old “eat your own dog food” adage. If you yourself run with least privilege, and design your applications in this way, your quality of code will increase, as will the security. Who would have thought such a small change could create such a large benefit?

Of course, you can ignore this article. You could stick your head in the sand and expose yourself to unnecessary risk. You can write applications without thinking about least privilege and access control. Hopefully, I won’t have to run your stuff.

Security is part of our every day life, and we should embrace it. Using secure coding practices is a great start.

References

  1. http://www.microsoft.com/technet/treeview/default.asp?url=/technet/prodtechnol/winxppro/proddocs/runas.asp[^]
  2. http://www.jsifaq.com/subf/tip2500/rh2548.htm[^]
  3. http://www.ntfaq.com/Articles/Index.cfm?ArticleID=25992[^]
  4. http://www.securityfocus.com/archive/82/312694[^]

History

  • 09/03/2003 - Initial Submission

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer
Canada Canada
O divine art of subtlety and secrecy!
Through you we learn to be invisible, through you inaudible;
and hence hold the enemy's fate in our hands.


-- Sun Tzu, The Art of War, c. 500bc

Sun Tzu said it best. I am your run of the mill security engineering geek that likes to break things. Well more to the point, I like to prevent others from being able to break things.

I dislike the FUD people sling around about how any one piece of software or their OS can completely secure the world. Security is a process and not a product, and should be treated as such. I think General Patton said it best when he said:

“Fixed fortifications are monuments to man’s stupidity.”

I spend most of my days developing code that is part of our security management life cycle, in the hopes people start to realize that static defences are not enough.

I spend most of my time on flavours of Windows (Currently XP) in a set of Cygwin bash shells SSHing to Linux and BSD systems to actually do a lot of my work. My main editor is vim with ctags (I can work faster in it than in Developer Studio) and it works great editing code both locally and remotely.

When I am not in front of a computer I can typically be found at the Squash courts or listening to contemporary jazz like Chris Botti, Diana Krall or Miles Davis (ok... so he is more Blues and fusion but his trumpet still sings). Otherwise, I will be immersed in a book which probably relates to information security, cryptography or has some sort of animal on the cover and is published by OR&A.

Comments and Discussions

 
GeneralInteresting, but.. Pin
Jim A. Johnson10-Mar-03 12:00
Jim A. Johnson10-Mar-03 12:00 
GeneralRe: Interesting, but.. Pin
Dana Epp10-Mar-03 12:44
Dana Epp10-Mar-03 12:44 
GeneralRe: Interesting, but.. Pin
User 988511-Mar-03 3:06
User 988511-Mar-03 3:06 
It depends on the situation though. Many enterprises do not want employees to even install other programs on their computers for various reasons (license infringement due to pirated software, objectionable content, IT management issues etc.) So the computer tends to be locked down to a very high level. Access may be restricted to parts of the registry etc. by a central policy.

In those situations, it is good to design systems such that it runs with the least required privileges. A business dataentry app does not need to have administrative privileges. But, many applications use things that need administrative privileges. Testing for these inadvertent things will save a lot of headache, if you let the apps run into the field and fail there.


My article on a reference-counted smart pointer that supports polymorphic objects and raw pointers


modified 29-Aug-18 21:01pm.

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.