Sunday, February 25, 2007

IE7 and local Proxies (e.g. Fiddler)

This is just a repeat of a german blog post by Marc Höppner - but I never read this elsewhere and it is so incredibly useful....

IE7 always bypasses proxies for "localhost" addresses. Regardless of configuration. Now when you want to use e.g. Fiddler with a local web app, this can become an issue.

If you are using IIS it's easy, just use the local machine name instead of "localhost" (something I usually do anyways because of SSL). But Cassini doesn't accept machine names - the (quite funny) workaround for that is to use "localhost." (note the dot) instead. Works fine....

 


Work in Progress
Sunday, February 25, 2007 11:05:27 AM UTC  #   
 Friday, February 23, 2007

MSDN US WebCast: ASP.NET Security - Storing Secrets

As always, the slides and demos I showed can be downloaded here.

See you next time!

 


Work in Progress
Friday, February 23, 2007 7:43:44 PM UTC  #   
 Thursday, February 22, 2007

MSDN US WebCast: ASP.NET Security - Input Validation

Thanks to all attendees - find the slides and source here.

See you next time!

 


Work in Progress
Thursday, February 22, 2007 8:34:00 PM UTC  #   

MSDN WebCast: ASP.NET Security 4 - Logging und Instrumentation

So es ist geschafft - vier WebCasts zu ASP.NET Security. Mir hat es Spass gemacht und ich hoffe für euch war etwas interessantes dabei!

Wie immer Slides und Code hier - und die ganze Serie im Überblick mit WMV download gibt es hier (ich hoffe der bleibt stabil...).

 


Microsoft Deutschland Security Portal
Thursday, February 22, 2007 4:34:19 PM UTC  #   

New (and finalized) CardSpace Resources

Recently Kim released the finalized versions of the CardSpace spec documents – get them here:

  • Information Card Profile V1.0 Technical Reference (here)
  • A Guide to Interoperating with the Infomation Card Profile V1.0 (here)
  • Guide to Supporting Information Cards within Web Applications and Browsers (here)

In addition there are now two sample Security Token Services you can play with:

Have fun…


For Your Favourites
Thursday, February 22, 2007 9:15:50 AM UTC  #   
 Wednesday, February 21, 2007

IIS7: Custom Worker Accounts and User Profiles

One of my favorite feature of IIS7 (well, there a lot) is that user profiles are now loaded for the worker process accounts. Why is this important?

A lot of the Windows functionality (and in my case – security features) depend on loaded profiles, e.g. DPAPI user keys and per user certificate/key stores. Prior to IIS7 you were always forced to use DPAPI machine keys (with application defined entropy) or to store application certificates in the machine store (and manually ACLing the private keys). This also affects the protected configuration feature which relies either on DPAPI keys or the key store. Per application pool profiles (and thus keys) makes isolating applications on a server now much easier.

Another interesting fact is that IIS7 injects the required group (called IIS_IUSRS) into the worker process account – in IIS6 you had to manually add the worker process account into IIS_WPG group.

To demonstrate all this I hacked a little proof of concept web site together that shows the worker process groups and uses the ProtectedData APIs, protected configuration and the X509Store class to query the user certificate store. Nice!

IIS7UserProfilesTest.zip (3.17 KB)

 


Work in Progress
Wednesday, February 21, 2007 12:12:03 PM UTC  #   
 Tuesday, February 20, 2007

MSDN US WebCast: Authentication and Authorization with ASP.NET 2.0

Thanks for attending the first webcast in my mini series!

Find the slides and code here.

 


Work in Progress
Tuesday, February 20, 2007 8:55:19 PM UTC  #   
 Wednesday, February 14, 2007

My 1st MSDN Magazine Article

The march issue of MSDN Magazine has just been released - it includes an article about certificates support in the .NET Framework I wrote a while ago.

I think MSDN Magazine is great and I am really happy this worked out...

http://msdn.microsoft.com/msdnmag/issues/07/03/NETSecurity/default.aspx

 


For Your Favourites | Work in Progress
Wednesday, February 14, 2007 11:07:19 PM UTC  #   
 Monday, February 12, 2007

DevelopMentor and Me

After my last post I received some emails asking me if I have left DevelopMentor …

No – that’s not the case! I am still taking care of their security curriculum and I am still teaching/authoring WCF, .NET Security and ASP.NET. Great people work at DM that I would really miss – besides the fact that I really enjoy teaching and helping people understand technologies that I find interesting.

Since I am doing consulting only for Thinktecture and training only for DevelopMentor there is no overlap at all.

 


Work in Progress
Monday, February 12, 2007 10:58:35 PM UTC  #   

Thinktecture and Me

I know Christian and Ingo for quite some time now. I respect their work and knowledge and (equally important) we always have a good time when we meet (late nights and high hotel/mini bar bills included).
Since security is part of every serious project today, I often helped the guys out when they had questions about Windows, ASP.NET or WCF security. So it seemed like a logical step to “officially” join them as a consultant. Since today the new website is online and you can have a look at which services we offer.

www.thinktecture.com


Work in Progress
Monday, February 12, 2007 1:36:00 PM UTC  #   
 Thursday, February 08, 2007

Admin Title Bar for PowerShell

I like this feature in Vista that elevated command prompts have the word "Administrator" in the title bar. This seems to be some special functionality baked into the command prompt - at least this does not work when starting PowerShell elevated.

This little script can do the trick - just call it from your profile.ps1:

$id = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$p = New-Object System.Security.Principal.WindowsPrincipal($id)

if ($p.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator))
{
 $Host.UI.RawUI.WindowTitle = "Administrator: " + $Host.UI.RawUI.WindowTitle
}

Thanks to Christian for the title bar code.

 


Work in Progress
Thursday, February 08, 2007 5:15:50 PM UTC  #   
 Tuesday, February 06, 2007

CardSpace and OpenID

A step in the right direction. Handing over to Kim.

 


For Your Favourites
Tuesday, February 06, 2007 7:52:26 PM UTC  #   

SPNs and IIS

Good KB article.

(via Doug Stewart)

 


For Your Favourites
Tuesday, February 06, 2007 11:08:11 AM UTC  #   
 Monday, February 05, 2007

ASP.NET Security Context Troubleshooting Tool

I slightly updated ShowContexts.aspx recently during some IIS7 research work. So I thought I post the new version here.

Features:

  • shows authentication and impersonation settings
  • shows configured role and membership providers
  • shows configured trust level (well - for completeness only - you need full trust for this page to work correctly)
  • shows the IPrincipal/IIdentity types on Context.User and Thread.CurrentPrincipal
  • shows the name and authentication type on Context.User and Thread.CurrentPrincipal
  • shows the thread identity (when impersonation is enabled)
  • shows the IIS LogonUser identity (used by FileAuthorizationModule)
  • shows the client cert (and some embedded information like the UPN if available)
  • shows roles (for Windows-, Roles and GenericPrincipal)
  • allows to save an aggregated config.web (with all settings from machine.config down to the vdir)
  • can set a FormsAuthentication ticket to simulate authentication

HTH

ShowContexts212.zip (2.67 KB)

 


Tools | Tools for Thinktecture
Monday, February 05, 2007 8:53:26 PM UTC  #   

Certificate Revocation and Status Checking

Thanks to Enno Rey for this excellent link. Haven't even fully read it yet, but seems to be THE document on the subject. For future reference.

 


For Your Favourites
Monday, February 05, 2007 8:35:40 PM UTC  #   
 Thursday, February 01, 2007

ASP.NET Security Webcast Teil 3 - Speichern von Daten

Wie immer - danke an alle Teilnehmer! Ich habe auch schon erste Rückmeldungen von Buchgewinnern erhalten...freut mich das das gut funktioniert!

Slides und Code: hier

Bis zum nächsten Mal...

 


Microsoft Deutschland Security Portal
Thursday, February 01, 2007 5:05:39 PM UTC  #   

MSDN US ASP.NET Security Webcasts

In february/march I am doing a 5-part Webcast series about ASP.NET Security for MSDN US. Maybe see you there...

The following topics are planned:

Authentication & Authorization
In this webcast, we explore how Microsoft ASP.NET 2.0 features a flexible authentication and authorization architecture that supports Windows, certificates, and custom credential types. Discover how, with the provided abstraction layers in ASP.NET, your application page code does not have to be aware of any authentication implementation details. Join this session to learn how you can take full advantage of these capabilities. We explain how the HTTP pipeline and its extensibility points work. We look at how the built-in authentication mechanisms function, and we examine how to extend them for enabling single sign-on (SSO) and Web farm scenarios. We also show you how to implement custom and mixed-mode authentication, role handling, and protection of other resources. (register)

Tuesday, February 20, 2007
11:00 AM Pacific Time (US & Canada)

Input Validation
Malicious or unexpected input is the reason for most of the stability and security problems in applications. How often do your applications crash because of logic problems compared to problems caused by malformed input? Many serious attacks rely on flawed or non-existent input validation in applications or how applications handle specially crafted input values. Join this webcast to learn about the most common input-validation attacks, like SQL injection, HTML injection, cross-site scripting, and directory traversal, in addition to the corresponding mitigation techniques. We examine the input validation mechanisms built into Microsoft ASP.NET, including request, ViewState, and event validation, and we look at the validation control infrastructure and its extensibility. (register)

Thursday, February 22, 2007
9:00 AM Pacific Time (US & Canada)

Storing Secrets
As an application developer you are responsible for many secrets, that is, sensitive information such as payroll, intellectual property, passwords, or configuration. Join this webcast to see how Microsoft ASP.NET can help you reduce the exposure of such data with hashing and encryption techniques. We explore the high-level data protection services in ASP.NET, including Data Protection API (DPAPI) and the protected configuration feature. Cryptography alone does not solve problems, but it can be effective in combination with the right architecture and management procedures. In this session, we examine approaches for different scenarios and explain how the APIs work to help you secure sensitive data. (register)

Friday, February 23, 2007
10:00 AM Pacific Time (US & Canada)

Error Handling, Logging & Instrumentation
In this webcast, we discuss best practices that can help you write more secure software. Building detection and reaction mechanisms that signal errors or attack conditions into your applications empowers you to diagnose and fix problems much more easily. We describe how these detection and reaction mechanisms are as important as prevention techniques, like authentication or input validation. Learn how Microsoft ASP.NET and the Windows platform offer many different error-handling and logging capabilities, like the event log, Windows Management Instrumentation (WMI), diagnostics tracing, or the performance monitor. Join this session to see which of these tools is most appropriate for certain situations. We also examine the Health Monitoring Framework, a new feature in ASP.NET that enables abstracting and extending your logging infrastructure through a unified API and a provider-based approach. (register)

 Monday, March 05, 2007
11:00 AM Pacific Time (US & Canada)

Partial Trust
Attend this webcast to discover one of the most overlooked security features of Microsoft ASP.NET, code access security (CAS). By default, your applications have access to powerful functionality, like calling out to arbitrary unmanaged code, accessing code in other application domains, and accessing every feature of the Microsoft .NET Framework. Join us to see how you can use CAS to disable dangerous APIs, or restrict them to only the features you need. We illustrate how this dramatically reduces the attack surface and enables you to use the principle of least privilege and defense-in-depth design. Also, learn about the dangers of running in full trust and get an introduction to partial trust, its configuration, and its extensibility. In this session, we explore common scenarios for using CAS to show you how it is possible to write feature-rich applications while running in a secure sandbox. (register)

 Tuesday, March 06, 2007
10:00 AM Pacific Time (US & Canada)

 


Work in Progress
Thursday, February 01, 2007 9:46:01 AM UTC  #   
 Tuesday, January 30, 2007

The universal Rules of Input Validation

...still apply ;)

(think XSS, SQL injection and friends...)

Everything that is not known at compile time is input...that of course includes InfoCards (and certificates btw too).

 


Misc
Tuesday, January 30, 2007 4:59:06 PM UTC  #   
 Monday, January 29, 2007

ASP.NET Security WebCast Teil 2 - Eingabe Validierung

Danke an alle Teilnehmer!

Slides und Code findet Ihr hier.

Bis zum nächsten mal...

 


Microsoft Deutschland Security Portal
Monday, January 29, 2007 4:41:11 PM UTC  #   
 Sunday, January 28, 2007

Adding Error Messages to a ValidationSummary

Validation summaries are nice when you are using the ASP.NET validation controls. It would be also quite handy to add your own validation/error messages (from internal validation or exception handling) to a summary. With a little background knowledge about the ASP.NET validation infrastructure, this is easily possible.

All validation controls implement the IValidator interface and add themselves to the Page.Validators collection at page creation time. IValidator has three members: IsValid, ErrorMessage and Validate(). When validation occurs, the Validate() method of each control is called which in turn sets the IsValid and ErrorMessage property. At render time the ValidationSummary cycles through the Validators collection and looks for controls where IsValid is set to false. If that's the case, the value of the ErrorMessage property is rendered to the summary.

To add a new error message, you simply have to add an IValidator derived class to the Validators collection (with IsValid = false) and let the summary pick it up. The following small helper class accomplishes that:

// adds an error message to a ValidationSummary control

public class ErrorSummary : IValidator

{

    string _message;

 

    public static void AddError(string message, Page page)

    {

        ErrorSummary error = new ErrorSummary(message);

        page.Validators.Add(error);

    }

 

    private ErrorSummary(string message)

    {

        _message = message;

    }

 

    public string ErrorMessage

    {

        get { return _message; }

        set { }

    }

 

    public bool IsValid

    {

        get { return false; }

        set { }

    }

 

