Browsing Posts in Security

If you’ve developed any moderately complex web application, you’ve probably implemented some form of role-based security. For instance, only administrators can access the /Admin directory. Only ContentCreators can update web page content. Only RegisteredUsers can access the site. ASP.NET makes all of this relatively easy through the <authorization> section of the web.config file(s), programmatic security, and security trimming of site maps. Managing roles is even easier with ASP.NET 2.0 as we now have the role manager (represented by System.Web.Security.Roles) and various RoleProviders. If you’re using the SqlRoleProvider, you can test different configurations of your website by adding and removing your user from various roles and not caching role memberships in cookies. (If you cache your role memberships in cookies, you either have to wait for the cookie to expire or clear your browser cookies every time you change your role membership to ensure that you have the correct memberships.) It’s tedious, but it can be done. Even more tedious is testing role-based security for an intranet application if you’re using Windows groups via the WindowsTokenRoleProvider. Basically your Windows group memberships become your roles. Simple enough – add your user to the appropriate local or domain groups using the Local Users and Groups or Active Directory MMC snap-in and you’re good to go. Right? Not quite. Your group memberships in your user token don’t get updated until you log out and back in again. (I’m ignoring some advanced security APIs that allow you to invalidate your user token and re-acquire it.) Now this is really tedious and is likely going to result in you doing less testing under different role memberships than you really should. Is there a way that we can improve this? I’m glad you asked. Enter the ImpostorHttpModule.

The ImpostorHttpModule is an ASP.NET HttpModule that re-writes an authenticated user’s roles based on a XML file, ~/App_Data/Impostors.xml. To use the module, simply drop the assembly into ~/Bin/ and add the following section to your web.config file:

  <add name=”ImpostorHttpModule” type=”JamesKovacs.Web.HttpModules.ImpostorHttpModule, JamesKovacs.Web.HttpModules”/>

Then create a XML file called ~/App_Data/Impostors.xml, which looks like this:

<?xml version=”1.0″ encoding=”utf-8″ ?>
  <impostor name=”DOMAIN\Jane” roles=”User, Manager, Administrator”/>
  <impostor name=”MACHINE\Bob” roles=”User”/>

The file format should be fairly self-explanatory. The name attribute is the log-in name of the user. It can be a local, domain, forms auth, or other user and is not case sensitive. The roles attribute is a comma-separated list of groups or roles to place the user in. The users can be authenticated by Windows, Forms, Passport, or any other authorization mechanism. The ImpostorHttpModule inserts itself after the authentication event and replaces the role membership of the incoming user with a GenericPrincipal if, and only if, the user is found in Impostors.xml. If the user is not found, their existing role memberships remain untouched. Impostors.xml file is located in ~/App_Data because by default, ASP.NET 2.0 doesn’t allow browser access to any files in this directory. It saves you from having to filter out and deny requests for this file yourself. ImpostorHttpModule monitors the Impostors.xml file for changes. So as soon as you update it with new user or role information, subsequent requests will acquire the new roles. You can see the new roles by browsing to ShowContexts.aspx, which was created by Dominick Baier. (You can download full source from his site here.) At the bottom, you’ll see your role memberships listed. Play around with Impostor.xml and see how your memberships change.

I should note that ImpostorHttpModule is only meant for development purposes. It will get very upset (e.g. blow chunks) with a bad Impostors.xml file. If you need a robust role management system, consider using Windows groups or the SqlRoleProvider. ImpostorHttpModule is meant as a quick-n-dirty testing tool. That said, you can download the ImpostorHttpModule with source code from here. In my next installment, I’ll show how to create a security-trimmed sitemap and test it with the ImpostorHttpModule. Also stay tuned for a detailed walkthrough of the source code where I’ll explain in painstaking detail how ImpostorHttpModule actually works.

EDIT: Updated ImpostorHttpModule to use a comma-separated list of roles to match <authorization> in Web.config and sitemaps.

Fellow plumber, Bil Simser, asks the question how the heck does someone debug SharePoint as a non-admin. Elementary, my dear Simser, elementary…

