February 2005 - Posts

How to configure your development environment to develop with least privilege

The most common objection developers hold against using a non-admin account is that they can’t develop software with a lesser privileged account. Standard user accounts do not have the sufficient privileges to debug applications or create web applications on Microsoft Internet Information Server. To configure your development environment correctly, you’ll need a good understanding of what privileges are required to perform different tasks. In this post I’ll provide a guide to configure your environment for least privileged development.

Most of the permissions needed to perform different tasks are already granted to different user groups defined on your computer. Members of the debugger users group are allowed to use Visual Studio .NET to debug processes, both locally and remotely. It is critical for all developers to have this permission, but it should not be granted to everyone because it can be exploited to gain elevated privileges. Members of the VS_Developers group can create new web applications on Microsoft Internet Information Server. Despite the name, membership in this group is not needed to do other Visual Studio .NET development, such as creating Windows Forms applications or similar. If you want to debug web applications on either Windows XP or Windows Server 2003, your user must be a granted the “Log on as batch job” privilege. This privilege is already granted to the IIS_WPG group on Windows Server 2003, so if you don’t have to explicitly give users this privilege if you add them to this group. Windows XP hasn’t got an equivalent to the IIS_WPG group, so you’ll have to grant users this privilege in Windows XP environment.

Below are guides to how you can configure your Windows XP or Windows Server 2003 development environment. Both guides require Visual Studio .NET to be installed on the development computer.

Windows XP (Service Pack 2)

  1. Log on as an administrator.
  2. If you already have a regular user account you can skip to 7
  3. Open the control panel in category view and click “User Accounts”. When instructed to pick a control panel icon, click “User Accounts” again.
  4. In the “User Accounts” dialog, open the “Users” pane and click “Add…”.
  5. In the “Add New User” wizards fill in the fields in the first step and click “Next >”. On the second pane choose the “Restricted user” option and click the “Finish” button.
  6. Change to the “Advanced” tab and click the “Advanced” button in the “Advanced user management” section.
  7. In the “Local Users and Groups” dialog, locate and double-click your user in the “Users” folder.
  8. In the “User Properties” dialog, open the “Member Of” tab.The user should be a member of the “Users” group, not the “Administrators” or “Power Users” groups.
  9. Click the “Add..” button button and type in “Debugger Users; VS Developers;” in the text box below “Enter the object names to select (examples):” caption.
  10. Click “OK” and close the “Local Users and Groups” dialog.
  11. Open the “Local Security Policy” console.
  12. Expand “Local Policies” and click “User Rights Assignment”
  13. Double-click “Log on as batch job”.
  14. From the “Log on as batch job Properties” dialog click the “Add User or Group…” button.
  15. In the “Add User or Group” type in name of your user account.
  16. Click “OK” and close the “Local Security Settings” console.

Windows Server 2003

  1. Log on as an administrator.
  2. Open the “Computer Management” console and expand “System Tools”.
  3. If you already have a regular user account you can skip to 7
  4. To create a new account, expand “Local Users and Groups”.
  5. Right-click “Users” and choose “New User”.
  6. In “New User” dialog fill in the required details and click “Create”.
  7. Double-click your existing or new user account in the “Computer Management” console.
  8. From the “User Properties” dialog, open the “Member Of” tab. The user should only be a member of the “Users” group, not “Administrators” or “Power Users”.
  9. Click the “Add” button and type in “Debugger Users; VS_Developers; IIS_WPG;” in the text box below “Enter the object names to select (examples):” caption.
  10. Click “OK” and close the “Computer Management” console.

ASP.NET 2.0 Auto Localization with culture preference stored in Profile

Localization
The best practice for creating multi culture web sites which mapped the Accept-Language headers to Thread.CurrentThread.CurrentCulture and/or Thread.CurrentThread.UICulture with ASP.NET 1.x was to set these properties before the request was handled; in an HTTP module or in a global.asax event.

void Application_BeginRequest (Object sender, EventArgs e)
{
    Thread.CurrentThread.CurrentCulture =
        CultureInfo.CreateSpecificCulture (Request.UserLanguages[0]);
    Thread.CurrentThread.CurrentUICulture =
        Thread.CurrentThread.CurrentCulture;
}