    public void Validate()

    { }

}

You can use the class in your code like that:

catch (Exception ex)

{

    // logging

 

    ErrorSummary.AddError("error message", this);

    return;

}

 


Work in Progress
Sunday, January 28, 2007 8:37:26 AM UTC  #   
 Saturday, January 27, 2007

Source Code Navigation

OK – this is nothing new at all – more a note to self…

Source code navigation in VS is cumbersome…I want hyperlinks for methods, classes, properties etc. – and I want a browser like back/forward navigation. Is this available in VS and I am missing something?

I really like the way you can navigate code in Reflector and I use it often to look at my own source code. Reflector also supports .PDB files which means your variable names etc. are shown correctly in Reflector (unlike string1 to n).

You can easily invoke Reflector from VS for browsing – just add a custom tool entry for Reflector to the Tools menu – set the argument to TargetPath and the working directory to TargetDir – and enable .PDB support in Reflector…nice.

I really wish Lutz would work on Visual Studio to improve such basic things…


Misc
Saturday, January 27, 2007 7:47:35 AM UTC  #   
 Wednesday, January 24, 2007

WebCasts im Februar

Die ASP.NET Security Serie geht im Februar weiter. Auf dem Programm steht:

Security mit ASP.NET 2.0 (Teil 3-4) - Sicheres Speichern von Daten mit ASP.NET 2.0
(1.2.2007 / 16.00)
Als Entwickler ist man ein regelrechter Geheimniskrämer – man muss tagtäglich mit Daten wie Adressen, Kreditkarten und Passwörtern umgehen oder gar medizinische oder finanzielle Information verwalten und speichern. Das .NET Framework bietet einige Einrichtungen, um vertrauliche Daten besser zu schützen. Dies umfasst Hashing- und Verschlüsselungs-Algorithmen sowie einige Hilfs-APIs. Nun kann Kryptografie allein keine Probleme lösen, aber - kombiniert mit der richtigen Architektur - Ihren Daten Sicherheits-Mehrwert hinzufügen. Dieser Webcast gibt einen Überblick über die relevanten Techniken und sagt, wo, wann und wie diese am besten eingesetzt werden. (Anmelden)

Security mit ASP.NET 2.0 (Teil 4-4) - Fehlerbehandlung, Logging und Instrumentierung für ASP.NET 2.0 Anwendungen
(22.2.07 / 16.00)
Es ist unmöglich, hundertprozentig sichere Software zu schreiben. Wenn man allerdings Erkennungs- und Benachrichtigungs-Mechanismen in die Anwendung designed, wird es zumindest bedeutend einfacher, Probleme zu erkennen und zu beheben. ASP.NET und die Windows-Plattform bieten eine Vielzahl von Fehlerbehandlungs- und Logging-Mechanismen, z.B. das Event Log, WMI oder den Performance Monitor. Allerdings sind diese APIs fragmentiert und es ist nicht einfach, den ausgewählten Mechanismus zu ändern, um sich Kunden- oder Netzwerk-Anforderungen anzupassen. Dieser Webcast gibt einen Überblick über Fehlerbehandlung in ASP.NET sowie die verschiedenen Logging-Mechanismen. Weiterhin wird das ASP.NET Health Monitoring Framework vorgestellt, das einen einzigen API für viele Logging-Technologien ermöglicht und durch einen Provider-basierten Ansatz leicht erweiterbar ist. (Anmelden)

 


Microsoft Deutschland Security Portal
Wednesday, January 24, 2007 5:18:07 AM UTC  #   
 Tuesday, January 23, 2007

IIS7 Managed Extensibility: ServerHeader Feature

Below you can find the complete source code and an experimental installation project for the ServerHeader feature i described in the last posts.

Have fun.

ServerHeader.zip (73.26 KB)

 


Work in Progress
Tuesday, January 23, 2007 7:57:40 PM UTC  #   
 Monday, January 22, 2007

IIS7 Managed Extensibility: Deployment

OK – let’s face it – deployment is no fun. The fact that in addition APIs are fragmented, inconsistent or simply missing doesn’t make it more entertaining. But here are the general steps that are necessary to deploy an IIS7 feature.


Register all assemblies in the GAC
See my previous post for more details.

Register the configuration extension
This is a two step process – first you have to copy the schema file to the schema directory

%SystemDrive%\%windir%\system32\inetsrv\config\schema

The next step is to register the section in the <configSections> element in applicationHost.config. Unfortunately there is no API to do that currently (but will be available in “Longhorn Server” starting with Beta 3). So XmlDocument is your friend….

private void RegisterApplicationHost()

{

    XmlDocument doc = new XmlDocument();

    doc.Load(_applicationHost);

 

    XmlNode node = doc.SelectSingleNode(

      "configuration/configSections/sectionGroup[@name='system.webServer']");

 

    XmlElement configNode = doc.CreateElement("section");

    configNode.SetAttribute("name", _configSectionName);

    configNode.SetAttribute("overrideModeDefault", "Allow");

 

    node.AppendChild(configNode);

 

    doc.Save(_applicationHost);

}

The resulting section looks like this.

<sectionGroup name="system.webServer">

  <section name="serverHeader" overrideModeDefault="Allow" />

 

Register the HttpModule
The HttpModule can be registered in applicationHost.config if you want it to be available machine wide. Otherwise you would register it in a down-level web.config. The following code uses the ServerManager class in Microsoft.Web.Administration to access applicationHost.config and to add the module:

private void RegisterHttpModule()

{

    ServerManager manager = new ServerManager();

 

    // get access to applicationHost.config

    Configuration config = manager.GetApplicationHostConfiguration();

 

    // install the module

    ModulesSection sectionModules = (ModulesSection)

        config.GetSection(ModulesSection.SectionName, typeof(ModulesSection));

 

    sectionModules.Modules.Add(_httpModuleName,

        _httpModuleType,

        "");

 

    manager.CommitChanges();

}

The result should look like this:

<system.webServer>

  <modules>

    <add name="ServerHeaderModule"

         type="LeastPrivilege.ServerHeader.ServerHeaderModule, … " />

  </modules>

</system.webServer>

Register the Management Extension
The last step is to add a reference to the ServerHeader module provider to administration.config. Again ServerManager can be used to access this configuration file (this time using the GetManagementConfiguration() method). The code is very similar to the previous one so I will omit this here.

The result should look like this:

<moduleProviders>

  <add name="ServerHeader" type="… " />

 

 

<location path=".">

  <modules>

    <add name="ServerHeader" />

The above procedures can be e.g. used in a VS installer project (using custom actions).

Next Post: the complete solution (finally)...

 


Work in Progress
Monday, January 22, 2007 7:08:28 AM UTC  #   
 Friday, January 19, 2007

IIS7 Managed Extensibility: Solution Structure

OK – let's wrap up the last posts.

An IIS7 feature consists of three assemblies:

  • The HttpModule/Handler
  • Server Management
  • Client UI

All three assemblies should be in the GAC (you can avoid the GAC for the HttpModule/Handler) if you only want to use it locally in an application, but the other two must be in the GAC. So you need a strong name (all the usual security implications apply…).

I think the following assembly/namespace naming and separation of functionality makes sense (and also mostly resembles the layout of the built-in features):

  • HttpModule Assembly
    Name: LeastPrivilege.ServerHeader.dll
    Namespace: LeastPrivilege.ServerHeader
    Contents: HttpModule
  • Server Management Assembly
    Name: LeastPrivilege.ServerHeader.Management.dll
    Namespace: LeastPrivilege.ServerHeader.Management
    Content: ModuleService, ModuleProvider, ConfigurationSection*
  • Client UI
    Name: LeastPrivilege.ServerHeader.ManagementClient.dll
    Namespace: LeastPrivilege.ServerHeader.Management
    Content: Module, ModuleProxy, UI

* I chose to put the ConfigurationSection into the server management assembly. The HttpModule has a dependency on that class but this is OK since the HttpModule and the server management assembly will always be on the same machine.

Next post: Deployment (sigh).


Work in Progress
Friday, January 19, 2007 10:25:38 AM UTC  #   
 Thursday, January 18, 2007

IIS7 Managed Extensibility: Client UI Integration


In the preceding posts we implemented the HttpModule, the configuration section and the server module including the server service – the last part of the integration story is the UI.

UI integration consists of three parts:

  • UI elements
  • The service proxy that is used by the UI to talk to the server service
  • A module that registers the UI with the IIS GUI

Let’s start with the proxy. The proxy provides an interface for the UI to read and write configuration. The proxy then marshals the requests to the IIS management server who in turn does the real work. You call the server methods you implemented in the service via the ModuleServiceProxy base class. The proxy for our ServerHeader feature looks like this:

class ServerHeaderModuleProxy : ModuleServiceProxy

{

    public PropertyBag GetConfiguration()

    {

        return (PropertyBag)base.Invoke("GetConfiguration", new object[0]);

    }

 

    public void SetConfiguration(bool enabled, string headerValue)

    {

        base.Invoke("SetConfiguration", new object[] { enabled, headerValue });

    }

}

For the UI elements you have several choices of how to integrate with the GUI. If you inspect the several feature settings pages you can spot several general types of UIs – dialogs, lists, property grids and features with sub-features (e.g. authentication). Depending on which type of UI you want, you derive from one of these base classes:

-          ModulePage
offers only the most basic services, no standard UI support

-          ModuleDialogPage
similar to a dialog, provides apply, cancel and refresh functionality, e.g. Session State, Directory Browsing

-          ModulePropertiesPage
uses a property grid, e.g. Compilation, Pages & Controls

-          ModuleListPage
uses a list view, useful for collections, e.g. Connection Strings, Handlers

I chose to use a ModuleDialogPage. This gives you a dialog that you can populate with standard WinForms controls. By implementing some of the base class methods you get nice support for the standard Apply/Cancel/Refresh UI elements in the IIS GUI. The complete class is a lot of code (mostly related to standard UI stuff), so I will only show you the important parts of it (the complete solution can be downloaded when the series is complete).

The easiest way is to start with a WinForms Form so that you can use the designer to layout your dialog. Afterwards copy the control declarations and InitializeComponent() to your ModuleDialogPage derived class. Furthermore you need access to the service proxy to issue calls to the configuration service. So your class would look similar to this:

class ServerHeaderPage : ModuleDialogPage

{

    private ServerHeaderModuleProxy _serviceProxy;

 

    // UI

    private System.Windows.Forms.CheckBox _chkEnabled;

    private System.Windows.Forms.Label _lblHeaderValue;

    private System.Windows.Forms.ComboBox _cmbHeaderValue;

 

    // state

    bool _enabled;

    string _headerValue;

 

    public ServerHeaderPage()

    {

        InitializeComponent();

    }

 

    private ServerHeaderModuleProxy ServiceProxy

    {

        get

        {

            if (this._serviceProxy == null)

            {

                this._serviceProxy = (ServerHeaderModuleProxy)

                    base.CreateProxy(typeof(ServerHeaderModuleProxy));

            }

            return this._serviceProxy;

        }

    }
}

Next you need two methods to read and write configuration – this is as simple as calling the corresponding methods on your proxy class, e.g.

private void ReadConfig()

{

    PropertyBag bag = ServiceProxy.GetConfiguration();

 

    _enabled = _chkEnabled.Checked = (bool)bag[0];

    _headerValue = _cmbHeaderValue.Text = (string)bag[1];

}

 

private void WriteConfig()

{

    ServiceProxy.SetConfiguration(_chkEnabled.Checked, _cmbHeaderValue.Text);

}

The base class also offers support for asynchronous operations. This helps keeping the UI responsive when you exchange more complex data or have a slow connection. Remodeling the WriteConfig() method to async looks like this:

private void WriteConfig()

{

    base.StartAsyncTask("writing configuration...",

        OnWriteConfigDoWork,

        OnWriteConfigCompleted);

}

 

void OnWriteConfigDoWork(object sender, DoWorkEventArgs e)

{

    ServiceProxy.SetConfiguration(_chkEnabled.Checked, _cmbHeaderValue.Text);

}

 

void OnWriteConfigCompleted(object sender, RunWorkerCompletedEventArgs e)

{

    if (e.Error != null)

    {

        this.DisplayErrorMessage(e.Error, Resource.ResourceManager);

    }

}

To help the GUI to enable/disable the Apply/Reset/Cancel labels you also have to implement methods that signal the host that settings have changed. The methods are called OnActivated/HasChanges/CanApplyChanges and ApplyChanges/CancelChanges. This mainly boils down to keeping two versions of the configuration data – the original and the read one – and to signal the GUI if changes have been done. You should also hook up control change event handlers to the UI controls to update the status in realtime.

The last step is to register the UI with the IIS manager. This is done in a Module derived class, and this is btw the type you specified in ModuleProvider.GetModuleDefinition(). The main job of this class is to get a reference to the IIS manager control panel and to register the UI in one (or more) of the available categories.

class ServerHeaderModule : Module

{

    protected override void Initialize(

      IServiceProvider serviceProvider, ModuleInfo moduleInfo)

    {

        base.Initialize(serviceProvider, moduleInfo);

       

        // get access to the control panel

        IControlPanel panel = (IControlPanel)

            serviceProvider.GetService(typeof(IControlPanel));

 

        // create a module description (name, icon, description etc)

        ModulePageInfo info = new ModulePageInfo(

            this,

            typeof(ServerHeaderPage),

            "ServerHeader",

            "Allows to change the Server Response Header",

            Resource.ServerHeaderIcon,

            Resource.ServerHeaderIcon);

       

        // register in the security category

        panel.RegisterPage(ControlPanelCategoryInfo.Security, info);

       

        // register in the IIS category

        panel.RegisterPage(ControlPanelCategoryInfo.Iis, info);

    }

 