The fundamental problem that Bil is experiencing occurs with SharePoint, ASP.NET, or any app that runs under a different security context than your own. A normal user can only debug applications running under his/her own security context.* Administrators have the SeDebug privilege, which allows them to debug processes running under any security context. Granting your user the SeDebug privilege gives them tremendous power, which is exactly what you’re trying to avoid. (With SeDebug, you can open any process, including system processes with full permissions. If you can do that, you own the box. I leave it as an exercise to the reader to figure out how, given only SeDebug, to elevate your normal user to be a member of the local administrators group.) I know of a few solutions to allow debugging of server processes:

  1. Develop server apps in an isolated virtual machine and use an admin account.
  2. Run as admin when debugging server apps, but run as a normal user while developing them. (This can be done using MakeMeAdmin and then running devenv.)
  3. Run the server app under your user account, though this may mean placing your username/password in clear text, which is non-ideal. (This is the strategy used by the Visual Web Developer Web Server – aka Cassini – that ships with VS 2005.)

* Note that although you don’t require any special privileges to debug a process running under your own security context, Visual Studio does enforce that you need to be a member of the Debugger Users group.

EDIT: Additional information added below related to Bil’s comment.

Bil is correct. If you run Visual Studio as a non-admin when developing server apps and you want to debug, you need to break stride and launch another copy of Visual Studio using MakeMeAdmin or runas. This is highly non-ideal. Is it a huge security risk to run Visual Studio under an admin account while the rest of your log-in session is running as a normal user? Somewhat, but it’s a lot better than running your entire log-in session as an admin.

Also remember one of the main reasons for developing apps as a non-admin – to ensure that you are running/debugging with credentials similar to what your end users will be using. (i.e. Your app isn’t writing to protected regions of the file system or registry to which normal users don’t have access.) With server apps, the story is a bit different. You want your server app to be running with different credentials – the credentials of the account that the application will be running under in production – NETWORK SERVICE or other service account. The safest solution is #1 above. Develop server apps as an admin in an isolated virtual machine. Second would be running only Visual Studio under elevated privileges using technique #2. Although technique #3 above works, you run the risk of developing your server code under unrealistic conditions – for instance, you’ll have a logged in user with a loaded HKCU hive. If you want to try option #3, you’ll have to configure your application pool and/or ASP.NET application to run as your current (non-admin) user. For the app pool identity, you can configure that using the IIS Manager MMC. For ASP.NET, you have to modify the following in machine.config:

    <processModel username="" password=""/>

Although you can store this in cleartext, I would recommend against it for obvious reasons. Take a look at aspnet_setreg.exe and the following KB article on how to store this information securely:

How to use the ASP.NET utility to encrypt credentials and session state connection strings

We’ve just released Episode 3: Powered by Infinite Improbability Drive. So that we can get you, our loyal listeners, the episodes more quickly, we’ll be hosting on both MSDN Canada Community Radio as well as on the Plumbers @ Work site. You can find the show notes here, photos here, and podcast here. It will be posted to MSDN Canada Community Radio shortly.

Show Notes

  • Introduction
  • Around the Horn with the Plumbers
  • Security March with Dan Sellers
  • Microsoft Blacklisted C++ Libraries
  • SHA-1 Discussion
  • Team Foundation Server (TFS) Release Candidate (RC) 1
  • Public Release of Internet Explorer (IE) 7.0 Beta 2
  • Various Issues with IE 7.0 Beta 2
  • Development of IE versus Development of Firefox
  • The Browser as a User Experience (i.e. AJAX)
  • Really Simple Syndication (RSS) in IE 7.0 and Outlook (AKA, The Ultimate Pull Application)
  • Information Overload (AKA, Organizing Information)
  • Upcoming Canadian Conferences: VSLive! and DevTeach
  • Half-Time
  • .NET Framework 2.0 Adoption
  • ASP.NET 2.0 Adoption
  • PetShop 4.0 Discussion and Highlights
  • .NET Nuke 4.0
  • Old Microsoft Reference Applications (AKA, “Different Strokes” or “ALF”)
  • Enterprise Library 2.0 Highlights
  • Windows “Live” Highlights (i.e. Domains, Favorites, and Messenger)
  • Other “Live” Projects (Office “Live” and Visual Studio “Live”)
  • Windows OneCare Beta
  • The Realities of a “Secure” Operating System
  • Windows Vista Favourite Features
  • Running as Standard User/Non-Admin on Windows Vista
  • Event Viewer in Windows Vista
  • Windows Calendar (WinCal) in Windows Vista
  • What’s Coming Up for the Plumbers
  • Upgrading to Community Server 2.0
  • John Still Doesn’t Have a Xbox 360

