
Wednesday, January 18, 2006
Neue Security Artikel Januar 2006
Auf dem Microsoft Deutschland Security Portal sind die ersten beiden Teile meiner Serie über die .NET Integration in Windows Security online (Teil1 / Teil2). Weiterhin findet Ihr dort mein Plädoyer an die Anwendungs-Sicherheit und warum Entwickler und Architekten mehr Sicherheits-Training erfahren sollten.
Viel Spass beim Lesen.
Microsoft Deutschland Security Portal
Wednesday, January 18, 2006 8:39:35 PM UTC
|
|
Cassini considered harmful
Visual Studio 2005 includes the development web server. While this is very useful to do simple stuff and proof of concept work - I see an increasing amount of issues in the ASP.NET newsgroups that all boil down to this statement: "it worked in the dev web server, but not on IIS".
There are some areas where the VS web server behaves differently than IIS - the issues in the newsgroups are mostly security related, but the VS web server is just not the "the real thing" and IMHO I would never ever develop/test/debug a real project using the VS web server.
Don't get me wrong - the VS web server is really nice and light-weight and for people running as non-admin it is much easier to work with ASP.NET, but there are certain issues you should be aware of:
- VS web server runs in the security context of the logged on user. This is a totally different security context than a IIS service account like NETWORK SERVICE. Combined with the fact, that a lot of devs run as admin - the web application effectively runs with administrative privileges. This means unrestricted access to NTFS files, registry keys, event logs, WMI, key containers, APIs etc..
This situation will totally change when the application gets deployed to IIS. A different security context (admin vs. least privilege service account) is used for DACLS checks and integrated authentication, e.g. to a file server or SQL server. Impersonation/Delegation will also behave differently... (and I've seen admins "fixing" this problem by running the production app with administrative/SYSTEM rights).
- In VS web server, all incoming requests are mapped to the ASP.NET runtime, this includes static files like .xml and .html etc. This means that these file are protected by ASP.NET URL authorization. IIS behaves totally different here. Only the standard extensions like .aspx, .ashx etc. are mapped to ASP.NET. Static content will be served by IIS directly and will not be routed to ASP.NET authorizaion. You have to manually configure IIS for this scenario. Be aware of this!
Keep this in mind when you start a new project with the VS web server, and IMO - better switch early to IIS for testing.
Work in Progress
Wednesday, January 18, 2006 12:48:39 AM UTC
|
|

Saturday, January 14, 2006
ConfigurationPermission and requirePermission
UPDATE I was actually wrong (and too lazy to properly test it). Here's the correct information:
The new ConfigurationPermission CAS permission in 2.0 protects access to configuration files using the new Web/ConfigurationManager APIs. In ASP.NET only full and high trust levels have this permission.
If you still want to be able to access config sections whithout granting this permission, you can attribute the config sections declaration in question with the requirePermission attribute, e.g. for appSettings:
<section
name="appSettings"
type="System.Configuration.AppSettingsSection, …"
requirePermission="false"
/>
By default only the appSettings, connectionStrings and the xmlSerializer sections require no permission.
Work in Progress
Saturday, January 14, 2006 5:13:53 PM UTC
|
|
Useful VS keyboard shortcut
I love this little smart tags in VS2005, e.g. "add using statement" or "generate method stub". I always found that it is an interruption in my workflow to use the mouse to activate these functions. Fortunately there is a shortcut to open the smart tag menu and it is: Alt+Shift+F10. great!
UPDATE: Denis commented that Ctrl-period is a easier way to get to the smart tag. Excellent! thanks.
Misc
Saturday, January 14, 2006 5:06:07 PM UTC
|
|

Friday, January 13, 2006

Thursday, January 12, 2006
HttpOnly and ASP.NET 2.0
HttpOnly is a flag that you can append to cookies which makes it a little bit harder for cookie harvesting attacks (e.g. via XSS) to steal your valuable cookies containing authentication tickets or session IDs. I wrote about it here before.
ASP.NET 2.0 now features a HttpOnly property on the HttpCookie class which adds the flag when set to true. Session and authentication cookies always have this flag set. You can also configure the default behaviour of your manually issued cookie by using this configuration element:
<httpCookies httpOnlyCookies="true" />
Unfortunately, this is not the default setting and you have to configure that manually in your web.config.
Work in Progress
Thursday, January 12, 2006 6:50:11 PM UTC
|
|
C++/CLI Webcast
Marcus, my fellow german DM instructor, finally surfaces again after digging 8 months into the new C++ compiler shipped with .NET 2.0 - one of his first signs of life:
A webcast on msdn.microsoft.com/visualc
"DevelopMentor instructor and C++/CLI guru, Marcus Heege, presents a video on the powerful ability to freely mix native C++ and Managed C++. This combination enables you to augment your existing C++ applications with the .NET Framework's classes and types giving you the best of both worlds!"
watch it here. For Your Favourites
Thursday, January 12, 2006 2:50:33 PM UTC
|
|

Tuesday, January 10, 2006

Monday, January 09, 2006
AzMan Bulk Importer / Converter
Joe Langley, a guy I speak to from time to time about AzMAn and other security related stuff sent me a very neat utility to import / convert AzMan stores between different formats (XML to AD and vice versa). This allows to painlessly start with local XML stores and import them into AD at some later point.
This tool was written as part of his day job, so unfortunately he is not allowed to release the source code...
AzManBulkImport.zip (11.48 KB)
Tools
Monday, January 09, 2006 8:12:23 PM UTC
|
|

Saturday, December 31, 2005
New Year, New Operating System
I just upgraded all domain controllers and some application server and development VMs to Windows Server 2003 R2.
Let's see if I can install Longhorn Server by the end of this year :)
Happy new year! Misc
Saturday, December 31, 2005 1:10:26 PM UTC
|
|

Wednesday, December 28, 2005

Tuesday, December 27, 2005
ASP.NET 2.0 Provider Ressourcen
Eine 100-seitige Dokumentation über das Provider-Modell sowie Beispiele für Membership, Role, Navigation etc. Provider findet man hier.
Einen Provider zu schreiben ist meiner Meinung nach nicht so einfach wie das oft dargestellt wird.
- Das Provider Modell an sich hat seine Grenzen (und das Überschreiten dieser führt oft zu der Erkenntnis das man mit einem nicht-Provider feature besser gefahren wäre).
- Eine "erfolgreicher" Provider verfolgt ein genaues Entwurfs-Muster
- Provider müssen Thread-Safe sein
Deswegen kann ich jedem, der plant einen eigenen Provider zu schreiben, diese Dokumentation ans Herz legen.
Microsoft Deutschland Security Portal
Tuesday, December 27, 2005 8:56:57 AM UTC
|
|

Saturday, December 17, 2005
NegotiateStream and NTLM
A question from a newsgroup:
"I have two non-domain Windows XP machines - I want to use NegotiateStream to get an NTLM authenticated connection between the two - but I don't have mirrored accounts - can I pass credentials to AuthenticateAsClient?"
Yes you can. You can create a NetworkCredential object that holds the username and password used for authentication. It is a little odd that the overload of AuthenticateAsClient also requires you to pass an SPN - which is not used for NTLM but for Kerberos. But it turns out that you can use string.empty for the SPN and NTLM with your supplied credentilas is used. Like this:
NetworkCredential cred = new NetworkCredential("user", "password", "machine");
negotiateStream.AuthenticateAsClient(cred, string.Empty);
For Your Favourites
Saturday, December 17, 2005 7:57:11 PM UTC
|
|

Friday, December 16, 2005

Tuesday, December 13, 2005
Windows 2003 R2 geht RTM
Der "Refresh" von Windows 2003 ist bald generell verfügbar - MSDN subscriber können jetzt schon downloaden.
Neben einigen Neuerungen im Infrastruktur und Storage Bereich stehen folgende Security Features ganz oben auf meiner Todo-Liste:
- Neuerungen im Authorization Manager (Support für ADAM principles, SAML)
- ADFS - die neue Technologie für Single-Sign-On Lösung mit AD und ASP.NET
- Das Common Logging File System - eine neues Logging-Konzept das über einen Datei-System Treiber realisiert wird - System.IO.Logging ist das managed API dafür...
Mehr Infos: http://www.microsoft.com/windowsserver2003/default.mspx
Dazu bald in Kürze mehr.. Microsoft Deutschland Security Portal
Tuesday, December 13, 2005 12:05:51 PM UTC
|
|

Sunday, December 04, 2005
Why AspNetTokenRoleProvider?
ASP.NET 2.0 ships with three role providers - one for SQL Server, one for AzMan and one for Windows tokens...
The Windows token provider is special - it only works with Windows authentication whereas all the other providers seem to be more targeted at Forms Authentication (the AzMan provider supports both).
Why do I need a role provider for Windows accounts? You don't have to take care of getting roles for Windows users as they come packaged in the token that gets procuced during authentication in IIS.
Well - the WindowsTokenRole provider can do some optimizations to Windows authentication
- Instead of a WindowsPrincipal you get a RolePrincipal which features a method called GetRoles() that returns all roles as a string array. This is more straightforward than using the code I showed here. You still have access to the underlying WindowsIdentity (Context.User.Identity) and can create a WindowsPrincipal if you have to.
- RoleManager can cache the roles. The first time you call IsInRole, RolePrincipal will fetch all roles from the token (which requires round trips to the DC to translate the SIDs to "human-readable" names. These names can get cached in the roles cookie (.aspxroles). This saves the roundtrip to the DC on subsequent requests.
So this is really just an (optional) optimization for Windows authentication based web apps. If you want to use role caching make sure to set reasonable timeouts (e.g. 30mins) - otherwise group membership changes for the user will have a high latency in your application.
Work in Progress
Sunday, December 04, 2005 7:07:38 AM UTC
|
|

Tuesday, November 29, 2005

Monday, November 28, 2005
Cloned Machines and the DTC
Yesterday I spent three hours troubleshooting a distributed transaction problem - ASP.NET just gave me a E_FAIL - which was not very helpful. After testing the connection with DTCPing - I got the message that both machines have the same CID value (a GUID identifying the DTC instance) - this was - well - understandable - as both machines are linked VMWare clones.
To get a new CID value for a machine run
msdtc -uninstall msdtc -install
and reboot. At least this solved my problems..
Monday, November 28, 2005 3:56:15 PM UTC
|
|

Saturday, November 26, 2005
ASP.NET Authorization Settings
A lot of people have asked me in the past why they need an explicit <deny user="*" /> at the end of ASP.NET authorization control lists.
Let's demystify that.
ASP.NET has a hierarchical configuration system. The root web.config is stored in the .NET Framework directory. This web.config has the following global authorization settings:
<authorization> <allow users="*" /> </authorization>
When you create a new web application, all web.config settings (global, site and local) are merged together to form the configuration that's really in effect for this application. By default a local web.config does not contain an authorization section but inherits the one defined globally. So you alway end up with a <allow user="*" /> entry.
If you now configure the following authorization list in your local config:
<authorization> <allow roles="HR" /> </authorization>
You really get this at runtime:
<authorization> <allow roles="HR" /> <allow users="*" /> </authorization>
And this means everybody is authorized. If you add an <deny users="*" /> at the end of your list you get:
<authorization> <allow roles="HR" /> <deny users="*" /> <allow users="*" /> </authorization>
Which does exactly what we want (ASP.NET parses the list top to bottom and the first match found is used).
You can have a look at the aggregated configuration that is currently in effect for your application whith this piece of code:
protected void _btnSaveConfig_Click(object sender, EventArgs e)
{
Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
config.SaveAs(_txtConfig.Text, ConfigurationSaveMode.Full, true);
}
Work in Progress
Saturday, November 26, 2005 12:01:56 PM UTC
|
|

Friday, November 25, 2005
IIS6 and Client Certificates
Adding client certificate authentication to a web application can enable some interesting scenarios, e.g.
- multi-factor authentication (something you have: a certificate / something you know: a password)
- restrict access to an application to selected hardware where the cert is installed. You maybe want to prevent that your users login using a computer in an internet cafe (with possible keyloggers etc. installed). Certificates on the client can be marked as "non-exportable"
- You can map the certificate to Active Directory accounts, either via configuration or by pulling out the UPN from the cert and getting a Protocol Transition token. This enables scenarios where clients connect over the internet and you "convert" their certificate to a Kerberos credential.
- You can encrypt data on the server using the client's public key transmitted during the SSL handshake.
Unfortunately, the documentation on using client certificates with IIS6 is a little - well - sketchy.
I had some issues - here's a quick walkthrough
First enable and require SSL for the application and require client certs (this is done in the IIS directory security dialog). Then issue a certificate to the user.
sounds easy...
If you browse to the application, IE sends the "right" client cert auto-magically to the server and if it is valid, IIS lets the request through to the application where you can access the cert using Request.ClientCertificate.
But what is the "right" certificate? During the SSL handshake the web server sends a list of allowed root CAs to the browser. The client cert has to be issued from one of these CAs. If IE finds a certificate issued by one of the allowed CAs he automatically sends it to the server. If IE finds multiple suitable certificates, you get a dialog box where you can choose the cert to use for authentication.
...and what are allowed CAs? The CA cert on the server must have an intended purpose of "Client Authentication". And that's what bit me - I requested a test cert from the german TrustCenter CA - but it didn't show up in IE's certificate selection dialog. Test certs from TrustCenter are issued from the "TC TrustCenter Class 1 CA" (and this CA is trusted by Windows 2003). I guess because this CA is only used for test certs the "Client Authentication" intended purpose is not enabled by default. To enable it - navigate to the Trusted CA container in the certificate MMC snapin - right click - properties - and enable "Client Authentication".
Now IE also allows you to select the cert from this CA.
Thanks to Andreas Klein from Microsoft Germany for helping me with this issue.
Friday, November 25, 2005 9:43:14 AM UTC
|
|

Thursday, November 24, 2005
ShowContexts - another update - I admit it
After finding this issue, I felt like I have to look at the different principals more granularly.
It is now showing:
- authentication & impersonation configuration settings
- type of Membership and Role provider
- trust level
- type of current IPrincipal/IIdentity on Context.User
- type of current IPrincipal/IIdentity on Thread.CurrentPrincipal
- process identity
- thread identity (if impersonating)
- Context.User name and authentication type
- Thread.CurrentPrincipal name and authentication type
- IIS authentication outcome used by FileAuthorizationModule
- client certificate (and the embedded UPN if from a Windows enterprise CA)
- roles (for Windows-, Roles- and GenericPrincipal)
ShowContexts1234.zip (2.29 KB)
Tools
Thursday, November 24, 2005 4:25:54 PM UTC
|
|

Wednesday, November 23, 2005
Context.User vs. Thread.CurrentPrincipal
The whole .NET authentication/authorization infrastructure is centered around two interfaces: IIdentity (taking care of who the user is - authentication) and IPrincipal (coupling roles with the Identity - used for authorization). The designated place to store that information is Thread.CurrentPrincipal.
Afterwards you do role checks by calling Thread.CurrentPrincipal.IsInRole - or use PrincipalPermission.Demand or [PrincipalPermissionAttribute] (which does nothing else than calling IsInRole on Thread.CurrentPrincipal under the covers). So far so good.
ASP.NET encourages you to use the "convenience" Context.User / Page.User which also point to an IPrincipal implementation and call IsInRole from there. But because PrincipalPermission relies on Thread.CurrentPrincipal and you maybe want to port a library used in desktop applications (where the Thread.CurrentPrincipal style is used) - ASP.NET has to populate Thread.CurrentPrincipal too - and synchronize it with Context.User.
When you want to plug into Forms Authentication in ASP.NET 1.1, you typically handled the AuthenticateRequest event in the HTTP pipeline. There you fetched the roles for the authenticated users, created an IPrincipal implementation and set Context.User to this new principal. Directly after AuthenticateRequest a (mostly) undocumented event fires called "DefaultAuthentication" and a module called DefaultAuthenticationModule subscribes to this event. This module has only one job, to copy Context.User to Thread.CurrentPrincipal so both values are in-sync.
In ASP.NET 2.0 there is the new PostAuthenticateRequest event and I like to think about the relationship between these two events in this way: AuthenticateRequest is used to create the IIdentity (identity information) and PostAuthenticateRequest is used to couple roles to that identity (authorization). The RoleManagerModule which has the job to couple roles from the provider backed store to the authenticated identity subscribes to exactly this event.
There is one gotcha though - ASP.NET does not take care of syncing Context.User and Thread.CurrentPrincipal after PostAuthenticateRequest - which is a bug IMO. So if you follow the pattern you know from 1.1 and set Context.User in PostAuthenticateRequest, Context.User and Thread.CurrentPrincipal will have different values. You may write really complex ASP.NET application whithout ever noticing that, but recently I plugged a custom IPrincipal implementation for AzMan into an ASP.NET 2.0 application and saw strange errors until I found out what the problem was. I set Context.User in PostAuthenticateRequest and my implementation contains an [AzManPrincipalPermission] which relies on Thread.CurrentPrincipal - but this was set to the wrong value because I relied on ASP.NET to sync to Context.User - which is not the case.
I wonder why the DefaultAuthentication event fires before PostAuthenticateRequest - maybe to guarantee that Thread.CurrentPrincipal and Context.User are correctly populated when the even fires. But why doesn't it also fire then after PostAuthenticateRequest to sync again??
So you basically have 2 choices:
1. Put the code in AuthenticateRequest and set Context.User. There are some implications:
- Make sure your module runs after the built-in authentication modules
- You run before RolesManager
- If you call code from AuthenticateRequest (or another module handles the event after you) that relies on Thread.CurrentPrincipal you have to set it anyway.
2. Put the code in PostAuthenticateRequest (which seems to be the designated place) and set Context.User = Thread.CurrentPrincipal = myPrincipal;
RoleManager also fires a GetRoles event where you can override the role fetching, but if this event is handled (and you set the EventArgs.RolesPopulated property to true) all RoleManager logic will be bypassed (including the step that syncs Context.User and Thread.CurrentPrincipal - aargh).
Proposed solution: Always set Thread.CurrentPrincipal and see those implementation details leak through or Microsoft has to sync both values after PostAuthenticateRequest.
This implementation detail was nicely hidden in 1.1 - why do i have to think about that in 2.0 ??
any thoughts?
Work in Progress
Wednesday, November 23, 2005 8:25:43 AM UTC
|
|

Saturday, November 19, 2005
ShowContexts - final update
Hopefully the final update - now it shows:
- authentication & impersonation configuration settings
- type of Membership and Role provider
- type of current IPrincipal/IIdentity on Context.User
- process identity
- thread identity (if impersonating)
- Context.User
- IIS authentication outcome used by FileAuthorizationModule
- client certificate (and the embedded UPN if from a Windows enterprise CA)
- roles (for Windows-, Roles- and GenericPrincipal)
ShowContexts123.zip (1.96 KB)
Work in Progress
Saturday, November 19, 2005 1:05:33 PM UTC
|
|

Wednesday, November 16, 2005

Monday, November 14, 2005
Tracing System.Net
Often, the last secret weapon you have when troubleshooting networked applications is a packet sniffer. If you ever need one, don't bother looking around, grab a copy of ethereal.
But there are also situations where sniffing is not easily possible, e.g. when you are using transport security like SSL, when you use the loobback address or you simply can't install a sniffer on the machine.
In .NET 2.0 you can enable tracing for the whole .NET network stack (aka System.Net). This can be done on a per-application basis using a configuration file. The trace output is really interesting. It shows the process and thread ID, the payload of the data (regardless of transport security as tracing happens much earlier) and lots of interesting protocol information.
To see what's going on in the network stack simply add the following to a configuration file:
<system.diagnostics>
<trace autoflush="true" />
<sources>
<source name="System.Net">
<listeners>
<add name="TraceFile" />
</listeners>
</source>
</sources>
<sharedListeners>
<add
name="TraceFile"
type="System.Diagnostics.TextWriterTraceListener"
initializeData="NetTrace.log" />
</sharedListeners>
<switches>
<add name="System.Net" value="Verbose" />
</switches>
</system.diagnostics>
and do a simple network operation like:
new WebClient().DownloadData("http://www.leastprivilege.com");
and inspect the NetTrace.log file.
You can have even more fun with stuff like web service proxies or the AuthenticatedStream classes.
Very useful!
Monday, November 14, 2005 6:44:10 PM UTC
|
|
DevWeek 2006
DevWeek 2006 is coming. The event takes place february, 20-24 at the amazing business design centre in London. If you get a change to attend, do it. Great venue, great people and great speakers, including some of my DM colleagues like simon horell, kevin jones, ted neward and niels berglund.
I will do a talk about ClickOnce security and a full day workshop about ASP.NET security. The ASP.NET security material will be from the brand new DevelopMentor course called "Developing secure ASP.NET Applications", which will debut the week right after at our training centre in London Hammersmith.
Conferences
Monday, November 14, 2005 5:35:27 PM UTC
|
|

Saturday, November 05, 2005
FormsAuth persistent cookies & 2.0 RTM
In ASP.NET 1.1 and 2.0 Beta2 persistent cookie that were placed using RedirectFromLoginPage and SetAuthCookie had a life time of 50 years. I wrote about that here.
In 2.0 RTM, this behaviour has changed. The timeout value of the <forms /> config element is used now. If you have set a 20 minutes timeout, the cookie expiration time will be set to 20 minutes, too.
Thats a good choice IMO; persistent cookies are dangerous, cookies with a nearly unlimited life time even more. Cookies containing a forms authentication ticket are completely self containing and can be easily replayed, even after years. Rudolph Aurajo wrote a paper about that here.
If you really want to persist the cookie (for a longer time than specified in the timeout attribute), you have to create the forms auth ticket yourself and set the cookie and expiration time manually now. Work in Progress
Saturday, November 05, 2005 12:05:46 PM UTC
|
|

Friday, October 28, 2005
HttpCfg GUI Tool
Steve started writing a nifty GUI tool for HttpCfg. Good work.
Now, Keith convinced him to incorporate his ACL dialog helper, maybe I can convince him to add support for well known SIDs - like here.
cool!
For Your Favourites
Friday, October 28, 2005 6:14:40 AM UTC
|
|

Tuesday, October 25, 2005

Thursday, October 20, 2005
ShowContexts - updated again (and again)
I guess this is the final update for ShowContexts.aspx - it now shows:
- authentication & impersonation configuration settings
- type of Membership and Role provider
- type of current IPrincipal/IIdentity on Context.User
- process identity
- thread identity (if impersonating)
- Context.User
- IIS authentication outcome used by FileAuthorizationModule
- client certificate
ShowContexts12.zip (1.51 KB)
Work in Progress
Thursday, October 20, 2005 1:08:25 PM UTC
|
|

Tuesday, October 18, 2005

Monday, October 17, 2005

Thursday, October 13, 2005
More on protecting static Resources with ASP.NET 2.0
I forgot to mention that there are also special directories in ASP.NET that generally cannot be browsed, e.g. App_Data and App_Code (there are more). App_Data seems to be the "designated" directory to put files that should under no circumstances be downloadable (e.g. file deployed SQL server databases).
Yesterday I showed the HttpForbiddenHandler which will emit a HTTP 403 - this leaks information, namely that the file exists but the client is not authorized to view it, better would be to generate a generic 404 (not found) status code.
Here - they suggest to use the HttpNotFoundHandler. Unfortunately this handler is internal and cannot be used by your code (at least on RC1). It is easy to write your own handler to accomplish the same task.
public class NotFoundHandler : IHttpHandler
{
public bool IsReusable
{
get { return true; }
}
public void ProcessRequest(HttpContext context)
{
throw new HttpException(404, context.Request.Path + " not found");
}
}
Put that e.g. in App_Code and add the following to web.config:
<httpHandlers>
<add path="*.xml" verb="*" type="NotFoundHandler, App_Code" validate="True" />
</httpHandlers>
When you now try to browse a .xml file, you will get a nice generic "the resource cannot be found".
UPDATE: HttpNotFoundHandler is internal and cannot be used from end-user code, nevetheless it can be used in config. So i was wrong.
Work in Progress
Thursday, October 13, 2005 7:41:03 AM UTC
|
|

Wednesday, October 12, 2005
Protecting non-ASP.NET resources with ASP.NET 2.0
A common problem I see in audits is, that people throw all kinds of files into their ASP.NET vdir (like .xml, .mdb etc) and just assume that these files will be protected by ASP.NET authentication & authorization. This is not the case.
IIS passes all ASP.NET related requests (.aspx, .asmx etc) to the ASP.NET AppDomain, everything else is served directly by IIS. If you want that your static files (or .asp files - more on that later) are handled by ASP.NET and its security system, you have to configure IIS to pass these requests to ASP.NET, too. This is done in the configuration settings of you IIS web application. In the script mappings dialog you configure which extensions are passed to which ISAPI extension - if you want to add specific extensions, add a new script mapping in the upper half of the dialog (have a look at which .dll the .aspx extension is configured for and use the same one for your static file).
Another option is to map every extension to ASP.NET. This is done in the wildcard mapping section in the lower part of the dialog. Just add the aspnet_isapi.dll here and all requests will be forwarded to ASP.NET. Be sure to uncheck "verify if file exists", otherwise "virtual" URLs like WebResource.axd won't work anymore.
By configuring a HttpForbiddenHandler you can now selectively deny files from being accessed via the browser.
<httpHandlers>
<add path="*.xml" verb="*"
type="System.Web.HttpForbiddenHandler" validate="True" />
</httpHandlers>
Well, before ASP.NET 2.0 this was not very practical because now the ASP.NET runtime has to serve all requests which resulted in a major performance degradation. In ASP.NET 2.0 the underlying architecture has changed to provider better support for this scenario. All unknown file extensions are now handled by a class called DefaultHttpHandler.
<add path="*" verb="GET,HEAD,POST" type="System.Web.DefaultHttpHandler" validate="True" />
This special handler accomplishes, that requests for static (or non-ASP.NET files) only pass the "front half" of the HTTP pipeline (including the important Authenticate and AuthorizeRequest events). Right before the point where page execution would normally begin, ASP.NET bounces the request back to IIS. This is much faster and gives you the best of both worlds. You can use the ASP.NET security infrastructure (e.g. forms authentication) to protect the files but you don't lose the performance of IIS request processing.
If you need more control, you can derive from DefaultHttpHandler and customize its behaviour. If you override the OverrideExecuteUrlPath method, you can modify the request path that gets handed back to IIS. You can also add new HTTP header to the request by adding entries to the ExecuteUrlHeader collection. This enables you e.g. to protect a classic ASP application with ASP.NET forms authentication and you can pass the user and role information via headers from ASP.NET to ASP.
Warning: Be sure to validate and authenticate the headers you pass with ExecuteUrlHeader, e.g. by adding a MAC using a secret that is shared between ASP and ASP.NET (HMACSHA1 would be a possibility).
Work in Progress
Wednesday, October 12, 2005 11:52:01 AM UTC
|
|

Tuesday, October 11, 2005
ShowContexts - updated again
I am currently writing the authentication & authorization chapters of my book...the little ShowContexts.aspx page is invaluable for testing - and I even extended it a little bit and added client certificate support - so now it shows:
- authentication & impersonation configuration settings
- process identity
- thread identity (if impersonating)
- Context.User
- IIS authentication outcome used by FileAuthorizationModule
- client certificate
ShowContexts1.zip (1.29 KB)
For Your Favourites
Tuesday, October 11, 2005 5:24:58 PM UTC
|
|
CLFS and Vista
here I found the managed API for the Common Log File System. I was not sure at that time if CLFS is also included in Vista (5219) because I got some strange exceptions when I tried to use the classes. As it turns out, there is a small bug in the LogStore class, especially when you pass FileMode.Create in the ctor. OpenOrCreate works. So, for now you want to start with something that looks like this:
using (LogStore store = new LogStore("log:myLog", FileMode.OpenOrCreate))
{
// do logging
}
(thanks to David Aiken from Microsoft for pointing that out)
Work in Progress
Tuesday, October 11, 2005 5:17:18 PM UTC
|
|

Sunday, October 09, 2005
ASP.NET 2.0 Deployment Mode
ASP.NET 2.0 features a new configuration element called deployment. If you set this in machine.config - debugging, tracing and detailed errors are turned off machine wide. This is a nice switch for admins to make sure a dev didn't forget to set the correct values in his local application.
<deployment retail="true" />
Work in Progress
Sunday, October 09, 2005 8:12:40 AM UTC
|
|

Friday, October 07, 2005
Secure Remoting
Because i have been asked by several people recently - here is a simple remoting example that uses the NegotiateStream class for the TCP channel (and shows how to impersonate the client).
SecureRemoting.zip (19.77 KB)
Samples
Friday, October 07, 2005 7:46:42 PM UTC
|
|

Wednesday, October 05, 2005

Tuesday, October 04, 2005

Wednesday, September 28, 2005
Common Log File System
One upside of being ill (I brought a flu virus from the last conference with me) is, that at some point you are so fed up with "recovering", that you start looking around for new technologies (don't do something work related - because you have to recover :)
One thing I was ranting about recently is, that all of these fancy new OS technologies in R2 and Vista will not be supported managed right from the start, and that Mr. P/Invoke will be a frequent guest at your house for some years again. And one of my prime examples was the new Common Log File System (CLFS). But hey, I was wrong.
System.IO.Log seems to be the managed implemenation of CLFS. woohoo. Now I only need a R2 dev image (as it does not seem to work on Vista, yet)....
Of course, only after I have fully recovered again :)
Work in Progress
Wednesday, September 28, 2005 7:17:37 AM UTC
|
|

Monday, September 26, 2005

Sunday, September 18, 2005
Authorization Manager and Vista
I just spotted that AzMan under Vista (build 5219) now support three types of authorization stores. Active Directory/ADAM, XML and ...tada.. SQL Server.
Work in Progress
Sunday, September 18, 2005 9:10:59 PM UTC
|
|

Tuesday, September 13, 2005

Thursday, September 08, 2005
Updated ShowContexts and Request.LogonUserIdentity
In ASP.NET you have to juggle with a number of identities, e.g.
- The account of the worker process
- The account of the client (= Context.User / Thread.CurrentPrincipal)
- The Thread identity (when client/application impersonation is used)
- The outcome of IIS authentication (used by the FileAuthorizationModule)
This can be confusing, e.g. when IIS is set to anonymous, but ASP.NET <authentication> is set to Windows (the default), you may wonder why the IUSR_ account needs read access to the .aspx files. This is because the FileAuthorizationModule uses the the security context that resulted from IIS authentication to check if the user is authorized.
In ASP.NET 2.0 you can now access this identity, too. It is stored in Request.LogonUserIdentity. So if you should need to impersonate the account that is set in IIS for anonymous access, this is now easily possible. I have updated the ShowContext.aspx helper, to show you all four identities. Nice for troubleshooting.
ShowContexts2.zip (1.24 KB)
Work in Progress
Thursday, September 08, 2005 8:39:21 AM UTC
|
|
Getting all Groups for a Windows Account in .NET 2.0
UPDATE: Thanks to Keith for pointing out a much simpler way (doh!). Removed my bad source code, added a new, good one.
Given the complexity of today's Active Directory installations, the only safe way of getting all Windows groups a user is member of, is to inspect the token.
After you have acquired a token (e.g. though IIS authentication, LogonUser or Protocol Transition), wrap it in a WindowsIdentity and call:
private static string[] getRoles(WindowsIdentity id)
{
List<string> groups = new List<string>();
IdentityReferenceCollection irc = id.Groups.Translate(typeof(NTAccount));
foreach (NTAccount acc in irc)
{
groups.Add(acc.Value);
}
return groups.ToArray();
}
much better now. Work in Progress
Thursday, September 08, 2005 7:18:34 AM UTC
|
|

Wednesday, September 07, 2005
Writing Secure ASP.NET Applications
As I stated earlier, I am in the process of writing a course and book about the above topic. The rough outline will be:
- Threats & Mitigation Techniques & Guidelines
- IIS6 & ASP.NET Architecture
- Input Validation
- Storing Secrets
- Authentication & Authorization
- ASP.NET 2.0 Security Provider
- Instrumentation
- Partial Trust
- Deployment & Hardening
- Tools & Resources for Pen-Testing
Do you like anything special covered, with what have you been struggling with? Write me an email or leave a comment, thanks! Work in Progress
Wednesday, September 07, 2005 6:58:04 AM UTC
|
|

Tuesday, September 06, 2005
More on locking down Partial Trust ASP.NET
This is a follow up to an earlier post.
I found a much easier way to lock down trust levels for individual applications. Still the scenario is that you have multiple web applications on a server, some should run in partial trust, some should run in full trust (and maybe also different levels of partial trust).
The rule of thumb is, that you have to lock down the configuration at least one level higher in the hierarchy than the application you want to lock down. For our scenario this could be site or machine level config. The following web.config in your site root will do the trick (works for relative paths under the root and vdirs):
<configuration>
<location path="App1" allowOverride="false">
<system.web>
<trust level="High"/>
</system.web>
</location>
<location path="App2" allowOverride="false">
<system.web>
<trust level="Medium" />
</system.web>
</location>
</configuration>
This sets the trust level for individual applications and the allowOverride prevents those applications from changing the settings. With the new configuration granularity we have in 2.0 it is even possible to partially lock down settings, e.g. the next sample locks the the trust level but still allows the individual applications to set the originUrl attribute.
<location path="AppWebService" allowOverride="true">
<system.web>
<trust level="Medium" lockAllAttributesExcept="originUrl"/>
</system.web>
</location>
It is even possible to set this in global web.config by including the site name (don't know if this is a new feature in 2.0, it was new to me at least). This allows some interesting scenarios...
<location path="Default Web Site/AppDomainFun" allowOverride="false">
<system.web>
<trust level="Medium"/>
</system.web>
</location>
This makes it a much smoother story than the single policy file approach I described in my previous entry.
Work in Progress
Tuesday, September 06, 2005 7:00:21 AM UTC
|
|

Saturday, August 27, 2005

Thursday, August 25, 2005

Wednesday, August 24, 2005
Shawn's What's new in .NET 2.0 Security
Shawn has a summary of new security features on his blog. Instead of the biggies like X509 support, negotiate stream and secure remoting he focuses more on (yet) unknown stuff like SecurityTransparent, Host Protection, AppDomainManager, FIPS enforcement a.s.o.
As you can see, the list is not complete and shawn will update this page when new articles get added. so check back. very recommended For Your Favourites
Wednesday, August 24, 2005 4:09:34 PM UTC
|
|

Thursday, August 11, 2005
Security makes my World go round
I finally consolidated my calendar for, say the next 9 months - and I like what I see, seems I will solely work on security topics for the next year. Currently I am writing a course for DevelopMentor and a book for O'Reilly, both code-named "Writing Secure ASP.NET Applications" (more on that later).
Furthermore I am taking more responsibilities in the overall security curriculum at DevelopMentor, this includes writing two new courses in the future (and I am especially excited about that): "Essential WinFX Security" (running on Vista) and the security modules for our Guerilla format of the WinFX course. woohoo.
Work in Progress
Thursday, August 11, 2005 9:36:37 AM UTC
|
|

Tuesday, August 09, 2005

Saturday, August 06, 2005

Tuesday, August 02, 2005
HttpCfg ACL Helper
Windows 2003 and XP SP2 include HTTP.SYS. This is a kernel mode http listener that is e.g. used by IIS6. A nice thing with http.sys is, that it enables port sharing. That means you can have several processes on your system listen e.g. on port 80. If you want to host a http listener in your own application, you use the http API to register a URI namespace with http.sys, e.g. 'http://*:80/MyApp/' registers for receiving all incoming requests to that URI. The new HttpListener class which will be included in .NET 2.0 is a nice managed wrapper for that functionality.
This can enable all kinds of interesting scenarios, e.g. embedding lightweight web servers in applications or hosting a web service or ASMX endpoint (like Aaron described in his article on MSDN here). Indigo uses HttpListener for ServiceHost<T> e.g.
One security feature of http.sys that most developers are not aware of is, that only users with administrative privileges can register arbitrary namespaces (sorry, of course i know that YOU are not running as admin, but most of the others do :)). This is by design. Otherwise it would be very easy for malware to 'hide' behind already opened ports.
If you want to enable HttpListener in applications which will be run by normal users, you have to reserve and ACL a namespace during deployment of the application. A tool called 'httpcfg.exe' can be used for this (included in the support tools for Server 2003 or for download for XP here).
The problem is, there is no managed API for reserving namespaces, but this would be indeed very useful for setup programs. The command line tool version is not very user friendly too, e.g. you have to set the ACL as a SDDL string, and i guess not everybody is fluent in that. A example (sets a GENERIC_EXECUTE on a URI for a user account):
httpcfg set urlacl /u http://*:8080/MyEndPoint/ /a D:(A;;GX;;;S-1-5-21-1144070942-1563683482-3278297161-1114)
I wrote a little tool where you can select user accounts, groups and well known SIDs (I currently don't support well known SIDs that need a domain SID). The tools spits out the right httpcfg syntax for your selection as well as copies the SDDL string to the clipboard.
Make httpcfg your friend. There is no excuse to run with elevated privileges!
HttpCfgAcl.zip (24.19 KB)
Tools | Work in Progress
Tuesday, August 02, 2005 6:53:14 PM UTC
|
|

Monday, August 01, 2005
ASP.NET MembershipProvider for Web.config (2nd Try)
OK - sometimes you are so focused on one technology that you just forget another. A significantly simplified version of the MemberShipProvider i posted here:
public class WebConfigMembershipProvider : MembershipProvider
{
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
base.Initialize(name, config);
}
public override bool ValidateUser(string username, string password)
{
if (FormsAuthentication.Authenticate(username, password))
{
new AuthenticationSuccessEvent(username, this).Raise();
return true;
}
else
{
new AuthenticationFailureEvent(username, this).Raise();
return false;
}
}
}
Samples | Work in Progress
Monday, August 01, 2005 2:02:52 PM UTC
|
|

Wednesday, July 27, 2005
ASP.NET MembershipProvider for Web.config
I had dinner with IanG, Fritz, Si and Kev. We had the obligatory tech-talk in between and thought about useful custom provider for ASP.NET - at some point Fritz came up with the idea of a MembershipProvider which reads from the good old web.config <credentials> element. That sounded like fun - so here it is (full sample here):
public class WebConfigMembershipProvider : MembershipProvider
{
private FormsAuthenticationUserCollection _users = null;
private FormsAuthPasswordFormat _passwordFormat;
// not implemented members omitted
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
{
base.Initialize(name, config);
_passwordFormat = getPasswordFormat();
}
public override bool ValidateUser(string username, string password)
{
try
{
if (_passwordFormat == FormsAuthPasswordFormat.Clear)
{
if (getUsers()[username].Password == password)
{
new AuthenticationSuccessEvent(username, this).Raise();
return true;
}
}
else
{
if (getUsers()[username].Password == FormsAuthentication.HashPasswordForStoringInConfigFile(password, _passwordFormat.ToString()))
{
new AuthenticationSuccessEvent(username, this).Raise();
return true;
}
}
}
catch
{
new AuthenticationFailureEvent(username, this).Raise();
}
return false;
}
protected FormsAuthenticationUserCollection getUsers()
{
if (_users == null)
{
AuthenticationSection section = getAuthenticationSection();
FormsAuthenticationCredentials creds = section.Forms.Credentials;
_users = section.Forms.Credentials.Users;
}
return _users;
}
protected AuthenticationSection getAuthenticationSection()
{
Configuration config = WebConfigurationManager.OpenWebConfiguration("~");
return (AuthenticationSection)config.GetSection ("system.web/authentication");
}
protected FormsAuthPasswordFormat getPasswordFormat()
{
return getAuthenticationSection().Forms.Credentials.PasswordFormat;
}
}
Samples | Work in Progress
Wednesday, July 27, 2005 6:34:08 AM UTC
|
|

Tuesday, July 26, 2005
Partial Trust ASP.NET 2.0 and processRequestInApplicationTrust
UDPATED (here)
I spent the the better half of my last weeks getting a specific partial trust ASP.NET scenario to work:
Multiple Applications on one machine, like
/WebApp1 /WebApp2
WebApp1 should run in medium trust, WebApp2 in full trust.
But there should be only one global trust level setting in (global) web.config with allowOverride="false" (controlled by the machine admin).
So I added UrlMembershipConditions to my global_policy.config file, like this (notice that you have to specify the location of the ASP.NET compilation output directory, not the path to the web app - another thing to watch out):
<CodeGroup
class="UnionCodeGroup"
version="1"
PermissionSetName="FullTrust">
<IMembershipCondition
class="UrlMembershipCondition"
version="1"
Url="file:///C:/WINDOWS/.../Temporary ASP.NET Files/WebApp2/*"
/>
</CodeGroup>
...with no success (at least thats what i thought) -
Well, even if i gave full trust to file:///c:/* - the ASP.NET app still had the "ASP.Net" PermissionSet.
After extended spelunking (TM) - i found the following -
There is a at least underdocumented (= not documented) attribute for the trust section called processRequestInApplicationTrust. If this is set to true (and that's the default) - the Page class will do a PermitOnly on the "ASP.Net" PermissionSet (in ProcessRequest(HttpContext)). So even if my app has full trust via policy, I have to Assert all permissions that are not granted by this PermissionSet - I didn't try Assert since I assumed I should be running under full trust. That's why I thought my policy document is somehow wrong.
If you set this attribute to false, only the AppDomain policy is in effect (and not an additional intersection with this PermissionSet)
Well - as is said - this took me some time to figure that out...thought i share that, in case someone tries to do something similar -
Hope this behaviour gets properly documented in RTM.
(thanks to my fellow DM instructor marcus for 'pair reflectoring') Work in Progress
Tuesday, July 26, 2005 12:21:04 PM UTC
|
|

Sunday, July 24, 2005
Installing Performance Counters
here i talked about instrumenting your applications with Windows Performance Counters. A number of people asked me how to install such a counter during deployment.
The easiest way is to derive from a class called PerformanceCounterInstaller, set the appropriate properties and run it (from an admin priv account) with installutil.exe. The System.Diagnostics namespace also provides APIs to manually create and remove counters. Here is a sample how to install the two counters I used in my previous article.
using System;
using System.Diagnostics; using System.ComponentModel;
namespace PerfCounterInstaller
{
[RunInstaller(true)]
public class MyInstaller : PerformanceCounterInstaller
{
public MyInstaller()
{
this.CategoryName = "SuspiciousActivity";
CounterCreationData ccd1 = new CounterCreationData(
"ValidationErrorsTotal",
"Total Numbers of Validation Errors",
PerformanceCounterType.NumberOfItems32);
CounterCreationData ccd2 = new CounterCreationData(
"ValidationErrorsPerSecond",
"Validation Errors per Second",
PerformanceCounterType.RateOfCountsPerSecond32);
Counters.Add(ccd1);
Counters.Add(ccd2);
}
}
}
Samples
Sunday, July 24, 2005 8:24:19 AM UTC
|
|

Wednesday, July 13, 2005
Policy Assemblies Headaches
Have you also encountered this error message when you are trying to add an assembly to the policy assembly list in 'mscorcfg.msc' saying that your assembly is not strong named?? I mean - you can only add assemblies from the GAC - i wonder how my assemblies make it in the GAC without having a strong name??? So this is clearly a bug of the tool.
I observed this behaviour on 1.1 and 2.0 and it happens randomly.
What always works, is to add the assembly programmatically - so i wrote this little tool, which may be also helpful for installation packages, whatever. enjoy.
using System;
using System.Reflection;
using System.Collections;
using System.Security.Permissions;
using System.Security.Policy;
using System.Security;
namespace LeastPrivilege.Tools
{
class Program
{
static void Main(string[] args)
{
IEnumerator policyLevelEnumerator = SecurityManager.PolicyHierarchy();
while (policyLevelEnumerator.MoveNext())
{
PolicyLevel lvl = (PolicyLevel)policyLevelEnumerator.Current;
if ("Machine" == lvl.Label)
{
AssemblyName asm = AssemblyName.GetAssemblyName(args[0]);
StrongNamePublicKeyBlob snpkb = new StrongNamePublicKeyBlob(asm.GetPublicKey());
StrongName sn = new StrongName(snpkb, asm.Name, asm.Version);
lvl.AddFullTrustAssembly(sn);
SecurityManager.SavePolicyLevel(lvl);
foreach (StrongNameMembershipCondition snmc in lvl.FullTrustAssemblies)
Console.WriteLine(snmc.Name);
break;
}
}
}
}
}
Samples | Work in Progress
Wednesday, July 13, 2005 2:22:21 PM UTC
|
|

Saturday, July 02, 2005
MVPed
Today I received my MVP Award - Visual Developer Security.
Thank you Microsoft.
Work in Progress
Saturday, July 02, 2005 12:28:35 AM UTC
|
|

Saturday, June 25, 2005
My Monad Command Prompt
With some help from Lee, i was able to reproduce my favourite prompt for cmd.exe (which is $P$_$+$G - thanks to Craig for that) in Monad. Just add the following to your 'profile.msh':
function prompt { "MSH " + (get-location).Path + "`n> " }
(note the escape character) Work in Progress
Saturday, June 25, 2005 9:50:25 AM UTC
|
|

Thursday, June 23, 2005
Centrally configure ClickOnce Trust Manager
The TrustManager is a piece of code that gets called when a ClickOnce application gets started. You can find the default implementation in System.Security.Policy.TrustManager. The heart of the TrustManager is a method called DetermineApplicationTrust(). You hand in all needed information, e.g. the manifest data. Inside of the TrustManager all the UI interaction and permission elevation logic is implemented.
You can write your own TrustManager, but for most cases the built-in one is just fine, and you can modify the default behavior with some registry keys.
One interesting possibility is, that you can lock down TrustManager and specify in which zone he should allow permission elevation and if only trusted applications are allowed to elevate permissions. The registry settings are described here.
Since these are registry settings, it is quite simple to distribute TrustManager configuration settings centrally via an Active Directory GPO. I wrote a little administrative template file which you can import into a group policy (to see the template copy it to \windows\inf, add the template to administrative templates and uncheck the "only show fully managed policies" in the view->filter menu in GPEdit).
TrustManager.adm.zip (.45 KB)
Thursday, June 23, 2005 10:43:26 AM UTC
|
|

Wednesday, June 22, 2005
Automatic Distribution of Authenticode Certificates
In my previous post i talked about how to get a code signing cert for Authenticode or ClickOnce.
In a corporate environment every client has to trust this cert (e.g. if you want to suppress the trust question in ClickOnce for trusted apps).
In Active Directory you can use GPOs to distribute the certs.
Root CA Certificate Add a GPO to AD and link at the appropriate level. Computer Settings -> Windows Settings -> Security -> Public Key Policies. Add the root CA cert under "Trusted Root Certification Authorities"
Authenticode Certificate Add a GPO to AD and link at the appropriate level. User Settings-> Windows Settings -> Internet Explorer Maintenance -> Security -> Authenticode Settings. Click Import and then Modify. If you don't want your users to modify their trusted publisher cert store on their own, you should also click "Lock down Trusted Publishers" as well as disable the corresponding Control Panel applet.
Then, give AD some time to think about it, err, replicate...
Work in Progress
Wednesday, June 22, 2005 7:25:23 AM UTC
|
|

Tuesday, June 21, 2005
W2K3 CA and Code Signing Certificates
If you want to use the trusted deployment feature of ClickOnce (or just plain Authenticode), you need a certificate with an intended purpose of at least "code signing".
You have 3 options
- Generate a self signed certificate using makecert.exe (only for testing purposes)
- Get one from a public CA like VeriSign
- Configure your internal (Windows) CA to issue this type of certificate
For corporate scenarios option 3 seems to be most likely. Here is how you get it to work.
Windows 2003 Enterprise CAs have so called "Certificate Templates" installed (certtmpl.msc). These templates configure the settings of issuable certificates. There is already a pre-installed template for "Code Signing". This template has a validity period of 1 year. If you want to modify the template (only supported on W2K3 Enterprise Edition), call "Duplicate Template", give it a new name and change the settings of the template. Either way, you have to modify the security settings. Give the user(s) who should be allowed the request such a certificate the "Enroll" permission.
After that go to the console of your CA and navigate to the "Certificate Templates" folder. Click "New->Certificate Templates to Issue", and select your code signing template.
Now you can request this type of certificate from the CA web interface or the client side "Certificates" MMC snap-in.
For Authenticode (and ClickOnce) there are two prerequisites:
- You have to add the code signing certificate to the client's "Trusted Publishers" (machine) store
- This cert has to have a trusted root (if you are using an enterprise CA, this is done automatically by AD), otherwise you have to add the CA cert to the "Trusted Root Certificate Authorities" folder
After that, you can use the certificate to sign binaries using "signcode.exe" as well as signing application manifests in ClickOnce (more info here).
Work in Progress
Tuesday, June 21, 2005 6:45:18 AM UTC
|
|

Sunday, June 19, 2005
Monad Beta 1
Beta 1 of the Microsoft Shell (code-named Monad) is available for download at beta place. It is compatible to B2 of .NET 2.0. yummie.
Download Instructions (via Lee Holmes)
For Your Favourites | Misc
Sunday, June 19, 2005 6:47:44 AM UTC
|
|

Saturday, June 18, 2005
Lifetime of persistent FormsAuth Cookies
A student asked me about the expiration time of the .ASPXAUTH cookie if you call FormsAuthentication.RedirectFromLoginPage(name, true).
This is not really new info, but i double checked on .NET 2.0 B2 - and tracked down the following line of code in System.Web.Security.FormsAuthentication.GetAuthCookie():
FormsAuthenticationTicket ticket1 = new FormsAuthenticationTicket(2, userName, DateTime.Now, createPersistentCookie ? DateTime.Now.AddYears(50) : DateTime.Now.AddMinutes((double) FormsAuthentication._Timeout), createPersistentCookie, string.Empty, strCookiePath);
Work in Progress
Saturday, June 18, 2005 8:19:50 PM UTC
|
|
ShowContexts (.NET 2.0 Version)
In ASP.NET you have to deal with three identities (Process, Thread and Managed Identity). In DevelopMentor's "Essential .NET Security" course i use this little tool, originally written by Keith, to show these identities.
I updated the code to .NET 2.0. You can see how to "RevertToSelf" using managed code, as well as the new overload in WindowsIdentity.GetCurrent() to figure out if you are currently impersonating.
I included two formats - ASPX and ASMX. The ASMX is especially useful to diagnose double hop scenarios.
ShowContexts.zip (1.39 KB)
Samples | Work in Progress
Saturday, June 18, 2005 8:11:03 PM UTC
|
|

Saturday, June 11, 2005

Wednesday, June 08, 2005
ASP.NET 2.0 Health Monitoring is Goodness
The new Health Monitoring framwork in ASP.NET 2.0 is very cool. Besides that ASP.NET itself uses it to emit all kinds of useful status information, you can build your own WebException classes and connect them via configuration to the EventLog, WMI, Emails a.s.o.
I am particularly impressed with the information that ASP.NET puts in there by default (in addition to whatever custom info you pass on to the the Exception).
An example of an WebException in the EventLog (special attention to process and thread information and security contexts as well as trust level). nice
Event code: 3005 Event message: An unhandled exception has occurred. Event time: 08.05.2005 23:11:19 Event time (UTC): 08.05.2005 21:11:19 Event ID: ca4ed555706c471dbad976bc5a49dead Event sequence: 201 Event occurrence: 2 Event detail code: 0 Application information: Application domain: 9b5eb6a8-1-127600601395677296 Trust level: Full Application Virtual Path: /TestApp Application Path: C:\... Machine name: DBDEMO Process information: Process ID: 1848 Process name: WebDev.WebServer.EXE Account name: LEASTPRIVILEGE\dbaier Exception information: Exception type: Exception Exception message: Something terrible happened. Request information: Request URL: http://localhost/TestApp/Test.aspx Request path: /TestApp/Test.aspx User host address: 127.0.0.1 User: LEASTPRIVILEGE\dbaier Is authenticated: True Authentication Type: NTLM Thread account name: LEASTPRIVILEGE\dbaier Thread information: Thread ID: 4 Thread account name: LEASTPRIVILEGE\dbaier Is impersonating: True Stack trace: ...
Work in Progress
Wednesday, June 08, 2005 9:25:17 AM UTC
|
|

Monday, June 06, 2005
ASP.NET 2.0 Cache/Control Debugger Visualizer for VS2005
Two quite handy debugger visualizers for VS 2005 - built by brett johnson.
Especially the one for inspecting the ASP.NET cache is fun while spelunking.
Just build the dowloadable project and copy the assembly to:
- My Documents\Visual Studio\Visualizer (currrent user)
- <VS Install Dir>\Common7\Packages\Debugger\Visualizers (all users)
Plus : An article on how to build your own visualizers with beta 2.
have fun debugging :) For Your Favourites
Monday, June 06, 2005 8:06:12 AM UTC
|
|

Saturday, June 04, 2005
Supported Hashing Algorithms for PasswordDeriveBytes
this was a question on the MSDN Newsgroups.
By looking at the source with reflector - they create a HashTable with all available algorithm mappings (look at System.Security.Cryptography.CryptoConfig. CreateDefaultMappingHT).
The HT includes hashing and encryption algorithms.
Out of experimentation i found out that you can use the following strings for the PasswordDeriveBytes ctor:
- MD5
- SHA1
- SHA256
- SHA384
- SHA512
- HMACSHA1
Work in Progress
Saturday, June 04, 2005 10:26:24 AM UTC
|
|

Thursday, June 02, 2005
Gudge tries to make Indigo Secure
So - it is not that easy to make the basic profile binding work over SSL in Indigo (even for a guy who is close to the product team).
That's why i suggested to make SSL the default. here. :))
Misc
Thursday, June 02, 2005 2:58:22 PM UTC
|
|

Tuesday, May 31, 2005

Wednesday, May 18, 2005
Full Trust in Whidbey
Every time I do the CAS modules in DevelopMentor's security course, we talk about all those different kinds of Permissions and students are quite impressed about the different ways to protected their code (especially with IdentityPermissions). A few slide later comes the obligatory: "but, this only applies if you are running in partial trust"...there is really no way to protect your code from fully trusted callers, it even can result in strange problems if you are using Identity Permissions in Full Trust environments.
CAS in Whidbey has changed to reflect this:
- Identity Permissions in any state become subset of Unrestricted PermissionSet
- Set logics for IdentityPermissions changes
- LinkDemands are optimized out in FullTrust
read the full story here.
Security in Whidbey
Wednesday, May 18, 2005 7:27:07 AM UTC
|
|

Saturday, May 14, 2005
BASTA 2005
I will do 2 talks and a whole-day workshop on the next BASTA in September.
- Developing secure distributed Applications (workshop)
- ASP.NET 2.0 Provider/Security Architecture
- New Security Features in .NET 2.0
More info.
Saturday, May 14, 2005 6:52:21 PM UTC
|
|

Thursday, May 12, 2005
ASP.NET Development Helper
Nikhil has a very cool IE Helper/HttpModule combination for download on his blog, which does
- Warn you when debugging or tracing is enabled
- Extracts trace information from a page and shows it in a separate window
- Shows decoded ViewState/ControlState
and all from within IE...very cool!
UPDATE new version can be downloaded here. The ASP.NET cache can now be viewed and purged + you can recycle the application for testing purposes.
For Your Favourites
Thursday, May 12, 2005 5:03:39 AM UTC
|
|

Tuesday, May 10, 2005
EventLog ACLs in Windows 2003
It seems to be a common problem (telling from the msdn newsgroups) that some user/service accounts can't write to the EventLog under Windows 2003.
That's what i answered (thought I post it here so i don't have to repeat myself over and over again :)
Under Windows 2003 the EventLogs are ACLed - they can be found in the registry, e.g.
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\Eventlog\Application\CustomSD
the default ACL for the Application Log is:
O:BAG:SYD:(D;;0xf0007;;;AN)(D;;0xf0007;;;BG)(A;;0xf0007;;;SY)(A;;0x7;;;BA) (A;;0x7;;;SO)(A;;0x3;;;IU)(A;;0x3;;;SU)(A;;0x3;;;S-1-5-3)
Nice, eh??
This is SDDL (Security Descriptor Description Language) and means:
O:BA Object owner is Built-in Admin (BA). G:SY Primary group is System (SY). D: This is a DACL, rather than an audit entry or SACL. (D;;0xf0007;;;AN) Deny Anonymous (AN) all access. (D;;0xf0007;;;BG) Deny Built-in Guests (BG) all access. (A;;0xf0005;;;SY) Allow System Read and Clear, including DELETE, READ_CONTROL, WRITE_DAC, and WRITE_OWNER (indicated by the 0xf0000). (A;;0x7;;;BA) Allow Built-in Admin READ, WRITE and CLEAR. (A;;0x7;;;SO) Allow Server Operators READ, WRITE and CLEAR. (A;;0x3;;;IU) Allow Interactive Users READ and WRITE. (A;;0x3;;;SU) Allow Service accounts READ and WRITE. (A;;0x3;;;S-1-5-3) Allow Batch accounts (S-1-5-3) READ and WRITE.
If you want to extend that ACL - you have to add the SID of the account and an access mask, which is as follows:
0x0001 ELF_LOGFILE_READ Permission to read log files. 0x0002 ELF_LOGFILE_WRITE Permission to write log files. 0x0004 ELF_LOGFILE_CLEAR Permission to clear log files.
More Info on SDDL and an article by Michael Howard about security changes in w2k3 can be found here and here.
Work in Progress
Tuesday, May 10, 2005 6:15:08 PM UTC
|
|

Monday, May 09, 2005

Sunday, May 08, 2005
Back from the Indigo SDR
Last week I attended the Indigo SDR in Munich. First of all it was fun to hang out with my fellow DM buddies Marcus and Marvin, and of course Aaron, who was our instructor for the 3 days.
I will not be too over-enthusiastic, but what i've seen so far is a nice programming model, which seems to make sense (after thinking about it) and will hopefully reduce a lot of the complexities that many devs face today (e.g. choosing which technology over the other or painfully try to combine several technology stacks).
A lot of effort has been put into the bridging of the XML/Objects impedance mismatch, and time will tell if we can build XML messaging based systems in the future without touching (or maybe even knowing) angle brackets.
Here comes the obligatory security part :)
- Seems that all binding (besides WSI-BP) have security enabled by default - which is good
- I suggested to force even WSI-BP to work only over SSL by default (and that we have to manually disable that). The other attendees didn't like the idea :)
- I really like that there is now an easy mechanism for services to provide a certificate with which a client can encrypt UsernameTokens (config setting, no coding)
- Indigo config files will get tremendously complex, and complexity is the natural enemy of security. We really need good tools that check config files for plausability. In addition i want something like the WSE Policy Advisor and big red lights if something with the security config is wrong. As a side note - i just assume the Indigo configs are compatible with the .NET 2.0 ProtectedConfiguration providers (but haven't tried, yet).
- What's really annoying is, that there is no built-in validation of the incoming messages against schema. While this is a general problem, everybody knows that input validation is maybe the most crucial part in today's application security. Please, Microsoft, include a validator - this does not have to be the standard behaviour - but it would be so nice to just flip a switch and have validation (and support for XSD Patterns and other restrictions).
- I was happy to see that the authorization demos were centered around AzMan.
- System.Security.Authorization seems to be an interesting new namespace. Pierre wrote about it already.
Will Indigo put instructors and consultants out of business (quoting dbox) ? Surely not. I expect a lot of people to use the straightforward programming interface right out of the box - but problems will arise later in the project (meet LOLA) - we will see if we can solve these problems then by reconfiguring and rebinding, without changing the code in the function.
The three days were a really nice overview, and i will definitely dive into the security APIs as soon as they look a little more stabilized. Good work!
Work in Progress
Sunday, May 08, 2005 6:41:08 PM UTC
|
|

Saturday, May 07, 2005
Windows Server 2003 R2 Trial
A trial version of W2K3 R2 is for download here.
Stuff i'd like to play around with
- Active Directory Federation Services
- New Authorization Manager features (SAML Tokens, ADAM Principles)
- Common Logging File System
if i'd had more time, time, time....
For Your Favourites
Saturday, May 07, 2005 7:50:58 AM UTC
|
|

Friday, May 06, 2005
Slowing down automated Attacks
I came across this new whitepaper from NGS (David Litchfield's company). It is about how automated scanners/attack tools work and how you could modify your web applications to make these kind of tools less successful. interesting read.
For Your Favourites
Friday, May 06, 2005 12:31:26 PM UTC
|
|

Tuesday, May 03, 2005
Another way of integrating AzMan
I am currently playing around with a custom IPrincipal implementation that uses AzMan as a backing store. There are other implementations around, but what strikes me odd is, that most of them only use the role storage features - which is IMO only 40% of the functionality provided.
A really powerful feature of AzMan is to map roles to operations in your application, e.g. you could have a operation "DeleteCustomer" and do an access check11 if the current user is allowed to delete that customer (of course this boils down to checking if the user is in a specific role that is allowed to execute that operation), but that is another layer of abstraction, and you don't have to hard-code role names in your code.
So i came up with the following usage pattern:
You replace your current principal with my AzManPrincipal - base it on some identity (more on that later) and point to your AzMan store and application name:
Thread.CurrentPrincipal = new AzManPrincipal(WindowsIdentity.GetCurrent(), @"msxml://c:\etc\source\1.1\AzManPrincipal\TestStore.xml", "TestApplication");
after that you can of course call IsInRole on that principal
[Test] public void IsBoss() { bool member = Thread.CurrentPrincipal.IsInRole("Boss"); Assert.AreEqual(true, member); }
but you can also ask if the current user is allowed to execute an operation, like (and this uses the AzManOpConst tool i posted earlier):
[Test] public void TestOperation1() { bool allowed = ((AzManPrincipal) Thread.CurrentPrincipal).HasAccess(Operations.GiveRaise); Assert.AreEqual(true, allowed); }
but the thing i find most compelling is to tie your code to an AzMan operation by using attributes, like this:
[Test] [Operation(Operations.GiveRaise)] public void TestOperation1Attribute() { bool allowed = ((AzManPrincipal) Thread.CurrentPrincipal).HasAccess(); Assert.AreEqual(true, allowed); }
HasAccess() returns a boolean, another option is to use CheckAccess() which will throw a SecurityException if necessary, like this
[Test] [ExpectedException(typeof(SecurityException))] [Operation(Operations.EnterCafeteria)] public void CheckOperation2Attribute() { ((AzManPrincipal) Thread.CurrentPrincipal).CheckAccess(); }
When we set up the Principal I used the current WindowsIdentity. I also implemented support for FormsIdentity (this will pickup the .Name property in the format Domain\Username to initialize the context) as well as a AzManCustomSidIdentity (to use with Custom SIDs).
So - what is missing?
- I like to have a AzManPrincipalPermission to use declaratively as well as imperatively
- A lot of testing
This stuff is not finished yet - but i wanted to share the programming model with you - do you like that, does that make sense?? Any comments??
Feedback is welcome.
Work in Progress
Tuesday, May 03, 2005 7:41:35 PM UTC
|
|

Thursday, April 28, 2005

Wednesday, April 27, 2005
New Blogs on the Block
Fellow geek-heads and DevelopMentor instructors Marvin Smit (XML, WebServices, BizTalk) and Marcus Heege (.NET, C++/CLI) have a blog now...
Nothing really useful (besides the usual hello world) up yet, but i expect big things to happen there :) subscribed.
For Your Favourites
Wednesday, April 27, 2005 9:32:56 AM UTC
|
|

Tuesday, April 26, 2005
ASP.NET Security Roadshow, 1st stop Munich
Today was the first stop of the CompuWare roadshow in Munich. I liked it - the attendees had lots of interesting questions and constructive criticism.
Something people really seem to care about is how to integrate security checking into an automated build process - that's good!
However - I am always puzzled how few people have ever thought about threat modelling.
4 cities to go.
Work in Progress
Tuesday, April 26, 2005 6:03:41 PM UTC
|
|

Saturday, April 23, 2005

Saturday, April 16, 2005
test test
Saturday, April 16, 2005 9:28:42 AM UTC
|
|

Wednesday, April 13, 2005
Back to normal Operation
I moved servers...unfortunately the transition wasn't as smooth as planned which meant i was offline for 2 days. sorry for that. back to business.
Misc
Wednesday, April 13, 2005 4:36:00 PM UTC
|
|

Monday, April 04, 2005
AzMan Operations Helper Tool
I am currently working on some AzMan related tools/sample code (e.g. an IPrincipal implementation with some cool extra goodies) - as a side effect i wrote a little tool which parses an AzMan store and creates a class with consts that map to your AzMan operations, like:
public class Operations { public const int opGiveRaise = 1; public const int opLeaveEarly = 2; public const int opEnterCafeteria = 3; public const int opRant = 4; }
just point the tool to the store and the application.
AzManCreateOpConsts msxml://c:\store.xml TestApplication
There is more stuff coming up...
AzManCreateOpConsts.zip (27.88 KB)
Work in Progress
Monday, April 04, 2005 10:22:41 PM UTC
|
|

Friday, April 01, 2005
Save classic IDL!
you thought the end of VB6 is scary?? now take this - microsoft wants to deprecate IDL...
sign this petition if you want to save IDL (we already have 7 MVPs!!!)
Misc
Friday, April 01, 2005 1:42:59 PM UTC
|
|

Friday, March 25, 2005
CompuWare Security Checker/Fault Simulator Roadshow
From april to june I will do a roadshow together with Compuware's Kurt Aigner focusing on application security/quality assurance in the development cycle.
We will kick off with a more general talk about secure development best-practices and threat modelling and after that you get the opportunity to gain hands-on experience with Compuware's new security products ASP.NET Security Checker and Fault Simulator. We will close the day with an extended QA session about .NET application security (i have a laptop loaded with ASP.NET with me, so we can do pretty much everything there).
be there. attendance is free. here's the link for registering for the event.
Dates:
- 26.04.2005 (Munich)
- 18.05.2005 (Baden Dätwill/Switzerland)
- 19.05.2005 (Hamburg)
- 20.05.2005 (Dreieich, Frankfurt)
- 07.06.2005 Düsseldorf
see you there.
Conferences | Work in Progress
Friday, March 25, 2005 7:33:15 AM UTC
|
|