    public override Version MinimumFrameworkVersion

    {

        get

        {

            return Module.FxVersion20;

        }

    }

}

The assembly implementing these classes needs to be registered in the GAC.

So that’s it – we now have a full blown IIS7 feature. The code that is needed is mostly boilerplate and I hope this walkthrough is helpful when building your own IIS features. In the next post I will talk about the general solution infrastructure, how many assemblies you should use and which class goes where.

 


Work in Progress
Thursday, January 18, 2007 8:43:21 AM UTC  #   
 Wednesday, January 17, 2007

ASP.NET Webcasts Teil 1 - Authentifizierung und Autorisierung

Vielen Dank an alle Teilnehmer - vielleicht bis zur nächsten Episode!

Slides und Code finden Sie hier.

 


Microsoft Deutschland Security Portal
Wednesday, January 17, 2007 4:39:37 PM UTC  #   

IIS7 Managed Extensibility: Server Management Integration


The IIS management framework allows configuring the web server using the IIS7 GUI. To understand the code that needs to be written, you have to know more about the management architecture.

The IIS GUI allows configuring local and remote servers (the remote functionality is not included in Vista). The local case is easy and boils down to accessing the local configuration and state data. In the remote case, the IIS GUI opens a SSL connection to the remote server and uses a web service style protocol to talk to a service on the remote machine that does the configuration. The current plans are that the client can automatically download all the client parts from the server on the first connection. On subsequent connections the IIS GUI checks for updated and new features.

This is the reason why management modules will always have two logical parts. The server part implements some registration code and the configuration service. The client part consists of the UI that will be integrated into the IIS GUI and a service proxy to talk to the server configuration service. In the local case the proxy->service communication will be short-circuited to local calls.

BTW – in the remote scenario, the client will not directly talk to the “real” IIS but to a small, customized management server running on the same machine. This guarantees remote access even if the “real” IIS should be unresponsive.

OK – so first you should implement your module service. This is a simple class which reminds a little of .asmx web services. Every method that should be callable from the service proxy has to be decorated with a [ModuleServiceMethod] attribute. Inside the service methods you read or write the configuration. I have not extensively tested this, but it seems you can use any serializable type to transmit data between the service and the proxy. To minimize dependencies between the client and the server I would recommend using a data structure that comes with the BCL like a Dictionary<>. In this simple example I chose a PropertyBag. I omitted the configuration code since this works exactly as in the HttpModule, but this time you get the current configuration (in the context of the application you manage) from base.ManagementUnit.Configuration.

class ServerHeaderModuleService : ModuleService

{

    [ModuleServiceMethod(PassThrough = true)]

    public PropertyBag GetConfiguration()

    {

        PropertyBag bag = new PropertyBag();

 

        bag[0] = Configuration.Enabled;

        bag[1] = Configuration.Value;

 

        return bag;

    }

 

    [ModuleServiceMethod(PassThrough = true)]

    public void SetConfiguration(bool enabled, string headerValue)

    {

        Configuration.Enabled = enabled;

        Configuration.Value = headerValue;

 

        base.ManagementUnit.Update();

    }

}

Another class you have to implement is a module provider. This class does the registration of the service and the client UI module. Furthermore you can also specify at which configuration level (machine, site, application) the module should be available. There are several base classes to derive from – most commonly you will use ConfigurationModuleProvider – this is the base class of all built-in modules and gives you feature delegation support.

class ServerHeaderModuleProvider : ConfigurationModuleProvider

{

    // returns the name of the configuration section

    protected override string ConfigurationSectionName

    {

        get { return ServerHeaderConfigurationSection.SectionName; }

    }

 

    // returns the fqn of the corresponding client (UI) module type

    public override ModuleDefinition GetModuleDefinition(IManagementContext context)

    {

        string clientname = "…";

       

        return new ModuleDefinition(base.Name, clientname);

    }

 

    // hooks up the module service

    public override Type ServiceType

    {

        get { return typeof(ServerHeaderModuleService); }

    }

 

    // specifies at which level the module should be available

    public override bool SupportsScope(ManagementScope scope)

    {

        return true;

    }

 

    public override string FriendlyName

    {

        get { return "ServerHeader"; }

    }

}

Configuration modules need to be registered in the GAC.

The last step is to register the module in administration.config (\windows\system32\inetsrv\config). You have to modify two configuration sections named <moduleProviders> and <modules> like this:

<moduleProviders>

  <!-- Custom Modules -->

  <add name="ServerHeader" type="… " />

 

<location path=".">

  <modules>

  <!-- Custom Modules -->

  <add name="ServerHeader" />

 

 

OK – now we have finished the server side of the management integration. But on its own – the server module is not very useful. In the next post I will show you how to write the corresponding UI integration and proxy to talk to the configuration service.

 


Work in Progress
Wednesday, January 17, 2007 9:05:01 AM UTC  #   
 Tuesday, January 16, 2007

IIS7 Managed Extensibility: Extending Configuration


I showed you the HttpModule on which this walkthrough is based on in the last post. This module is always active once it is registered and changes the Server header to a hardcoded value. It would be nice if the value and the ‘enabled’ status could be read from a configuration file. In this post I will show you the bits and pieces you have to do to add a new configuration section and make this section available to the IIS7 command line configuration tool and the configuration API.

OK – so first of all you should have an idea how your configuration section looks like, I chose the following design (inside of system.webServer):

<serverHeader enabled="true" value="www.leastprivilege.com" />

To make the IIS configuration system “understand” this config section, you have to provide a schema file. This file describes the layout of the section and things like required values, default values, value boundaries and more. Unfortunately there is no documentation of the XML vocabulary used – but if you look at \windows\system32\inetsrv\config\schema – you can inspect the schema used for the built-in section and get an idea of the options you have. The XML schema file for our section looks like this:

<configSchema>

  <sectionSchema name="system.webServer/serverHeader">

    <attribute name="enabled" type="bool" defaultValue="false" />

    <attribute name="value" type="string" defaultValue="www.leastprivilege.com" />

  </sectionSchema>

</configSchema>

Copy this file to the above location. The next step is to register the configuration section in applicationHost.config (\windows\system32\inetsrv\config). Search for the system.webServer section group and add a new section underneath, like this:

<sectionGroup name="system.webServer">

  <section name="serverHeader" overrideModeDefault="Allow" />

 

 

From that point the native configuration system can handle your config section and tools like appcmd.exe know about it, e.g. you can show the standard settings of your section (according to the schema definition) with:

appcmd list config /section:serverHeader /config:*

To set configuration for an application use:

appcmd set config "Default Web Site/App" -section:serverHeader /enabled:true /value:SomeServer

You can now also use the APIs in Microsoft.Web.Administration to read/write the configuration section programmatically (I wrote more about the options here). To get a strongly typed wrapper for the configuration section you have to add a mapper class that derives from ConfigurationSection. The class is very simple and looks like this:

public class ServerHeaderConfigurationSection : ConfigurationSection

{

    public static readonly string SectionName = "system.webServer/serverHeader";

 

    public bool Enabled

    {

        get { return (bool)base["enabled"]; }

        set { base["enabled"] = value; }

    }

 

    public string Value

    {

        get { return (string)base["value"]; }

        set { base["value"] = value; }

    }

}

Now we can add configuration functionality to the HttpModule. First of all I added a property that retrieves the current configuration. I used the WebConfigurationManager class found in Microsoft.Web.Administration. This is the light-weight read-only API that always gives you an aggregated view of all configuration settings in effect (regardless of at which level they were configured). This API also works in partial trust scenarios.

private ServerHeaderConfigurationSection _configuration = null;

 

protected ServerHeaderConfigurationSection Configuration

{

    get

    {

        if (_configuration == null)

        {

            _configuration =

                (ServerHeaderConfigurationSection)WebConfigurationManager.GetSection(

                    HttpContext.Current,

                    ServerHeaderConfigurationSection.SectionName,

                    typeof(ServerHeaderConfigurationSection));

        }

 

        return _configuration;

    }

}

The OnLeave event handler can now read from config and act accordingly:

void OnLeave(object sender, EventArgs e)

{

    if (!Configuration.Enabled)

        return;

 

    // set header

    HttpContext.Current.Response.Headers.Set("Server", Configuration.Value);

}

OK – that’s it for now. We have completed two important steps – added a general request processing module to IIS and made this module available to the configuration system. In the next post I will show you how to integrate the module configuration into the IIS server side management system.

 


Work in Progress
Tuesday, January 16, 2007 9:01:21 AM UTC  #   
 Monday, January 15, 2007

IIS7 Managed Extensibility: The HttpModule

Writing a module that can intercept requests in IIS7 is very easy. In fact, for people that have written HttpModules in ASP.NET before – this is nothing new at all.

The general idea is that you write a class that implements the IHttpModule interface and register it in the <modules> section in configuration. This interface defines two methods, Init and Dispose. Init is called during application startup and is used to hook up an event handler to one of the various request processing events, e.g. BeginRequest, AuthenticateRequest etc. In Dispose you get the chance to do resource cleanup if needed.

namespace System.Web

{

    public interface IHttpModule

    {

        void Dispose();

        void Init(HttpApplication context);

    }
}

Since the ServerHeader module wants to change the HTTP response headers, it seems appropriate to inject our code into the PreSendRequestHeaders event which occurs directly before the headers are sent out to the client. The following code does the event handler registration:

public void Init(HttpApplication context)

{

    context.PreSendRequestHeaders += OnLeave;
}

To change a response header you use the HttpResponse.Headers collection. Changing response headers that don't originate from managed code (in this case from the web core) is a new feature in IIS7 and is enabled by the integrated pipeline. The following code would throw an exception on IIS6:

void OnLeave(object sender, EventArgs e)

{

    // set header

    HttpContext.Current.Response.Headers.Set("Server", "MyFavouriteServer");
}

The last step is to compile this class into a .dll and copy it either into the /bin folder of an application or into the GAC. After that you can register the module at the configuration level you want to use it (machine, site or application). Add the following section to the corresponding web.config:

<system.webServer>
 
<modules>
   
<add name="ServerHeaderModule"
        
type="LeastPrivilege.ServerHeader.ServerHeaderModule, … " />
 
</modules>
</system.webServer>

When you now make requests to IIS7 and inspect the response (e.g. with a tool like Fiddler), you can see that the value of the server header is to whatever you have set it in code. And btw – this is also the case if you request a static file like html or jpg. Managed modules get called for every single request now (at least by default).

OK – so that's the core of the new IIS7 feature I want to add. It may look simple but this is a huge improvement. For the first time we can plug directly into IIS request processing using managed code and you can imagine all kinds of interesting scenarios you can realize with this possibility.

Next time I will talk about how to add a custom configuration section to web.config and how the module can read its configuration settings.

 


Work in Progress
Monday, January 15, 2007 7:35:43 AM UTC  #   
 Saturday, January 13, 2007

IIS7 Managed Extensibility: An end-to-end Example

IIS7 (and the tooling around it) has wonderful new features. First of all managed code is now a first class citizen and can do (nearly) everything as the unmanaged API. Almost everything that could be accomplished by ISAPI filters and extensions is now possible with .NET HttpModules/HttpHandlers. Next IIS7 allows to seamlessly integrate your custom functionality with the configuration and management system. This includes the configuration file, the administration GUI and remote management features.

I wanted to test drive the new APIs so I decided to build a module that can change the value of the Server HTTP Header so that IIS can look to scanners like an Apache or whatever you want (I did this ages ago using an ISAPI filter). My module should feel like a built-in IIS feature with regards to configuration and management.

This scenario allows testing several new features of IIS7, e.g.

  • (ASP).NET code can change response headers even if they are not originating from the same "handler" (this also applies to request headers and server variables - btw)
  • Processing of all requests
  • Integration into the unified configuration system and feature delegation. The configuration section of the ServerHeader feature will live under <system.webServer>
  • Integration into the IIS7 GUI and the remote administration infrastructure

This was not hard to do, but it turns out that the whole solution is quite some code (mostly for the UI integration plumbing) – so I will split the walkthrough in several logical parts and explain the underlying concepts while we go. I plan to talk about the following topics:

  • The HttpModule
  • Configuration
  • Management Integration (on the server)
  • Management (aka UI) Integration (on the client)
  • Wrap up and Solution Structure
  • Deployment

Watch this space.


Work in Progress
Saturday, January 13, 2007 10:43:08 AM UTC  #   
 Tuesday, January 09, 2007

IIS7 Configuration API

IIS7 uses (nearly) standard .NET .config XML files for configuration. This is great and is one of the coolest features of IIS7 IMO. The metabase is gone (woohoo) and you can mix ASP.NET and IIS7 settings in a single web.config file. This means that you don't have to adjust settings in two places and that you can deploy your ASP.NET application together with IIS7 configuration. That's awesome.

How often have I wished in the past that I can configure Windows authentication in ASP.NET and IIS in a single step and without having to navigate GUIs. Like this:

<configuration>
 
<system.web>
   
<authentication mode="Windows" />
 
</system.web>

  <system.webServer>
   
<security>
     
<authentication>
       
<anonymousAuthentication enabled="false" />
       
<windowsAuthentication enabled="true" />
     
</authentication>
   
</security>
 
</system.webServer>
</configuration>

To read or modify configuration you have several choices, notepad, the IIS GUI, a command line tool (appcmd.exe) or the IIS configuration API.