Show References

Rory Blyth and the Ewok
The SharePoint Show
Alberta .NET User Group
Calgary .NET User Group
Dan Sellers’ Blog
MSDN WebCasts
Saying Goodbye to an Old Friend (Michael Howard)
Bruce Schneier
SHA-1 Broken (Bruce Schneier)
Michael Howard’s Blog
Team Foundation Server (TFS) Release Candidate (RC) 1 (via Jeff Beehler)
Rob Caron’s Blog
Jeff Beehler’s Blog
Team Foundation Server (TFS) Go-Live License
TFS Blog
Internet Explorer (IE) 7.0 Beta 2
Scott Hanselman’s “Running Internet Explorer 7.0 Beta 2 without installing it.” Post
VSLive! Toronto
MSDN Article for Petshop Migration
.NET Nuke
Enterprise Library 2.0
Windows “Live”
Microsoft Gadgets
Windows “Live” Domains
Windows “Live” Favorites
Tuscany (AKA, Visual Studio “Live”)
Windows OneCare Beta
Windows OneCare Pricing Announcement
UntitledNet (Xbox 360 Locator Application)

You can post comments in the forums. As always, feedback is more than welcome.

Michael Howard, co-author of Writing Secure Code*, has an excellent blog post on how static code analysis tools are only one weapon in your arsenal when writing secure code. I would highly recommend reading it. A quick summary… Unless you understand the threats, know how to architect secure applications, know how to write secure code, know how to test for security vulnerabilities, and then backstop it all with a static analysis tool, you’re doomed to write insecure code.

* Fantastic book. Everyone developing software, whether on the Microsoft platform or not, should read this book.

As usual, I’ve been reading voraciously about all things .NET and here’s a selection of articles and blog posts that every developer should read in their copious amounts of spare time over the holidays.

Our first stop is security… Security for developers has long been near and dear to my heart. So it should come as no surprise that I’m a big fan of Keith Brown‘s work. His articles on security for developers are very insightful and his book, The .NET Developer’s Guide to Windows Security, should be on every developer’s bookshelf. Keith recently published an article in MSDN Magazine entitled Encrypting Without Secrets, where he lays out a foundation for encrypting data (such as credit card numbers) without placing the decryption keys on an internet-accessible server. He uses a technique very similar to SSL where he uses public/private key cryptography (RSA in his example) to encrypt a dynamically generated symmetric key (AES aka Rijndael, pronounced rain-doll). You keep the private (decryption) key on a secure server in your back office and the public (encryption) key on your web server. Even if the web and/or database server are compromised, the attacker doesn’t have the decryption key to make use of the encrypted credit cards numbers he (or she) just harvested. Very cool stuff.

Our next stop is SharePoint land… Bil Simser has a great blog post that discusses why you shouldn’t use your lightsabre to slice cheese. (Because it will melt the cheese, silly!) His point is that although SharePoint is a cool tool, you should use it for what it was designed for. Like any tool, it cannot be all things to all people. A good developer/architect knows his toolset and knows how to pick the right tool for the job. When all you’ve got in your toolbox is SharePoint, everything looks like a webpart. If this is you, learn a few more tools so you can pick the right one for the job.

Last stop is the world of ASP.NET… There are a wide variety of ways to redirect a user to a new web page and ASP.NET 2.0 adds some new tricks. Ting-hao Yang enumerates the options, including pros and cons of each technique, in this blog post. A very worthwhile read for anyone doing ASP.NET development, either 1.X or 2.0.

After months of preparation and much secrecy, Plumbers @ Work has been released into the wild by the .NET Plumbers. The regular podcast is part of MSDN Canada Radio and will be featuring John Bristowe, Dan Sellers, Bil Simser and myself. We’ll be talking about current and upcoming developments in .NET and Microsoft technologies. Our inaugaural episode will discuss hot topics like:

  • Introducing the podcast
  • VS 2005/SQL 2005/BizTalk 2006 - Here they come!
  • SharePoint vNow and vNext
  • Drinking from the .NET 2.0 firehose
  • Half-time show
  • Security – It’s a process not a technology
  • Developing as a non-admin
  • Microsoft hardware
  • A walk down memory lane with Microsoft Bob
  • Xbox 360 – Should I get one?