ASP.NET 2.0 makes this much easier by allowing pages to be declaratively configured to map Accept-Language headers by setting the new culture attributes of the @Page directive or globalization element in web.config to “auto”. The following declarations are functionally equivalent to the code in the preceding example.

For a single page:
<%@ Page Culture=”auto” UICulture=”auto” %>

In web.config:
<globalization culture=”auto” uiCulture=”auto” />

Whereas you had to manually read resources from a ResourceManager and assign the resource values to controls within the page in ASP.NET 1.x, ASP.NET 2.0 allows declarative mapping of control properties to resources using <%$ … %> expressions.
Automatic culture mapping and declarative resource mapping makes developing world-ready ASP.NET 2.0 sites a breeze.

Profiles
The new profile service makes a brief task of storing user settings, such as preferred culture, persistently. At first glance the profile service resembles session state since both are designed to store per-user data, but they are different. While session state stores user data for a finite period, the profile service stores it “forever”.

Profiles are defined in web.config as shown below:
<configuration>
  <system.web>
    <profile>
      <properties>
        <add name="PreferredCulture" type=”System.String” />
        <add name="FavoriteNumber" type="System.Int32" />
      </properties>
    </profile>
  </system.web>
</configuration>

When you’ve defined a profile ASP.NET dynamically compiles that profile, provides strongly typed access to it and persists the profile data. As with session state, profiles work with both anonymous and authenticated users.

The profile is easily accessed through the Profile property which ASP.NET injects into all pages that derive from System.Web.UI.Page.

Storing preferred culture in a profile
Declarative localization in ASP.NET 2.0 is achieved through yet another new feature; expression handlers and builders. Expression handlers resemble data binding expressions, but they differ in significant ways. Expression handlers is a parse-time feature, whereas data binding expressions are evaluated when the DataBind() method is called. Since expression handlers are evaluated when the page is parsed, they are called before any of the page events occur.  It is therefore too late to change culture properties of the thread in any of these events. Instead, you must either use an event handler in global.asax or an HTTP module. The following example shows how to read the PreferredCulture from the profile and set the UICulture property of the running thread:

protected void Application_PreRequestHandlerExecute(object sender, EventArgs e)
{
    if (HttpContext.Current.Profile["PreferredCulture "] != null)
    {
        Thread.CurrentThread.UICulture = CultureInfo.CreateSpecificCulture(HttpContext.Current.Profile["PreferredCulture "] as string);
    }
}

If you provide a link the user can click to change the culture, for instance ImageButtons with the flags for the available cultures, the users expect the culture to change at once. The following code resembles a typical click event handler:

private void Flag_Click(object sender, EventArgs e)
{
ImageButton button = sender as ImageButton;
 Profile.Culture = button.CommandArgument;}
}

The trouble with this approach is that, since localization happens before any of the page events, localization has already occured done when the preferred culture is changed. There are two ways to workaround this, you can either force the page to be reloaded by making it redirect to itself or intercept the new culture preference when changing thread’s culture properties.
To do a redirect, simply add the following line to the above method:

Response.Redirect(Page.AppRelativeTemplateSourceDirectory, true);

To intercept a culture setting passed as query string parameter (“__SetPreferredCulture”) in your PreRequestHandlerExecute event handler, add the following lines to the top of the method:

string newCulture = HttpContext.Current.Request.QueryString["__SetPreferredCulture"];
if (newCulture != null)
{
    HttpContext.Current.Profile.SetPropertyValue("PreferredCulture ",newCulture);
}

The localization and profile features in ASP.NET 2.0 are awesome. Even if there are you’ll have to jump through some hoops to create common multi-cultural features, such as language selection, you can still enjoy the huge benefits of ASP.NET 2.0s declarative model. After all, it’s much easier to create world-ready application with optional culture settings in ASP.NET 2.0 than in it’s this predecessors.

Firefox, Outlook Web Access and a full mailbox