You can find the API in the Microsoft.Web.Administration.dll assembly located in the GAC or \Windows\System32\Inetsrv. The most obvious class to start with is called ServerManager – this gives you full access to the IIS7 configuration and you can easily navigate through most settings using the Sites, Applications, ApplicationDomains and ApplicationPools collections. Another not so obvious class is called WebConfigurationManager which also gives you access to configuration. What's the difference and when to use which?

ServerManager is an administration (or design-time) API mostly useful for deployment and automated configuration. ServerManager is (currently) not designed for partial trust scenarios and some functionality requires elevated OS privileges.

WebConfigurationManager is a fast, light-weight runtime configuration API for applications, handlers and modules that need to read configuration settings. This is the one you want to use in your ASP.NET application code.

To get access to configuration you need a Configuration object. ServerManager features two methods called GetAdministrationConfiguration() and GetApplicationHostConfiguration() which return the Configuration object for the two machine wide config files (the Application class also has a method called GetWebConfiguration()). From there you usually call the GetSection() method and specify the configuration section you want to access using an XPath like expression, e.g. "system.webServer/directoryBrowse". WebConfiguration also has a GetSection() method – the configuration returned here is always the one for the current application.

GetSection() returns a ConfigurationSection (derived) class from which you can read and write configuration attributes and, when using ServerManager, write the changes back to the config file. The following code changes configuration to allow directory browsing for an application:

Configuration config = app.GetWebConfiguration();

// weak typed
ConfigurationSection sectionBrowse = config.GetSection
  (
"system.webServer/directoryBrowse");

sectionBrowse["enabled"] = true;

Those of you who have looked at ASP.NET custom configuration sections know that you can provide a class that does the mapping between the object and XML worlds. This allows using strongly typed properties instead of string values to change attributes. The IIS7 configuration API uses a similar approach (but not the same). You can provide a ConfigurationSection derived class that gives you properties – but the actual schema of the configuration section (enums, default and required values, min/max values etc.) is specified in an XML file. The reason for that is (I believe) that configuration has to be usable from managed and unmanaged code – and the custom attribute approach to define schema would tightly-couple the configuration section to the CLR.

The schema definition for the <directoryBrowse> section looks like this:

<sectionSchema name="system.webServer/directoryBrowse">
 
<attribute name="enabled" type="bool" defaultValue="false" />
 
<attribute name="showFlags" type="flags" defaultValue="Date, Time, Size, Extension">
   
<flag name="None" value="0" /> 
    
<flag name="Date" value="2" /> 
    
<flag name="Time" value="4" />
   
<flag name="Size" value="8" />
   
<flag name="Extension" value="16" />
   
<flag name="LongDate" value="32" /> 
  </attribute>
</sectionSchema>

You can find the complete schema file in \Windows\system32\inetsrv\config\schema.

The corresponding configuration section class would look like this:

public class DirectoryBrowseSection : ConfigurationSection
{
 
public static string SectionName = "system.webServer/directoryBrowse";

  public
bool Enabled
 
{
   
get { return (bool)base["enabled"]; }
   
set { base["enabled"] = (bool)value; }
 
}

  public EnumDirectoryBrowseShowFlags ShowFlags
 

   
get { return (EnumDirectoryBrowseShowFlags)base["showFlags"]; }
   
set { base["showFlags"] = (int)value;
  }
}

public enum EnumDirectoryBrowseShowFlags
{
 
None = 0,
 
Date = 2,
 
Time = 4,
 
Size = 8,
 
Extension = 16,
 
LongDate = 32
}

With such a strong typed wrapper, the configuration code looks more OO:

Configuration config = app.GetWebConfiguration();
DirectoryBrowseSection sectionBrowse = (DirectoryBrowseSection)
 
config.GetSection(
   
DirectoryBrowseSection.SectionName, 
    
typeof(DirectoryBrowseSection));

sectionBrowse.Enabled = true;

While technically there are already ConfigurationSection classes defined for all IIS7 and ASP.NET settings (in the Microsoft.Web.Management*.dll) – they are currently internal. Fortunately Kanwal from the IIS team posted a tool that generates configuration classes from the XML definition file. Simply point it at the IIS7 schema file and you will get an object model for all configuration groups and sections. Nice!

 



Tuesday, January 09, 2007 8:56:11 PM UTC  #   

ASP.NET Security WebCasts auf MSDN

Im Januar/Februar werde ich vier WebCasts zum Thema ASP.NET Security für MSDN Deutschland machen.

Genaue Informationen über den Februar reiche ich nach - aber im Januar haben wir folgendes auf dem Programm:

Security mit ASP.NET 2.0 (Teil 1-4) - Authentifizierung & Autorisierung mit ASP.NET 2.0
(Mitttwoch, 17.01.2007 16:00-17:00 Uhr)
ASP.NET verfügt über eine äußerst flexible Authentifizierungs- und Autorisierungs-Infrastruktur für Windows, Zertifikate und Custom Benutzer-Accounts. Dabei sind die Details für den Anwendungs-Code völlig irrelevant, und Seiten müssen nicht mit der eingesetzten Authentifizierungsmethode im Hinterkopf entwickelt werden. Um diese Infrastruktur effizient zu nutzen, muss man allerdings einen genaueren Blick auf die ASP.NET-Verarbeitungs-Pipeline und die vorhandenen Erweiterungs-Punkte werfen. Dieser Webcast beleuchtet die vorhandenen Authentifizierungs-Mechanismen und  untersucht, wie man durch Erweiterungen der Pipeline-Szenarien wie Single-Sign-On, Web Farms, Schutz von statischem Content sowei Mixed-Mode-Authentifierung implementieren kann. (Anmeldung)

Security mit ASP.NET 2.0 (Teil 2-4) - Eingabe-Validierung mit ASP.NET 2.0
(Montag, 29.01.2007 16:00-17:00 Uhr)
Böswillige oder einfach auch nur unerwartete Eingaben sind der Grund für die meisten Stabilitäts- und Sicherheits-Probleme in Anwendungen. Oder was ist der häufigste Grund für Programm-Abstürze bei Ihnen - Logikfehler oder unerwartete Eingabewerte? Zudem existieren eine Reihe von ernstzunehmenden Attacken, die sich fehlerhafte (bzw. nicht-existierende) Eingabe-Validierung zu Nutzen machen. Erfahren Sie mehr über typische Angriffe wie SQL, HTML und Script Injection, Cross Site Scripting oder Directory Traversal - und darüber, wie Sie sich dagegen wehren können. Beleuchtet werden weiterhin die eingebauten Eingabe-Validierungs-Dienste wie Request, ViewState und Event Validation sowie die Validation Controls und ihre Erweiterbarkeit. (Anmeldung)

 


Microsoft Deutschland Security Portal
Tuesday, January 09, 2007 7:46:21 AM UTC  #   
 Saturday, January 06, 2007

ASP.NET Control for CardSpace

CardSpace is a very promising new way of doing strong authentication across trust boundaries (it is much more than that, but there are already very good introductions and in-depth articles about it out there – see the links at the end of this post).

Adding CardSpace support to ASP.NET applications is very easy – you have to add a special <object> tag to a page and by submitting the containing form (or by doing a getElementById) you can trigger the client identity selector and transmit the encrypted XML token back to the web application. On the server side you can extract the token from the form, decrypt it using the private key of the server’s SSL certificate and process the contained claims. The <object> tag contains information about the card issuer, the token type and the required/optional claims, e.g.

<object type='application/x-informationcard' name='_selector'> 

  <param name='tokenType' value='urn:oasis:names:tc:SAML:1.0:assertion' />

  <param name='issuer' value='http://www.leastprivilege.com...' />

  <param name='requiredClaims' value='http://www.leastprivilege.com...' />

  <param name='optionalClaims' value='http://www.leastprivilege.com...' />

</object>

These are very low-entry technology requirements and can be done by any application that supports SSL, can emit HTML and decrypt standard W3C encrypted XML (e.g. sandbox.netfx3.com is implemented in ASP.NET whereas Kim Cameron’s blog uses PHP). Currently Microsoft only supports IE7, but there are plugins for Firefox and Safari available. For non-web applications, CardSpace support is integrated into WCF.

Due to the lack of broad support (OS, browsers and identity providers) and some other problems that need to get solved first (e.g. mobility of cards), most of you cannot just make an immediate switch to CardSpace – but it may be interesting for you to offer CardSpace authentication as an alternative to a password based logon. 

To find out how hard it really is to add CardSpace support to an existing username/password based application, I started with a pretty standard ASP.NET application that uses all the usual technologies that Microsoft wants us to use (master pages, themes, the security controls, forms authentication, profile, navigation etc.). I will write about my experiences in a different post (e.g. about possible migration scenarios, how to integrate token/claims based authentication / authorization into you back-end without impacting your existing application and some management issues and procedures that need to be thought about).

One thing I wrote during that experiment is an ASP.NET server control to emit the right CardSpace object tag and the necessary JavaScript to invoke the identity selector on the client. This gives you a server side object to program against, makes maintenance easier and solves some problems you might run into when using CardSpace with master pages.

The CardSpaceSelector markup is straightforward:

<lp:CardSpaceSelector runat="server" ID="_selector"

  IssuerType="Managed"

  Issuer="http://www.leastprivilege.com/sts"

  TokenType="urn:oasis:names:tc:SAML:1.0:assertion">

               

  <lp:ClaimType>http://www.leastprivilege.com/.../givenname</lp:ClaimType>

  <lp:ClaimType>http://www.leastprivilege.com/.../surname</lp:ClaimType>

 

  <lp:ClaimType IsOptional="true">

    http://www.leastprivilege.com/.../optionalclaim</lp:ClaimType>

</lp:CardSpaceSelector>

This renders an <object> tag, a clickable image and a JavaScript click handler that stores the encrypted XML in a hidden form field. On the server side you can retrieve the encrypted XML directly from the hidden field or from the XmlToken property of the control. Afterwards you can decrypt the token, e.g. using the TokenProcessor library from the SDK.

protected void Page_Load(object sender, EventArgs e)

{

  if (IsPostBack)

  {

    // retrieve encrypted XML

    string xmlToken = _selector.XmlToken;

    if (!string.IsNullOrEmpty(xmlToken))

    {

      try

      {

        // parse and decrypt the token

        Token token = new Token(xmlToken);

 

        // access claims

      }

      catch (Exception ex)

      { … }

    }

  }

}

CardSpaceSelector has a number of properties that can make your life easier, e.g.

IssuerType
This enum has two values ‘SelfIssued’ and ‘Managed’. If you select ‘SelfIssued’ then the issuer URI for self-issued cards will be emitted. If you select ‘Managed’ you have to set the issuer URI yourself.

Issuer and IssuerPolicy
Specifies the URIs for the issuer and the issuer policy.

TokenType
Specifies the token type. If not set, the URI for SAML 1.0 will be used.

HiddenFieldName
Specifies the name of the hidden field where the encrypted XML token gets stored on the client. The default is __XMLTOKEN.

XmlToken
Contains the encrypted XML token if an InfoCard was selected.

AutoPostBack
If set to true, the control will automatically do a postback after the user has selected an InfoCard.

ImageUrl
Let’s you change the default image.

In the attached zip you can find the source for the control alongside a little demo ASP.NET app that uses it. Be aware that the identity selector will only pop up if you are running over SSL – this is needed to encrypt the token and to create a unique PPID for your application.
Maybe this is useful for you. Write me if you have any comments, suggestions or found a bug…

Some additional reading

Thanks for your help: Brock Allen, Jason Diamond and Christian Wenz

CardSpaceSelector.zip (38.55 KB)

 


Tools | Tools for Thinktecture | Work in Progress
Saturday, January 06, 2007 7:54:17 AM UTC  #   
 Friday, January 05, 2007

Protocol Transition Revisited

Protocol Transition is a handy technology when you have to "convert" a non-Windows credentials to Kerberos.

Since PT does not require to know the password of an account to get a token, access to resources using this token is limited. You only have access to local resources if you have the TCB privilege and to remote resources via constrained delegation.

But sometimes you need access to local resources or, even worse, to access a remote resource you first have to read some local information (remote Performance Counters come to my mind here). And of course it is not recommended to elevate the privileges of your main application to SYSTEM or similar to make Protocol Transition work in these scenarios.

Keith describes an excellent solution how to factor out PT logic into a separate highly privileged process to create the tokens - and also adds some tricky ACL and token handle code - very interesting. Read it here.

 


For Your Favourites
Friday, January 05, 2007 4:34:09 PM UTC  #   
 Saturday, December 23, 2006

UAC DropPad

What bugs me from time to time with Vista and UAC is that I cannot directly start data files (like .sln files) elevated - I always have to start the application (like Visual Studio) elevated first and open the solution from there.

So I wrote a little WinForms app that allows to drag&drop arbitrary files on it and starts the associated application elevated.

The bare bones were easy to write, but my WinForms skills suck - so Jörg Neumann added some finishing touches and UI magic to it. So if this is useful for you, feel free to take it as our X-mas present.

Merry Christmas!

UacDropPad.zip (27.17 KB)

UPDATE1: I slightly modified the code - if you don't want to have an open window around - just keep a shortcut to UacDropPad.exe on your desktop and drag&drop the files you wannt to start elevated on the icon.

UPDATE2: Brock doesn't like to drag&drop. You can also add UacDropPad to the "Send to" menu - just copy a link to \Users\<user>\AppData\Roaming\Microsoft\Windows\SendTo.

 