Without further ado, I present to you:

Plumbers @ Work – Episode 1 – Mostly Harmless

You can catch the RSS feed here. You can leave us feedback and suggestions on the podcasts at .NET Plumbers.

So you’ve finally decided to do it – you’re going to break the addiction, join AA (Administrators Anonymous), and stop developing as a local administrator. I applaud you. I’ve been successfully developing software as a non-administrator for a number of months and I feel great. Here’s a few tips and tricks to be a successful Visual Studio developer without requiring admin privileges on your local box. First, I’m not going to re-hash some great articles that are must-reads. So go read Keith Brown’s “How to develop code as a non-admin” and Lars Bergstrom’s “Developing Software in Visual Studio .NET with Non-Administrative Privileges”.
Now for the step-by-step guide of setting yourself up to develop as a non-admin:
  1. Make sure you know your COMPUTERNAME\Administrator password. If you don’t, change it to something you do know.
  2. Add yourself to Users (not PowerUsers since PowerUsers have most of the rights of an admin), Debugger Users, VS Developers, Network Configuration Operators (optional), and Remote Desktop Users (optional).
  3. Set the local security policy to assign ownership to Administrators rather than user if user is a member of the Administrators group. Launch Administrative Tools… Local Security Policy… In the Local Security Settings MMC, browse to Security Settings… Local Policies… Security Options… System objects: Default owner for objects created by members of the Administrators group. Set this to “Administrators group”.
  4. Grant modify rights to your user to C:\Documents and Settings\All Users\Application Data\microsoft\Crypto\RSA\MachineKeys. If you do not do this, you will not be able to compile signed assemblies in Visual Studio .NET. (i.e. If you are signing your assemblies via assembly:AssemblyKeyFile and/or assembly:AssemblyKeyName in AssemblyInfo.cs or AssemblyInfo.vb, your compile will fail without the proper ACL on the MachineKeys subdirectory.)
  5. Install PrivBar.dll from here.
  6. Install MakeMeAdmin.cmd and MakeMePU.cmd from here. Also read Aaron’s follow-up.
  7. Remove yourself from the COMPUTERNAME\Administrators group.
  8. Log off and log back in again. You’re now running (and developing) as a non-administrator. Congrats!
Here’s how to accomplish a number of common tasks as a non-admin:
  • To run a single program from Windows Explorer as the COMPUTERNAME\Administrator, use Shift-Right-click “Run as…”
  • To run a single program from the command line as the COMPUTERNAME\Administrator, use runas.exe.
  • To use the administrative MMC consoles, launch from Administrative Tools using Shift-Right-click “Run as…”
  • To set ACLs, change link properties, and other file system properties, run MakeMeAdmin.cmd, launch “c:\Program Files\Internet Explorer\iexplore.exe”, and type “c:\” into the address bar. Internet Explorer will work almost identically to Windows Explorer for modifying local file system properties. This only hiccup that I’ve discovered is that folders don’t automatically refresh themselves if you add/delete/modify files and folders.
  • If you need to debug a program that opens ports or performs other adminstrator-only operations, run MakeMeAdmin.cmd and launch “c:\program files\Microsoft Visual Studio .NET 2003\Common7\IDE\devenv.exe”. Be careful as Visual Studio and any programs that it launches is now running as a local admin.

Microsoft has entered the antispyware fray with a surprisingly named product – Microsoft AntiSpyware - which is currently in beta. (After the Microsoft Bob fiasco, Microsoft has gotten a lot better at naming its products – even if the names are a tad obvious. Hmmmm… I wonder what Microsoft Content Management Server does???) Anyway Microsoft acquired GIANT Company and its antispyware product only 23 days ago, which is a quick turn-around to re-brand a product. As Scott Hanselmann points out, they missed a few spots though. Still Microsoft AntiSpyware is a welcome addition to our arsenal of tools against malware. I’m wondering how it will fare against SpyBot and AdAware.