I recently discovered that the e-mails I’d been sending last week never reached its recipients. The cause was that my Exchange mailbox was full and I wasn’t allowed to send any more mail until I cleaned it out. At the time I was out-of-office every single day, so I used the Outlook Web Access client. Firefox is by browser of choice, so even though the UI for “low level”* browsers such as Firefox has limited features, I choose to cope with it than the hassle of staring Internet Explorer just to read mail.

The trouble was I never got any error messages telling me that my mailbox was full so I thought that the mail I was sending actually got sent. It wasn’t, nor did it end up in my outbox nor the sent items folder, it just disappeared into oblivion.

If you’re expecting an email from me, please notify me and I’ll get back to you as soon as possible.

* Irony
The noun "irony" has 3 senses:
1. sarcasm, irony, satire, caustic remark -- (witty language used to convey insults or scorn; "he used sarcasm to upset his opponent"; "irony is wasted on the stupid"; "Satire is a sort of glass, wherein beholders do generally discover everybody's face but their own"--Johathan Swift)
2. irony -- (incongruity between what might be expected and what actually occurs; "the irony of Ireland's copying the nation she most hated")
3. irony -- (a trope that involves incongruity between what is expected and what occurs)
Source: WordNet

Non-admin wiki launched

Jonathan Hardwick has set up a wiki dedicated to using a least privileged user account.  The wiki can be found at http://nonadmin.editme.com/ and is already packed with useful information on the ins and outs of using a non-admin account.
Kudos to you Jonathan!

Do your homework Mr. Gosling

Sun CTO James Gosling described Microsoft’s decision to support C and C++ in the .NET CLR as the “biggest and most offensive mistake that they could have made” in a speech at an Australian developers event earlier this week. Gosling based his statement on that the C and C++ languages allow arbitrary casting, pointer usage and other “unsafe” features. It isn’t shocking that Suns CTO attacks their fiercest competitor in a speech, but he should do his homework more carefully to come across as credible. I know many Java developers, and just as many .NET developers know Java, most of them they are .NET literates.
Gosling’s assumption is that having a programming language which allows programmers to do unsafe things makes all code hazardous. This is wrong. The key cause of security holes is that many programmers aren’t security savvy. Although you seldom get buffer overruns in managed environments, you can create gaping security holes, such as cross site scripting and SQL injection vulnerabilities, in software developed with both Java and C#. Managed code is a safe-guard against unforeseen side effects, but it’s not a panacea for unsecured code.
A key feature in Microsoft Visual C++ 2005, Gosling “forgot about”, is Secure CRT. C++ now has an entire set of secure alternatives to the old C library functions such as strcpy. So the decision to still support C and C++ in Visual Studio 2005 is far from security vulnerability, it’s an effort to make C++ programming more secure!
Most .NET developers stick to managed code. I can only recollect having used the unsafe keyword a couple of times. While managed environments constantly break new ground, there are scenarios where the low-level C or C++ is the only option for performance, memory usage or other reasons. In such a scenario James Gosling would probably tell you that “this cannot be done”. The rest of us, Java or .NET developer alike, can reach for our trusty C++ compiler and get things done. Thanks to the efforts of Microsoft’s library team writing safe C++ code is easier than ever. This is probably why Gosling is so scared.

Chubby Client term slowly getting adopted

When I conceptualized smarter web clients I coined the term “Chubby Client” to describe such applications. At the time, the only other paper using the term was an old IBM paper on terminal clients. Lately, I have seen the term used in around the blogosphere. Longhorn evangelist Jerry Mazner recently wrote a blog post about different Smart Clients and smarter web clients entitled “Smart Client”. Scott Hanselman used the term last year when he wrote about my JavaScript XmlSerializer and many others have followed in his footsteps.
Earlier this week the editor-in-chief of a major programming journal asked me if I was interested in reworking my post about Google Suggest into a proper article. This goes to show that aided by Google’s innovative betas, Microsoft’s cool MySpaces and similar “smarter” web clients the “Chubby Client” concept is gaining interest. Now I need your help to make the term "Chubby Clients" common place.