Tools | Tools for Thinktecture
Saturday, December 23, 2006 9:02:32 PM UTC  #   
 Saturday, December 09, 2006

Known Differences Between IIS7 Integrated and Classic Mode

Read about it here.

 


For Your Favourites | Work in Progress
Saturday, December 09, 2006 8:19:32 AM UTC  #   
 Thursday, December 07, 2006

Bug in 2.0 Jitter?!

Just found this (scroll down to ".NET Framework 2.0 Security Hole") via Marc's Blog.

Not sure if this is true - but it sounds scary...this brings me back to an old point - don't run untrusted apps off the Internet - and be careful with technologies that allow this by default ;)

 


Work in Progress
Thursday, December 07, 2006 10:02:19 PM UTC  #   
 Wednesday, December 06, 2006

"Manage Private Key" on Vista

A while ago I wrote how to set ACLs on a private key container.

Today I spotted a new context menu item in the "Certificates" MMC snap-in on Vista. Right-click a certificate and select "All Actions->Manage Private Key" to get to the ACL dialog of the key container. nice!

 


Work in Progress
Wednesday, December 06, 2006 9:17:58 PM UTC  #   
 Friday, December 01, 2006

TVP Slides

Thanks to everyone who attended the Connected Systems Roadshow this week in Reading! We had great fun.

You can find the slides and the architecture sample I wrote during the talk here.

Mike - who did a great talk on hosting Workflow in ASP.NET has also uploaded his slides and demo here. Thanks Mike!

 


Conferences | Work in Progress
Friday, December 01, 2006 9:52:17 AM UTC  #   
 Monday, November 20, 2006

HttpSysCfg

A (kind of) polished version of my HTTP.SYS ACL/SSL helper tool can be found on the thinktecture tools page.

 


Tools
Monday, November 20, 2006 11:16:30 PM UTC  #   

AntiXss 1.5

Finally...the new version of the AntiXss library is now available for download. Go get it!

New features include:

  • support for partial trust :)
  • more encoding functions
  • tutorials

Happy encoding!

 


For Your Favourites
Monday, November 20, 2006 8:49:55 PM UTC  #   
 Tuesday, November 14, 2006

AzManBulkImport Update

Joe sent me a new version of his AzMan bulk importer - in the .zip is a changes document. enjoy!

AzManBulkImport123.zip (6.25 KB)

 


Tools
Tuesday, November 14, 2006 2:43:38 PM UTC  #   
 Thursday, November 02, 2006

SecureString Redux

Read more over at Shawn's

http://blogs.msdn.com/shawnfa/archive/2006/11/01/securestring-redux.aspx

 


For Your Favourites
Thursday, November 02, 2006 5:51:38 PM UTC  #   
 Wednesday, November 01, 2006

CAS und ClickOnce Webcast

Ich habe total vergessen die versprochenen Samples für den CAS & ClickOnce Webcast hochzuladen (danke Andreas für die Erinnerung).

ClickOnce und NoTouch.zip (873.58 KB)

 



Wednesday, November 01, 2006 5:10:09 PM UTC  #   
 Monday, October 30, 2006

Interview mit Mike Downen

Mike Downen ist der Security Program Manager der CLR - dieses Interview habe ich im Sommer für das Reach Magazine geführt, und ist jetzt online auf MSDN.

http://www.microsoft.com/germany/msdn/security/interview27102006.mspx


Microsoft Deutschland Security Portal
Monday, October 30, 2006 10:30:47 PM UTC  #   
 Friday, October 27, 2006

So much for SecureString

Every once in a while questions come up regarding the usefulness of SecureString.

StaceyW posted this link today...:O

Interestingly, Ian told me that the latest build of WPF also removed the SecureString functionality from the PasswordBox and replaced it with an ordinary string...

 


Work in Progress
Friday, October 27, 2006 6:18:28 AM UTC  #   
 Wednesday, October 25, 2006

Certificate References in Configuration

When you are doing STS work (that goes beyond the hardcoded SDK samples), you need programmatic access to certificates from the store. To make this easier I hacked together a configuration section for certificate references, e.g.

<certificateReferences>

  <add name="Sts"

       findValue="CN=STS"

       x509FindType="FindBySubjectDistinguishedName"

       storeLocation="LocalMachine"

       storeName="My" />

 

  <add name="http://localhost:9000/IssuedToken"

       findValue="CN=Service"

       x509FindType="FindBySubjectDistinguishedName"

       storeLocation="LocalMachine"

       storeName="AddressBook" />

</certificateReferences>

...and a static class that gives you easy access to the certificate information (e.g. in your STS):

// get the encryption certificate for the requested service

private void SetTargetToken(string appliesTo)

{

  CertificateReferenceElement config =

    CertificateReference.GetReference(appliesTo);

 

  ProofKeyEncryptionToken = FederationUtilities.GetX509TokenFromCert(

    config.StoreName,

    config.StoreLocation,

    config.FindValue);

}

CertificateReference.zip (14.95 KB)

 


Work in Progress
Wednesday, October 25, 2006 9:00:53 AM UTC  #   

TechEd 2006

TechEd is in two weeks - and I am really looking forward to it!

I will do a talk on the architecture track -

ARC309 Security is a Feature - Best Practices for Designing Secure Distributed .NET Applications 
Thu Nov 9 17:30 - 18:45
 
Security is nothing you can buy or bolt onto a product at the end. The most common mitigation techniques are not hard to implement, but have to be planned and designed right from the start. Furthermore the .NET Framework and the Windows platform provide a vast amount of security APIs and technologies to choose from. Find out which are the right ones for you and how they can improve your design and architecture. Furthermore you'll get some common best practices, tools and tips to make your life easier.

Since I am only doing one talk, but will hang out the whole week - there will be extended time for networking and partying :) Stop by and say hello!

 


Conferences
Wednesday, October 25, 2006 8:23:54 AM UTC  #   
 Tuesday, October 24, 2006

Simple Sandboxing API Artikel

Es haben mich schon ein paar Leute danach gefragt, der Artikel (ursprünglich erschienen im DotNet Magazin) ist nun auch als .pdf bei MSDN verfügbar.

 


Microsoft Deutschland Security Portal
Tuesday, October 24, 2006 12:45:16 PM UTC  #   
 Monday, October 23, 2006

MSDN Webcast: Zertifikate in .NET 2.0

Danke an alle Teilnehmer des Zertifikate Webcasts. Anbei finden Sie die Slides & den Code. Bei Rückfragen einfach Mail an mich.

WebCastDEZertifikate.zip (558.36 KB)

 


Microsoft Deutschland Security Portal
Monday, October 23, 2006 1:54:49 PM UTC  #   

ADC Nachtrag

Danke an alle Teilnehmer meiner beiden Vorträge auf der ADC. Ich hoffe es hat euch genauso viel Spass gemacht wie mir :)

Bei weiteren Fragen - einfach Email oder Comment an mich.

 


Microsoft Deutschland Security Portal
Monday, October 23, 2006 10:13:06 AM UTC  #   

IIS7 loads User Profiles

That's excellent news.

This enables using user-scoped DPAPI keys and certificate stores/key containers.

 


Work in Progress
Monday, October 23, 2006 10:06:08 AM UTC  #   
 Friday, October 20, 2006

WCF proxies in partially trusted ASP.NET Apps

Summary: OK - I got this working - but you may not like the solution.

So it still bugs me that WCF won't directly support partial trust in V1. This means that it is much harder for partially trusted ASP.NET applications to host or use WCF services (same applies of course to all WCF clients like ClickOnce applications).

Today I decided to give it a go and find out how hard it really is. Here is what happened.

<sidebar>
If you want to call something from partial trust which does not allow partially trusted callers, you have to wrap it in/assert full trust (keep that in mind - we will need this later on) - or as my good friend Marcus would say: "the devil is in the detail" :)
</sidebar>

OK - so after you have a working client/service in full trust, these are the necessary steps:

  • Move the WCF proxy to a separate assembly.
  • Give that assembly a strong name.
  • To be able to call the proxy from partial trust, you have to add a [assembly: AllowPartiallyTrustedCallers] attribute to the proxy assembly.
  • Assert full trust in the proxy. The easiest way to do this is by adding an attribute on top of the proxy class.

[SecurityPermission(SecurityAction.Assert, Unrestricted=true)]

public class Proxy

{

    ...

}

  • Create a new policy file. It is recommended to use the medium trust policy as a starting point. You can find the policy files in the framework configuration directory. The medium trust policy is called 'web_mediumtrust.config'

  • You have to add a new code group for your proxy assembly to the policy file granting full trust. This code group should go directly under the 'AllCode' grop. Use a StrongNameMembershipCondition to identify the proxy (you get strong names in the right format from secutil.exe with the -hex and -s option).

<CodeGroup

  class="UnionCodeGroup"

  version="1"

  PermissionSetName="FullTrust">

 

  <IMembershipCondition

    class="StrongNameMembershipCondition"

    version="1"

    PublicKeyBlob="00..C9" />

</CodeGroup>

  • Add a new trust level to global web.config that points to your policy file

<securityPolicy>

  <trustLevel name="WCF" policyFile="web_WCF.config" />

</securityPolicy>

 

  • Apply this trust level to your application (either in your local web.config or via a location element in an upstream config)

<trust level="WCF" />

So far so good - the proxy is separated from the application and has full trust. But when you try running the application now, you will get an ugly ConfigurationErrorException saying the system.serviceModel/client configuration section cannot be accessed because the assembly does not allow partially trusted callers..WTF?!

After following an adventurous code path through the .NET configuration system and seeing variables named like isTrusted and isLocationTrusted - I suddenly knew what is going on.

I remember vaguely that ASP.NET has this concept of trusted configuration locations - e.g. a configuration handler that is registered in machine.config gets full trust even if the application using that section is running in partial trust. This on the other hand means that if a configuration handler is demanding full trust - and thats what System.ServiceModel.dll is essentially doing - the configuration section can't be in a partially trusted location.

I then tried to move the <system.serviceModel> configuration section to a location element in global web.config - and (drum roll) - it worked...

<location path="Default Web Site/PartialTrustWcfClient">

  <system.serviceModel>

    ...

  </system.serviceModel>

</location>

By moving the config section we basically "wrapped" it in full trust. The only other option I see is wrapping the configuration section classes instead. This is quite some work and you would loose intellisense.

OK - so this just shows that partial trust is an un-supported and un-tested scenario in WCF V1. But it works and is - if you have to use WCF - better than running ASP.NET in full trust.

You can find the artifacts here.


ASP.NET | WCF | Work in Progress
Friday, October 20, 2006 10:09:22 AM UTC  #   
 Tuesday, October 17, 2006

Webcasts im Oktober

Nächste Woche mache ich zwei Webcasts rund um Zertifikate und CAS. Bei Interesse einfach reinschauen.

Arbeiten mit Zertifikaten und PKCS#7/CMS in .NET 2.0
Montag, 23.10.2006 14:00-15:00 Uhr
Eines der meist verlangten Features für .NET 2.0 war ohne Zweifel die Unterstützung für X.509-Zertifikate sowie die kryptografischen Operationen, die damit nach PKCS#7/CMS-Standard konform durchgeführt werden können. Dieser Webcast beleuchtet die beiden neuen Namensräume System.Security.Cryptography.X509Certificates und Pkcs und gibt Ihnen einen Überblick, wie man mit Zertifikaten und dem Windows Zertifikat-Speicher arbeitet. Außerdem beschäftigen wir uns mit der Anwendung von Verschlüsselung und mit digitalen Signaturen. (Anmelden)

Den Client im Griff mit Code Access Security
Donnerstag, 26.10.2006 14:00-15:00 Uhr
Code Access Security (CAS) ist eine Technologie, die Benutzer vor bösartigem oder auch einfach nur fehlerhaftem Code schützen soll. In der Praxis stolpert man über dieses Sicherheits-Feature immer dann, wenn man z.B. eine Anwendung von einem Netzwerk-Laufwerk oder Web Server starten will. Dieser Webcast gibt eine Einführung in die Funktionsweise von CAS und der dazugehörgen Security Policy sowie Tipps & Tricks, die einem die Arbeit mit dieser Technologie erleichtern können. Abgerundet wird das ganze mit einem Blick auf ClickOnce, einem Deployment-Feature von .NET 2.0, das die typischsten CAS-Probleme zu lösen verspricht. (Anmelden)


Microsoft Deutschland Security Portal
Tuesday, October 17, 2006 11:39:26 AM UTC  #   
 Friday, October 13, 2006

WebEventFormatter Constructor is Internal

The WebEvents in the Health Monitoring Framework in ASP.NET 2.0 emit all kinds of useful information. You can also add your own information to it by overriding FormatCustomEventDetails().

The built-in WebEvent provider call that method which adds the information to a WebEventFormatter. After that they call ToString() on the formatter (see e.g. System.Web.Management.EventLogWebEventProvider.AddBasicDataFields().

The problem is that the WebEventFormatter ctor is internal. That means the built-in providers can access the information, but custom ones can't.

Is this a bug? Am I missing something? Has anybody managed to get this to work?

I submitted feedback to the Microsoft connect site - but got no response yet. If this affects you too, please vote for this bug.



Friday, October 13, 2006 10:14:57 AM UTC  #   
 Tuesday, October 10, 2006

Sicherheitsbewusste Programmierer

Gerade auf Heise gefunden - so wahr...

"Eine Umfrage von Symantec unter 400 Programmierern zeigt: Die Anwendungssicherheit genießt bei ihnen einen hohen Stellenwert. Allerdings steht der ordentlichen Umsetzung häufig Termindruck entgegen"

http://www.heise.de/newsticker/meldung/79225

 


Misc
Tuesday, October 10, 2006 9:59:00 PM UTC  #   

New ASP.NET 2.0 Vulnerability

This time XSS related - get the details/fix here.


For Your Favourites
Tuesday, October 10, 2006 9:47:08 PM UTC  #   
 Sunday, October 08, 2006
 Wednesday, October 04, 2006

Book in Stores

I finally made it ;)

http://www.microsoft.com/mspress/books/9989.asp

Feel free to write a review on Amazon :))

 


Work in Progress
Wednesday, October 04, 2006 3:08:26 PM UTC  #   
 Wednesday, September 27, 2006

RolePrincipal vs. RoleProviderPrincipal

WCF supports the ASP.NET role manager feature to assign roles to clients. However the semantics how role providers are used from both stacks differs slightly. You may run into that when you want to re-use an existing role provider. Here are the details.

ASP.NET
When the role manager features is enabled, the RoleManagerModule in ASP.NET 2.0 creates a RolePrincipal (System.Web.Security.RolePrincipal) in the PostAuthenticateRequest pipeline event. The RolePrincipal is set on Thread.CurrentPrincipal and Context.User. Initially RolePrincipal does not know the roles of the user, but on the first call to IsInRole, RolePrincipal calls the role provider's GetRolesForUser() method. This method returns all roles for the user and RolePrincipal caches the role list internally. All subsequent calls to IsInRole go against the cached version of the role list.

The ASP.NET role manager also has some more features like de/serializing the role list and caching it in a cookie.

WCF
When you set the principalPermissionMode to UseAspNetRoles in the serviceAuthorization service behavior, WCF creates a RoleProviderPrincipal (System.ServiceModel.Security.RoleProviderPrincipal) passing in the configured role provider name and sets it on Thread.CurrentPrincipal.

Instead of calling GetRolesForUser(), RoleProviderPrincipal forwards all calls to IsInRole() to the role provider's IsUserInRole() method. This has some implications.

The minimum requirement for an ASP.NET role provider is to implement GetRolesForUser(). To use the same provider in WCF you also have to implement IsUserInRole().
In WCF, every call to IsInRole or a PrincipalPermission will result in a round-trip to the role store. In ASP.NET only the first call to IsInRole() accesses the role store. The number of roles and the number of role checks in your application decide which approach performs better. Just be aware of that.

To get the same caching behavior in WCF as the RolePrincipal in ASP.NET you would have to use a custom principalPermissionMode and provide your own principal implementation that does its own caching.


ASP.NET | WCF | Work in Progress
Wednesday, September 27, 2006 10:47:46 PM UTC  #   
 Monday, September 25, 2006

Hosting WCF Services in ASP.NET - The Survival Guide

As you might know, I spent quite some time with ASP.NET 2.0 in the last 15 months. Now that the book is finished I investigated a little more in WCF and examined some scenarios I care about. And, of course, looking at WCF from an ASP.NET perspective is one of them.

The way how WCF services are hosted in ASP.NET differs fundamentally to .asmx web services. Here are some observation I made and some tips.

As an .asmx developer you are used to rely on the features of the hosting environment (IIS/ASP.NET) like HTTP authentication, session, cookies or cache support. WCF on the other hand was designed to be host agnostic and such services are provided by its own host called the ServiceHost (this includes e.g. authentication and authorization information).

So the first thing you might notice is, that HttpContext.Current is null by default. Other ASP.NET pipeline services like File and UrlAuthorization, Session, Output Cache or Impersonation are also ignored. This is intentional so that you are not tempted to use any host specific features and to make it easier to move the service to a different hosting environment. How does that work?

By default an HttpModule (System.ServiceModel.Activation.HttpModule) subscribes asynchronously to the PostAuthenticateRequest pipeline event. When a request for a .svc file comes in, the request is dispatched to a WCF controlled thread and the ASP.NET worker thread is put back into the thread pool. This makes WCF independent of ASP.NET threads which can be a bottle-neck in some situations. The HttpContext gets nulled and the service gets invoked. When WCF has finished processing, the response is transmitted back to the client. The whole HTTP pipeline gets short-circuited when WCF takes over control (this also implies that custom modules that subscribe to events later in the pipeline will not get called).

Where have my HttpContext provided Services gone? Some Workarounds.
Well - usually you shouldn't need those services at all. WCF has an equivalent called the OperationContext and e.g. you get to the identity of your client (the first thing I looked for) from OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.Name.

Another thing you might need is the Cache, e.g. when you want to share cached data between the service and an ASP.NET application in the same AppDomain. It turns out that you don't have to get the Cache from HttpContext.Cache - you can also use the HttpRuntime class like that:

Cache cache = HttpRuntime.Cache;

The third thing I came across is the mapping of virtual paths to physical one. Since there is no HttpContext by default, you cannot easily call Server.MapPath(). A workaround for that is to use the HostingEnvironment class:

string file = String.Format("{0}\\{1}\\{2}",
  HostingEnvironment.ApplicationPhysicalPath, "App_Data", "foo.txt");

ASP.NET impersonation is another thing you may rely on. All impersonation is undone when the request enters the WCF ServiceHost. You have to configure impersonation in the WCF service itself - either via a serviceBehavior configuration setting or an OperationBehavior attribute in code.

The equivalent of the ASP.NET <authorization> element is a [PrincipalPermission] attribute on top of an service method or class or a custom ServiceAuthorizationManager derived class.

IIS Authentication Settings
Another thing I noticed is, that WCF requires to enable anonymous authentication for the .svc files in IIS (regardless of WCF authentication settings). If you drop a .svc file into an existing ASP.NET application that uses Windows authentication you will see this error message:

"Security settings for this service require 'Anonymous' Authentication but it is not enabled for the IIS application that hosts this service."

You have to individually enable anonymous access for the .svc files to make it work.

Sharing Users between an Application and a Service
WCF supports the ASP.NET membership feature. If your want to share your user base between an application and a service and you have wrapped your security logic into a membership provider, you are good to go. You can also write a UserNamePasswordValidator derived class which can be plugged into WCF for username/password validation. This is more light-weight than implementing a full featured membership provider.
WCF enforces (transport) security when you use authentication - so prepare to finally get friendly with SSL. Also have a look at the other authentication types like Windows, Certificates and issued tokens (Federation of CardSpace).

Role-based Security
The standard WCF authorization model is based on claims. But you can also get traditional role based security to work. The replacement for Page/Context.User.IsInRole() is now Thread.CurrentPrincipal.IsInRole(). Thread.CurrentPrincipal is not always populated. For Windows authentication you will find the Windows groups as roles there. WCF also support the ASP.NET role manager, so you can plug in a role provider for mapping usernames to roles. For all other cases you can write a class that implements IAuthorizationPolicy to create your custom principal object.

Trust Level
WCF does not support partially trusted callers. That means you are forced to run the ASP.NET application in full trust. If you spent time and effort to make your application or service work in partial trust (which is a good thing), you have to host the WCF service in a different application (=AppDomain). Bad news here.

Which Binding?
The basicHttpBinding is compatible with .asmx - that means transport level security (SSL) and HTTP authentication. If you want to move to message level security, WS-Security and other credential shapes use the wsHttpBinding.

ASP.NET Compatibility Mode
If you absolutely need the HttpContext and pipeline services, e.g. because of migration issues or to share certain services with an ASP.NET application in the same AppDomain, there is also a compatibility mode.

You have to enable the compatibility mode with this configuration setting:

<serviceHostingEnvironment aspNetCompatibilityEnabled="true" />

Additionally, in the service you have to opt-in using this attribute on the service class:

[AspNetCompatibilityRequirements
  (RequirementsMode=AspNetCompatibilityRequirementsMode.Required)]

In this mode, the request will not get intercepted by the HttpModule, but will pass the complete front-part of the HTTP pipeline. The asynchronous handler for .svc files (System.ServiceModel.Activation.HttpHandler) dispatches the request then to the WCF host. The ASP.NET worker thread is freed at this point. After WCF processing is finished, a new worker thread is grabbed from ASP.NET, and the post-request pipeline events fire. In this mode, WCF behaves much like plain .asmx.

You shouldn't use ASP.NET features like cookies or session state in web services. The standard mode is more efficient and the compatibility mode is really only for migration purposes.

UPDATE: Christan just pointed me to this article which contain extra info.

 


WCF | Work in Progress | ASP.NET
Monday, September 25, 2006 9:35:51 PM UTC  #   

DevelopMentor Connected Systems Roadshow

Rich, Niels and me will do a 2-day event at the Microsoft Campus Thames Valley Park in Reading 29th/30th November.

Rich and Niels will build a system based on WCF, Service Broker and Biztalk on that day and have David Gristwood and Gavin King (both from Microsoft) talking about the general strategy and roadmap of the above products.

My track will focus on the ASP.NET side of the house and will cover topics like ASP.NET integration in IIS7 (and the new extensibility), Input Validation, Authentication & Authorization, Logging and Instrumentation as well as migration of password based application to Windows CardSpace (aka "InfoCard"). In addition Mike Taulty from Microsoft will show how to integrate ASP.NET web applications and services with business processes implemented in Workflow.

The event is free and will be fun - for more info go to www.develop.co.uk or call +44 (0) 1242 525108.



Monday, September 25, 2006 7:56:18 AM UTC  #   
 Friday, September 22, 2006

BASTA Nachtrag

Hallo,

die BASTA ist vorbei und es hat sehr viel Spass gemacht!

Anbei findet Ihr die Slides zu meinen drei Vorträgen - bei Rückfragen einfach eine Email/Comment an mich. Bis zum nächsten Mal!

IntegrationInWindowsSecurityMitNET.pdf (983.13 KB)

PluginArchitektur.pdf (296.85 KB)

SmartClientDeploymentSecurity.pdf (334.52 KB)

 


Conferences
Friday, September 22, 2006 11:21:44 AM UTC  #   
 Saturday, September 16, 2006

Bye, Bye Ireland - See you soon...

Ireland was a blast!

Though I was not feeling that good, it gave me a lot of energy talking about a topic I love to so many nice people. Thanks to everyone who attended my talks!!!

I am very impressed by the work Damien, Simon, Philip, Joe, Mick and, of course, Clare do for their communities. Support them!

I'll be back (who could say no to Clare? :)

Below are my slides and demos - so you can play around with them yourself (and show them to your boss)

IrelandUGtourSlidesAndCode.zip (328.83 KB)

 


Work in Progress
Saturday, September 16, 2006 5:07:17 PM UTC  #   
 Wednesday, September 13, 2006

Essential WCF

DevelopMentor's Essential WCF course debuts in London the week October 2nd.

If you are interested in WCF, come visit Rich and me and get the typical DM-style in-depth treatment of the topic.


WCF
Wednesday, September 13, 2006 10:23:07 AM UTC  #   
 Wednesday, September 06, 2006

Back to Ireland

Next week I will be talking about ASP.NET security in Belfast, Dublin, Cork and Galway (Ireland).

I really enjoyed the last time I've been there and I am looking forward to the next week. If you are around, come by and say hello.

http://blogs.msdn.com/clare_dillon/archive/2006/08/21/710884.aspx

 


Work in Progress
Wednesday, September 06, 2006 12:50:17 PM UTC  #   
 Tuesday, September 05, 2006

URI ACLs and WCF - revisited

This morning (right after my first coffee) I had to troubleshoot an URI ACL issue with Christian. He tried using my tool to reserve URI namespaces to host a bunch of services using HTTP. But it didn't work.

I told him that the right format for the URL is:

http://localhost:7777/Service/

but this gave us access denied. I then tried:

http://*:7777/Service/

No success.

After a little bit of trial and error, I managed to get it to work using:

http://+:7777/Service/

That surprised me, because I am 100% positive that the '*' and localhost works for plain HttpListener and that's ultimately what WCF's ServiceHost uses to listen to HTTP requests.

So what's the difference between '+' and '*' and why is this not working with WCF? Well - too bad the httpcfg.exe docs don't tell you, so I had to dig deep into the Windows SDK and finally found a decent description of the URL prefix formats in the docs for the HTTP_SERVICE_CONFIG_URLACL_SET structure (the structure you pass into the unmanaged reservation API called HttpServiceSetConfigurationAcl). Intuitive, isn't it?

The '*' is a so called weak wildcard whereas '+' is a strong wildcard. Strong wildcards seem to work regardless of the host header in the HTTP request, weak wildcards only listen to registered hostnames. Strong wildcards also take precedence over weak ones. Check the SDK document for more interesting details.

By default WCF demands a strong wildcard. But you can change this with the HostNameComparison property on the BasicHttpBinding class (thanks for the pointer, Nicholas).

Christian also nagged me that my tool is not able to show all existing URL registration (well, he was just too lazy to type 'httpcfg query urlacl' ;). But hey - only happy users are good users, and here is a new version of it:

HttpCfgAcl22.zip (33.49 KB)

 


WCF | Work in Progress
Tuesday, September 05, 2006 1:07:22 PM UTC  #   
 Friday, August 25, 2006
 Monday, August 21, 2006

ExpressionBuilder for SSL Redirects

In this post I explained why you have to use absolute URLs when you switch to SSL. I showed the GetAbsoluteUrl method which allows to pass in a relative URL and a protocol and returns an absolute URL. By using the <% %> notation, you can also directly subsitute links in HTML markup, e.g.

<a href="<%= SslTools.GetAbsoluteUrl("~/ssl/default.aspx", ProtocolOptions.Https) %>">SSL Page</a>

This works only for literals like HTML. If you want to set attributes of ASP.NET controls inline, you have to use an expression builder (read more here). This allows this syntax:

<asp:HyperLink runat="server" ID="_lnk" Text="SSL Page" NavigateUrl="<%$ HttpsUrl:~/ssl/default.aspx %>" />

The ExpressionBuilder mostly consists of boiler plate code that is used to inject a call to GetValue into the compiled ASP.NET page. GetValue then just calls the GetAbsoluteUrl method I showed in my earlier post.

public class HttpsUrl : ExpressionBuilder

{

    public override CodeExpression GetCodeExpression(

      BoundPropertyEntry entry,

      object parsedData,

      ExpressionBuilderContext context)

    {

        // boilerplate code to inject 'GetValue' in the page class

        CodeTypeReferenceExpression targetClass = new

          CodeTypeReferenceExpression(typeof(HttpsUrl));

        string targetMethod = "GetValue";

        CodeExpression methodParameter = new

          CodePrimitiveExpression(entry.Expression.Trim());

 

        return new

          CodeMethodInvokeExpression(

            targetClass, targetMethod, methodParameter);

    }

 

    public static object GetValue(string param)

    {

        return SslTools.GetAbsoluteUrl(param, ProtocolOptions.Https);

    }

}

ExpressionBuilders have to be registered in the compilation element in web.config:

<compilation debug="false">

  <expressionBuilders>

    <add expressionPrefix="HttpsUrl" type="HttpsUrl, App_Code" />

  </expressionBuilders>

</compilation>

 

 


Work in Progress
Monday, August 21, 2006 3:38:15 PM UTC  #   

Caching and SSL Pages

Browsers cache pages. We all know that. But most browsers also cache SSL secured pages. Such pages potentially contain sensitive data and you don't want that anybody who has file access to your computer (administrator, remote attacker, virus or trojan) can read that data in your browser cache, right?

You can double check IE's settings in Internet Options->Advanced->Security->Do not save encrypted pages to disk.

To disable client side caching (at least for RFC compliant browsers) in ASP.NET, you can use the OutputCache directive, e.g.

<%@ OutputCache Location="None" VaryByParam="none" %>

You can also define a cache profile for sensitive pages in web.config:

<caching>

  <outputCacheSettings>

    <outputCacheProfiles>

      <add name="Sensitive" location="None" varyByParam="none"/>

    </outputCacheProfiles>

  </outputCacheSettings>

</caching>

...and refer to it on a page:

<%@ OutputCache CacheProfile="Sensitive" %>

If you want to programmatically disable caching (e.g. in a base page or module) you can do this:

Response.Cache.SetCacheability(HttpCacheability.NoCache);

 


Work in Progress
Monday, August 21, 2006 3:11:17 PM UTC  #   
 Sunday, August 20, 2006

Partially SSL Secured Web Apps with ASP.NET

Recently I have been revisiting several ways to implement web apps that are partially secured by SSL. That means that only parts of the application use SSL transport security whereas other parts transmit data over clear text.

This can be a requirement because SSL increases the CPU load on the web server and can limit scalability. Often you need SSL only for a small subset of an application. On the other hand SSL is not the "CPU killer" as sometime stated. IIS6 also support SSL accelerators that allow to off-load the crypto operations to specialized CPUs.

IMO - in many cases it is totally OK to enable SSL protection for the whole application which will save you from some headaches. But if you want a partitioned application, you have to take several things into account.

Leaking Information
Besides the obvious cases where you maybe accidentally allow clear text connections to pages that should be SSL secured, there are more subtle things you could accidentally leak to clear text (which means it can be potentially sniffed and disclosed). Authentication cookies are a popular example. You have to make sure that such cookies are only transmitted over SSL (e.g. when you users leave the SSL secured area again after authentication).

Cookies support the secure flag which instructs RFC compliant browsers to send the cookie only over SSL. You can set this flag using the Secure property on the HttpCookie class or via web.config: 

<httpCookies requireSSL="true" />

In the case of Forms authentication, the requireSSL attribute also checks if the user is logging in from an SSL connection before calling FormsAuthentication.SetAuthCookie (something you have to check yourself if you are issuing tickets manually).  

<authentication mode="Forms">

  <forms requireSSL="true" />

</authentication>

Switching to SSL
You have to explicitly switch to SSL when you are redirecting to an SSL secured resource. This has to be done using an absolute URL like https://server/app/page.aspx. Relative URLs like the convenient ~/page.aspx won't work. This would mean that you have to hardcode those values in your code or markup.

There are several ways to work around that problem. One approach would be to write a page base class for SSL secured pages that checks for SSL and does an absolute redirect to itself if required. Like this:

public class SslPageBase : Page

{

    protected override void OnInit(EventArgs e)

    {

        if (!Request.IsSecureConnection)

            SslTools.SwitchToSsl();

 

        base.OnInit(e);

    }

}

 

Another approach would be to write a module that inspects the URL and does a redirect based on a configuration element where you specify pages or directories that should be SSL protected.

If you want to use automatic redirection to your login page by Forms authentication, you have to use one of the above approaches. Otherwise the redirection will be done using the current protocol, which may be clear text.

These both approaches are very convenient because they allow you to use relative URLs in code and markup. But unfortunately they rely on a "misconfiguration" of IIS. If IIS is configured correctly the pages and directories that should be SSL protected are marked for "SSL required" in IIS. In this case the IIS SSL check will run much earlier than ASP.NET. IIS will bounce requests with a 403.4 status code before a module or a page base class can run. Such a configuration is very typical and recommended when thinking defense in depth.

So you have to do absolute redirects at the page level. A little helper can accomplish that without having to hardcode server or vdir names.

A replacement for Response.Redirect allows the following semantics:

SslTools.Redirect("~/ssl/default.aspx", RedirectOptions.AbsoluteHttps);

...and for HTML links:

<a href="<%= SslTools.GetAbsoluteUrl
("~/ssl/default.aspx", ProtocolOptions.Https) %>">SSL Page</a>

GetAbsoluteUrl (which is ultimately used by the Redirect and SwitchToSsl methods shown earlier) constructs an absolute URL from the relative one and conserves query string parameters.

public static string GetAbsoluteUrl(string url, ProtocolOptions protocol)

{

    if (url == null)

    {

        return url;

    }

 

    // check for querystring parameters

    string path, query;

    if (url.Contains("?"))

    {

        int qpos = url.IndexOf('?');

        path = url.Substring(0, qpos);

        query = url.Substring(qpos);

    }

    else

    {

        path = url;

        query = "";

    }

 

    if (VirtualPathUtility.IsAppRelative(path))

    {

        path = VirtualPathUtility.ToAbsolute(path);

    }

 

    Uri baseUri;

    string hostName = HttpContext.Current.Request.Url.Host;

 

    if (protocol == ProtocolOptions.Http)

    {

        baseUri = new Uri(String.Format("http://{0}", hostName));

    }

    else

    {

        baseUri = new Uri(String.Format("https://{0}", hostName));

    }

 

    return new Uri(baseUri, path).ToString() + query;
}

 

Feature Request
I would love to see this functionality rolled into HttpResponse.Redirect in the next version of ASP.NET. I also think that the FormsAuthenticationModule should do an SSL redirect to the login page if the requireSSL attribute is set to true.

Will IIS7 change the situation?
Currently not. It is by design to not allow any user code to execute before IIS does the SSL check. I think it would be nice if the IIS team would implement an automatic redirect feature into the SSL check...

SslHelper.zip (.87 KB)

 


Work in Progress
Sunday, August 20, 2006 2:12:55 PM UTC  #   
 Saturday, August 19, 2006

Back from Vacation

...and really just a test of LiveWriter...

(which works really well)


Misc
Saturday, August 19, 2006 2:10:31 PM UTC  #   
 Friday, August 04, 2006

URI ACLs and Vista

I just came across this blog entry from Martin.

Seems that on Vista the functionality for setting ACLs on URIs for HttpListener is now included in netsh (makes sense). Netsh allows to simply specify the account name and doesn't force you to fluently speak SDDL anymore. woohoo.

netsh http add urlacl /url=http://+:8888/MyService /user=DOMAIN\user

If you are running a "legacy operating system" or want to do it programmatically, have a look at the tool I wrote some time ago...

 


Work in Progress
Friday, August 04, 2006 6:40:59 AM UTC  #   
 Wednesday, August 02, 2006

How to get to the Private Key File from a Certificate

I get this question from time to time. Most often because you have to set ACLs on the private key file to allow access for worker process accounts.

There is no clean way to do that in managed code. The general procedure is:

  1. Select a certificate
  2. Create an RSACryptoServiceProvider object from the certificate's PrivateKey property
  3. Retrieve the UniqueKeyContainerName property
  4. Search for this file name in the various locations where keys are stored. Thats under ApplicationData for user keys and CommonApplicationData for machine keys

If you only want to set ACLs, there are two tools that can do that for you:

I wrote a little tool that does the above steps and displays the ACL editor via ShellExecute (with a little help of the WSE3 tool and Reflector). You could of course use this code to do your own ACLing with System.Security.AccessControl.

GetCertKeyFile.zip (10.33 KB)

 



Wednesday, August 02, 2006 1:06:08 PM UTC  #   
 Monday, July 31, 2006

Joe Kaplan is blogging

Joe Kaplan finally has a blog. He is the author of this great book and you can find a lot of useful LDAP/AD and ADFS related content on his brand new blog.

http://www.joekaplan.net/

 


For Your Favourites
Monday, July 31, 2006 8:08:27 PM UTC  #   
 Saturday, July 29, 2006

The Appendixes

OK - that's the last book related post for now - if you think this information is useful and you want it at the earliest possible date - you can pre-order here or here :)

Appendix A: Building a Custom Protected Configuration Provider
Appendix B: Session State and Security
Appendix C: Compartmentalizing Web Applications
Appendix D: Web Services and Security
Appendix E: Unit Testing with Visual Studion Team Edition

 



Saturday, July 29, 2006 4:05:48 PM UTC  #   

Chapter 3: Input Validation

- What is Input?
- The Need for Input Validation
  - The Data/Control Channel Problem
    - SQL Injection, Cross Site Scripting, Directory Traversal
- Input Validation Techniques
  - Black Listing
  - White Listing
    - Data Type Conversion
    - Regular Expressions
    - XML Validation
    - Resource Access
- Mitigation Techniques
  - Output Encoding (Encoding Contexts and Encoding Controls)
  - Sandboxing
  - Integrity Checking
- Validation in ASP.NET Applications
  - Automatic Validation Services
    - Request Validation
    - ViewState Validation (+ Replay Protection)
    - Event Validation
      - Building Custom Controls with EventValidation Support
    - Header Checking
  - Form Validation
    - Manual Validation
    - Validation Controls
  - Building a Custom Validation Control



Saturday, July 29, 2006 3:59:24 PM UTC  #   

Chapter 5: Authentication and Authorization

the biggest chapter in the whole book...

Fundamentals

- Terminology
- Application Design (Trusted Subsystem vs Impersonation/Delegation)
- ASP.NET Security Pipeline and Infrastructure
  - IPrincipal and IIdentity
  - Role-based Authorization (programmatically vs declarative)
- Server Authentication

Using Windows Accounts

- IIS Authentication Methods (Basic, Digest, NTLM, Kerberos)
- Impersonation
  - Automatic vs. Programmatic
  - Impersonation Gotchas (multi-threading and async handlers, error handling)
- Delegation and How to get it to Work
- Security Context and Accessing External Resources

Using Custom Accounts

- Forms Authentication
  - Mechanics
  - Configuration
  - Security
- Customizing Forms Authentication
  - Issuing Tickets
  - Role Management
  - Role Caching (Cache vs User Data)
  - Web Farms and Single-Sign-On Scenarios
- Protecting Non-ASP.NET Resources with ASP.NET
  - Securing classc ASP

Hybrid Approaches

- Manual Windows Authentication (LogonUser vs LDAP)
- Converting a Windows Token into a GenericPrincipal
- Caching Windows Tokens
- Protocol Transition
- Basic Authentication against Custom Accounts
- Client Certificate based Authentication
  - Cryptographic Operations
  - Translating between Certificates and Windows Accounts
- Mixed Mode Authentication

 


Work in Progress
Saturday, July 29, 2006 3:43:20 PM UTC  #   
 Thursday, July 27, 2006

Manuscript Shipped

Finally! I shipped the complete manuscript to MS Press on Monday....The final book is supposed to hit the shelves in October.

With that much spare time, I am almost bored now....

 


Misc
Thursday, July 27, 2006 7:22:51 PM UTC  #   
 Tuesday, July 25, 2006

Eval is not Evil

While working through the ASP.NET security reference implementation (which is good work btw), the following guideline caught my attention:

"Additionally, all calls to DataBinder.Eval() have been removed. While Eval is sometimes safe to use on purely static data, it is best to avoid it completely as it has the potential to allow an attacker to execute arbitrary code on the host server."

That sounded a bit vague to me and a look at the source also didn't show anything specifically dangerous. I then double checked with the ASP.NET Team (specifically Stefan Schackow who is always very helpful and a great source of ASP.NET security knowledge), and they confirmed that there is no such problem with Eval.

Eval indeed supports an expression syntax (e.g. Company.Offices[0]) that allows to navigate through object hierarchies (using reflection against public properties only) and of course it may lead to unexpected results if you blindly pipe external input into Eval. I guess that's what is meant in the guideline.

But IMO the general input validation rules apply here. Also no sign of "executing arbitrary code" on the server.

The 99.9% use case of Eval is static input anyways:

<%# Eval("FirstName") %>

I have already seen blogs that multiply this information - so for now:

Eval is not Evil (until proven otherwise)

 


Work in Progress
Tuesday, July 25, 2006 10:05:56 PM UTC  #   

How to get Cookieless FormsAuthentication to work with self-issued FormsAuthenticationTickets and custom UserData

This question was asked by Scott recently.

Short answer: you can :)

The trick is to do a Response.Redirect with an appended query string in the following format:

~/Page.aspx?{0}={1}

where

{0} = forms ticket name
{1} = encrypted forms ticket string

in addition you have to set enableCrossAppRedirects to true in the forms auth config.

Here is some code (e.g. behind your login button):

  // access forms auth configuration

  AuthenticationSection section = (AuthenticationSection)

    ConfigurationManager.GetSection("system.web/authentication");

  TimeSpan timeout = section.Forms.Timeout;

       

  // create ticket with user data

  FormsAuthenticationTicket ticket = new FormsAuthenticationTicket(

    1,

    _txtName.Text,

    DateTime.Now,

    DateTime.Now.Add(timeout),

    false,

    "user defined data");

 

  // encrypt ticket

  string encTicket = FormsAuthentication.Encrypt(ticket);

  string ticketName = FormsAuthentication.FormsCookieName;

       

  // do the redirect

  Response.Redirect(String.Format("{0}?{1}={2}",

    FormsAuthentication.DefaultUrl,

    ticketName,

    encTicket));

 

The above code has one disadvantage. For some reason, the forms auth timeout is not exposed via the FormsAuthentication class and you have to access the configuration element to retrieve it. This in turn requires ConfigurationPermission which you only have in Full and High trust.

 

On the next roundtrip you can access the user data as normal:

 

if (Request.IsAuthenticated)

{

  FormsIdentity id = Context.User.Identity as FormsIdentity;

 

  FormsAuthenticationTicket ticket = id.Ticket;

  string userData = ticket.UserData;

}

 


Work in Progress
Tuesday, July 25, 2006 10:28:50 AM UTC  #   
 Monday, July 24, 2006

Update for AzMan Bulk Importer

via Joe Langley:

UPDATED 7/24/2006:
Bug fixed where top level application groups were not copied
Option added so that you can have a patch mode (patch only one application in a store...helpful if you have more than one application in a store)
 
UPDATED 7/10/2006:
Bug fixed where nested roles and nested tasks were not copied

AzManBulkImport12.zip (5.55 KB)

 


Tools
Monday, July 24, 2006 6:06:20 PM UTC  #   

iTunes and Windows 2003 - Update

OK - this is broken. The version of QuickTime that comes with the latest iTunes download is conflicting with MS06-15 (kb908531). The only work around seems to be uninstalling the hotfix (which is a critical, remote exploitable one - so don't do that).

You can read the whole thread here.

Some guy got it working using these steps:

- install iTunes 6.0.5
- get the stand-alone installer for QuickTime 7.1, start it
- go to the temp directory and copy QuickTime.msi
- right klick on QuickTime.msi and choose uninstall
- install QuickTime 7.0.4 from the link above
- use iTunes 6.0.5....

sigh.

[UPDATE: The above procedure worked for me, too]

 


Misc
Monday, July 24, 2006 7:39:55 AM UTC  #   
 Friday, July 21, 2006

ASP.NET 2.0 Security Reference Implementation

The patterns&practices group has released a version of Pet Shop that uses and applies all the PAG security guidance.

You can download the complete source code + design document here.

Interesting read (both the .doc and the source).


For Your Favourites
Friday, July 21, 2006 5:14:35 PM UTC  #   
 Thursday, July 20, 2006

BASTA 2006

Bald steht die BASTA wieder vor der Tür...Ich werde drei Vorträge über .NET Security machen. Kommt vorbei und sagt Hallo!

Architektur für stabile und sichere erweiterbare Anwendungen
Techniken wie dynamisches Laden von Assemblies und Reflection machen es einfach eine Anwendung zur Laufzeit durch externen Code zu erweitern. Dabei sollte man allerdings einige Überlegungen zur Stabilität und Sicherheit anstellen – vor allem wenn die Erweiterungsschnittstellen für Dritte gedacht sind. Dieser Vortrag behandelt den Einsatz von AppDomains und dem Simple Sandboxing API.

Integration von Windows Security in .NET-Anwendungen
Als Entwickler will man das Rad nicht ständig neu erfinden. Windows bietet bereits exzellente Sicherheitsdienste wie Benutzer und Gruppenverwaltung, Verschlüsselung, Authentifizierung und sichere Kommunikationsprotokolle sowie Impersonierung und Delegation. Mit .NET 2.0 lassen sich diese nun Dienste auch ohne Win32 Interop nutzen. Wo was wie Sinn macht beleuchtet dieser Vortrag.

Sicheres Deployment von Smart Clients mit No-Touch und ClickOnce
Deployment von Client-Anwendungen im Intranet oder gar Internet ist ein lange gehegter Traum, der immer mit Sicherheitsbedenken kollidieren wird. Nach dem etwas erfolglosen 1.x "No-Touch Deployment" wagt Microsoft einen neuen Anlauf mit dem Namen "ClickOnce" – ein praktikablerer aber auch unsicherer Ansatz – was hierbei beachtet und verstanden werden muss, beleuchtet dieser Vortrag.

 


Conferences | Microsoft Deutschland Security Portal
Thursday, July 20, 2006 9:14:32 AM UTC  #   

iTunes and Windows Server 2003

If you are running Windows Server 2003, don't upgrade to the newest version of iTunes (V6.0.5.20) - it won't work...

Does anyone know where I can download older versions??

 


Misc
Thursday, July 20, 2006 9:09:04 AM UTC  #   
 Tuesday, July 18, 2006

MSDN UK Security Nuggets

A while ago I recorded four security screencasts for MSDN UK. They are part of their Nuggets series which I always liked.

Main Page:
http://www.microsoft.com/uk/msdn/events/nuggets.aspx

 


Work in Progress
Tuesday, July 18, 2006 10:21:08 PM UTC  #   

Dark Room

That's so cool - "Dark Room - a full screen, distraction free writing environment".

I immediately liked this when I saw it, but now there is also a .NET version.

When you ever wrote a book you know what "distraction free" really means...


For Your Favourites
Tuesday, July 18, 2006 3:42:04 PM UTC  #   
 Tuesday, July 11, 2006

Information Disclosure Vulnerability in ASP.NET 2.0

Again a URL canonicalization bug. This shows two things (again):

  • It is very, very hard to get resource names and encodings right - even in big projects with a lot of testers.
  • Never store sensitive data under the application vroot (the further away the better).

Description and patch here.

 


Work in Progress
Tuesday, July 11, 2006 8:24:35 PM UTC  #   
 Monday, July 10, 2006

HttpListener Artikel Teil 2: ASP.NET Integration

Teil 2 des HttpListener Artikels ist nun online auf MSDN. In diesem Teil wird das Hosting von ASP.NET in einem custom WebServer beleuchtet. Weiterhin werden die notwendigen Schritte gezeigt wie Sicherheits-Informationen wie Authentifizierungs-Daten vom Host an ASP.NET weitergereicht werden.

Den Source Code für beide Teile kann man hier runterladen.

 


Publications
Monday, July 10, 2006 11:02:59 AM UTC  #   
 Friday, July 07, 2006

UAC Screencasts

Ian has two screencasts up on channel9 that show how to work with UAC as a developer.

http://channel9.msdn.com/Showpost.aspx?postid=211271

and

http://channel9.msdn.com/Showpost.aspx?postid=209647


For Your Favourites
Friday, July 07, 2006 7:44:08 AM UTC  #   
 Thursday, July 06, 2006

HttpListener Artikel

Teil 1 meines HttpListener Artikels ist online. Dort werden Themen with Authentifizierung, Autorisierung, Impersonierung, Sandboxing und SSL mit Client Zertifikaten besprochen.

Teil 2 wird in Kürze auch verfügbar sein - dort dreht sich alles um ASP.NET Integration.

 


Publications
Thursday, July 06, 2006 10:28:15 PM UTC  #   
 Sunday, July 02, 2006

Hosting PowerShell in ASP.NET

Having read this post. I just couldn't resist :) Of course, this is not a full featured PS host - but simple commands like get-process work and by caching the runspace you keep state between the commands you invoke.

Needless to say that such a page should be properly secured....

<%@ Page Language="C#" %>

 

<%@ Import Namespace="System.Management.Automation" %>

<%@ Import Namespace="System.Management.Automation.Runspaces" %>

<%@ Import Namespace="System.Collections.ObjectModel" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"

"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<script runat="server">

 

  protected void _btnInvoke_Click(object sender, EventArgs e)

  {

    Runspace rs = GetRunspace();

 

    Pipeline cmd = rs.CreatePipeline(_txtCommand.Text);

    Collection<PSObject> results = cmd.Invoke();

 

    StringBuilder sb = new StringBuilder();

    sb.AppendLine("Command: " + _txtCommand.Text);

    sb.AppendLine();

 

    foreach (PSObject ps in results)

    {

      sb.AppendLine(ps.ToString());

    }

 

    sb.AppendLine();

    _txtOutput.Text += sb.ToString();

  }

 

  protected Runspace GetRunspace()

  {

    if (Cache["rs"] == null)

    {

      Runspace rs = RunspaceFactory.CreateRunspace();

      rs.Open();

      Cache["rs"] = rs;

    }

 

    return (Runspace)Cache["rs"];

  }

 

  protected void _btnClear_Click(object sender, EventArgs e)

  {

    _txtOutput.Text = "";

  }

</script>

 

<html xmlns="http://www.w3.org/1999/xhtml">

<head runat="server">

  <title>ASP.NET PowerShell</title>

</head>

<body style="font-family: Arial">

  <form id="form1" runat="server"

    defaultbutton="_btnInvoke" defaultfocus="_txtCommand">

    <div>

      <h1>

        PowerShell</h1>

    <br />

    Command:

    <br />

    <asp:TextBox runat="server" ID="_txtCommand" Width="800px" />

    <br />

    <asp:Button runat="server" ID="_btnInvoke" Text="Invoke"

      OnClick="_btnInvoke_Click" />

    <asp:Button runat="server" ID="_btnClear" Text="Clear History"

      OnClick="_btnClear_Click" />

    <br />

    <br />

    History:

    <br />

    <asp:TextBox runat="server" ID="_txtOutput" Width="800px" Height="550px"

      TextMode="MultiLine" />

    </div>

  </form>

</body>

</html>

 



Sunday, July 02, 2006 8:24:07 AM UTC  #   

AuthenticateRequest vs PostAuthenticateRequest

I get questions every now and then why there are these two events and which one to use for what. The way I like to think about it:

  • If you change the IIdentity - use AuthenticateRequest.
  • If you change the IPrincipal - use PostAuthenticateRequest.

So - the built-in auth modules (Forms/Windows) establish a user identity, meaning they set Context.User.Identity - this is done in AuthenticateRequest. Another example would be when you implement your own auth mechanism (e.g. basic authentication against custom accounts).

Adding roles to an already established identity is done in PostAuthenticateRequest. RoleManager would be an example of a built-in functionality (and read this if you are doing stuff like that).

Following these rules, you achieve the best extensibility and pluggability.

To follow Rich' great analogy - it is like the pirate guidelines in "The Pirates of the Carribean" - you don't have to follow these guidelines, but it would be better if you do.



Sunday, July 02, 2006 8:12:24 AM UTC  #   

Very happy to announce...

...that Mark Curphey and Rudolph Araujo from Foundstone will contribute to my Tools & Resources book chapter!!!

Foundstone have always been my pen testing/auditing tools heros. And from books like the "Hacking Exposed" series, I learned a lot about tools & testing.

Check out their own tools - good stuff.

I am very happy to have these guys on board!

 


Work in Progress
Sunday, July 02, 2006 8:00:41 AM UTC  #   
 Saturday, July 01, 2006

Re-MVPed

My MVP award for the "Visual Developer - Security" category has been renewned for another year. thanks!

 


Misc
Saturday, July 01, 2006 5:49:11 PM UTC  #   
 Friday, June 30, 2006

ASP.NET/.NET Guidance Explorer

Die Patterns & Practices Gruppe hat eine Winforms Anwendung veröffentlicht, in der man die Security & Performance Best Practices für seine Projekt-Zwecke browsen, durchsuchen, sortieren und neu anordnen kann.

Noch Beta - aber sieht vielversprechend aus. Download.


Microsoft Deutschland Security Portal
Friday, June 30, 2006 7:01:57 AM UTC  #   
 Monday, June 26, 2006

Source Code for AzMan Bulk Importer

Joe finally got permission from his employer to realease the source code for the excellent AzMan Export/Import tool.

Essential if you are doing AzMan development.

AzManBulkImport1.zip (5.17 KB)

 


Tools
Monday, June 26, 2006 7:12:53 AM UTC  #   
 Wednesday, June 21, 2006

ASP.NET Security Hub

Auf dieser Seite hat Scott Guthrie eine Reihe von Links und Ressourcen zu ASP.NET Security zusammengestellt. Dort kann man exzellente Informationen finden, und es wird auch weiterhin Content hinzugefügt. Also ab und zu mal vorbeischauen lohnt sich.

 


Microsoft Deutschland Security Portal
Wednesday, June 21, 2006 8:58:57 AM UTC  #