Token Request Validation in ASP.NET

Earlier this week during my TechDays presentation on Windows Identity Foundation, there was a part during the demo that I said would fail miserably after the user was authenticated and the token was POST’ed back to the relying party.  Out of the box, ASP.NET does request validation.  If a user has submitted content through request parameters it goes through a validation step, and by default this step is to break on anything funky such as angle brackets.  This helps to deter things like cross site scripting attacks.  However, we were passing XML so we needed to turn off this validation.  There are two approaches to doing this.

The first approach, which is what I did in the demo, was to set the validation mode to “2.0”.  All this did was tell ASP.NET to use a less strict validation scheme.  To do that you need to add a line to the web.config file:

<system.web>
<httpRuntime requestValidationMode=”2.0” />
</system.web>

This is not the best way to do things though.  It creates a new vector for attack, as you’ve just allowed an endpoint to accept trivial data.  What is more preferred is to create a custom request validator.  You can find a great example in the Fabrikam Shipping demo.

It’s pretty straightforward to create a validator.  First you create a class that inherits System.Web.Util.RequestValidator, and then you override the method IsValidRequestString(…).  At that point you can do anything you want to validate, but the demo code tries to build a SignInResponseMessage object from the wresult parameter.  If it creates the object successfully the request is valid.  Otherwise it passes the request to the base implementation of IsValidRequestString(…).

The code to handle this validation is pretty straightforward:

    public class WSFederationRequestValidator : RequestValidator
    {
        protected override bool IsValidRequestString(HttpContext context,
            string value, RequestValidationSource requestValidationSource, 
            string collectionKey, out int validationFailureIndex)
        {
            validationFailureIndex = 0;

            if (requestValidationSource == RequestValidationSource.Form
                && collectionKey.Equals(WSFederationConstants.Parameters.Result, 
                   StringComparison.Ordinal))
            {
                SignInResponseMessage message =
                     WSFederationMessage.CreateFromFormPost(context.Request) 
                     as SignInResponseMessage;

                if (message != null)
                {
                    return true;
                }
            }

            return base.IsValidRequestString(context, value, requestValidationSource,
                   collectionKey, out validationFailureIndex);
        }
    }

Once you’ve created your request validator, you need to update the web.config file to tell .NET to use the validator.  You can do that by adding the following xml:

<system.web>
<httpRuntime requestValidationType="Microsoft.Samples.DPE.FabrikamShipping.Web.Security.WSFederationRequestValidator" />
</system.web>

You can find the validation code in FabrikamShipping.Web\Security\WSFederationRequestValidator.cs within the FabrikamShipping solution.

Free Code Sample Request Service from Microsoft

Just came across this on the Decrypt my World blog.  It seems a lot of Microsoft developers are asked for code samples and for lots of valid reasons they can’t provide them.  So Microsoft is fixing that by opening up a service where you can request code samples for any Microsoft technologies.

Here is the official word on what it is:

Developers are encouraged to submit code sample requests dealing with any Microsoft development technologies to our site. At the same time, developers can now vote for newly submitted or existing code sample topics. Here’s the exciting part! Microsoft engineers will then pick the requests with the highest number of votes and provide the code samples. It’s all FREE!

You can find the full write-up here: http://1code.codeplex.com/wikipage?title=NEW%2c%20FREE%20Code%20Sample%20Request%20Service%20from%20Microsoft%20All-In-One%20Code%20Framework

Kerberos: Very Claims-y

I’ve always found Kerberos to be an interesting protocol.  It works by way of a trusted third party which issues secured tickets based on an authentication or previous session.   These tickets are used as proof of identity by asserting that the subject is who they claim to be. Claims authentication works on a similar principle, except instead of a ticket you have a token.  There are some major differences in implementation, but the theory is the same.  One of the reasons I find it interesting is that Kerberos was originally developed in 1983, and the underlying protocol called the Needham-Schroeder protocol, was originally published in 1978.

There have been major updates over the years, as well as a change to fix a man-in-the-middle attack in the Needham-Schroeder protocol in 1995, but the theory is still sound.  Kerberos is the main protocol used in Windows networks to authenticate against Active Directory.

The reason I bring it up is because of a comment I made in a previous post.  I made an assertion that we don’t necessarily abstract out the identity portion of our applications and services. 

Well, It occurred to me that up until a certain period of time, we did.  In many environments there was only one trusted authority for identity.  Whether it was at a school, in a business, or within the government there was no concept of federation.  The walls we created were for a very good reason.  The applications and websites we created were siloed and the information didn’t need to be shared.  As such, we created our own identity stores in databases and LDAP directories.

This isn’t necessarily a problem because we built these applications on top of a foundation that wasn’t designed for identity.  The internet was for all intents and purposes designed for anonymity.  But here is where the foundation became tricky: it boomed.

People wanted to share information between websites and applications, but the data couldn’t be correlated back to the user across applications.  We are starting to catch up, but it’s a slow process.

So here is the question: we started with a relatively abstract process of authentication by way of the Kerberos third party, and then moved to siloed identity data.  Why did we lose the abstraction?  Or more precisely, during this boom, why did we allow our applications to lose this abstraction?

Food for thought on this early Monday.

Spam: Don’t forget the Alt-Text

Constructive

Whitepaper on ADFS 2 Federation with Shibboleth and the InCommon Federation

Over on the Claims-Based Identity blog, they announced a whitepaper was just released on using ADFS 2 to federate with Shibboleth 2 and the InCommon Federation.  I just started reading through it, but it looks really well written.

Here is the abstract of the paper itself:

Through its support for the WS-Federation and Security Assertion Markup Language (SAML) 2.0 protocols, Microsoft® Active Directory® Federation Services 2.0 (AD FS 2.0) provides claims-based, cross-domain, Web single sign-on (SSO) interoperability with non-Microsoft federation solutions. Shibboleth® 2, through its support for SAML 2.0, enables cross-domain, federated SSO between environments that are running Microsoft and Shibboleth 2 federation infrastructures.

You can download the whitepaper in .docx format.

What is Shibboleth?

The Shibboleth System is a standards based, open source software package for web single sign-on across or within organizational boundaries. It allows sites to make informed authorization decisions for individual access of protected online resources in a privacy-preserving manner.

What is InCommon?

InCommon eliminates the need for researchers, students, and educators to maintain multiple passwords and usernames. Online service providers no longer need to maintain user accounts. Identity providers manage the levels of their users' privacy and information exchange. InCommon uses SAML-based authentication and authorization systems (such as Shibboleth®) to enable scalable, trusted collaborations among its community of participants.

TechDays 2010 Presentation Resources

This page contains a bunch of useful links to resources described in my presentations at TechDays this year.

Windows Identity Foundation

Visual Studio 2010 Tips and Tricks

Minor Change to TechDays Presentation

Just a quick update to let everyone know that Miguel Carrasco and I are switching sessions so he can get back home for a prior engagement.  As such, I will now be doing OPT315: Microsoft Visual Studio 2010 Tips and Tricks. This session is on the 2nd day at 3:40pm - 4:45pm.

What makes Claims Based Authentication Secure?

Update: I should have mentioned this when I first posted, but some of these thoughts are the result of me reading Programming Windows Identity Foundation.  While I hope I haven’t copied the ideas outright, I believe the interpretation is unique-ish. Smile

One of the main reasons we as developers shy away from new technologies is because we are afraid of it.  As we learned in elementary school, the reason we are afraid usually boils down to not having enough information about the topic.  I’ve found this especially true with anything security related.  So, lets think about something for a minute.

I’m not entirely sure how valid a method this is for measure, but I like to think that as developers we measure our understanding of something by how much we abstract away the problems it creates.  Now let me ask you this question:

How much of an abstraction layer do we create for identity?

Arguably very little because in most cases we half-ass it.

I say this knowing full well I’m extremely guilty of it.  Sure, I’d create a User class and populate with application specific data, but to populate the object I would call Active Directory or SQL directly.  That created a tightly coupled dependency between the application and the user store.  That works perfectly up until you need to migrate those users in a SQL database to Active Directory.  Oops.

So why do we do this?

My reason for doing this is pretty simple.  I didn’t know any better.  The reason I didn’t know better was also pretty simple.  Of the available options to abstract away the identity I didn’t understand how the technology worked, or more likely, I didn’t trust it.  Claims based authentication is a perfect example of this.  I thought to myself when I first came across this: “are you nuts?  You want me to hand over authentication to someone else and then I have to trust them that what they give me is valid?  I don’t think so.”

Well, yes actually.

Authentication, identification, and authorization are simply processes in the grand scheme of an application lifecycle.  They are privileged, but that just means we need to be careful about it.  Fear, as it turns out, is the number one reason why we don’t abstract this part out.*

With that, I thought it would be a perfect opportunity to take a look at a few of the reasons why Claims based authentication is reasonably secure.  I would also like to take this time to compare some of these reasons to why our current methods of user authentication are usually done wrong.

Source

First and foremost we trust the source.  Obviously a bank isn’t going to accept a handwritten piece of paper with my name on it as proof that I am me.  It stands to reason that you aren’t going to accept an identity from some random 3rd party provider for important proof of identity.

Encryption + SSL

The connection between RP and STS is over SSL.  Therefore no man in the middle attacks.  Then you encrypt the token.  Much like the SSL connection, the STS encrypts the payload with the RP’s public key, which only the RP can decrypt with its private key.  If you don’t use SSL anyone eavesdropping on the connection still can’t read the payload.  Also, the STS usually keeps a local copy of the certificate for token encryption.

How many of us encrypt our SQL connections when verifying  the user’s password?  How many of us use secured LDAP queries to Active Directory?  How many of us encrypt our web services?  I usually forget to.

Audience whitelist

Most commercial STS applications require that each request come from an approved Relying Party.  Moreover, most of those applications require that the endpoint that it responds to also be on an approved list.  You could probably fake it through DNS poisoning, but the certificates used for encryption and SSL would prevent you from doing anything meaningful since you couldn’t decrypt the token.

Do we verify the identity of the application requesting information from the SQL database?  Not usually the application.  However, we could do it via Kerberos impersonation.  E.g. lock down the specific data to the currently logged in/impersonated user.

Expiration and Duplication Prevention

All tokens have authentication timestamps.  They also normally have expiration timestamps.  Therefore they have a window of time that defines how long they are valid.  It is up to the application accepting the token to make sure the window is still acceptable, but it is still an opportunity for verification.  This also gives us the opportunity to prevent replay attacks.  All we have to do is keep track of all incoming tokens within the valid time window and see if the tokens repeat.  If so, we reject them.

There isn’t much we can do in a traditional setting to prevent this from happening.  If someone eavesdrops on the connection and grabs the username/password between the browser and your application, game over.  They don’t need to spoof anything.  They have the credentials.  SSL can fix this problem pretty easily though.

Integrity

Once the token has been created by the STS, it will be signed by the STS’s private key.  If the token is modified in any way the signature wont match.  Since it is being signed by the private key of the STS, only the STS can resign it, however anyone can verify the signature through the STS’s public key.  And since it’s a certificate for the STS, we can use it as strong proof that the STS is who they say they are.  For a good primer on public key/private key stuff check out Wikipedia.

It's pretty tricky to modify payloads between SQL and an application, but it is certainly possible.  Since we don’t usually encrypt the connections (I am guilty of this daily – It’s something I need to work on Winking smile), intercepting packets and modifying them on the fly is possible.  There isn’t really a way to verify if the payload has been tampered with.

Sure, there is a level of trust between the data source and the application if they are both within the same datacenter, but what if it’s being hosted offsite by a 3rd party?  There is always going to be a situation where integrity can become an issue.  The question at that point then is: how much do you trust the source, as well as the connection to the source?

Authentication Level

Finally, if we are willing to accept that each item above increases the security and validity of the identity, there is really only one thing left to make sure is acceptable.  How was the user authenticated?  Username/password, Kerberos, smart card/certificates, etc.  If we aren’t happy with how they were authenticated, we don’t accept the token.

So now that we have a pretty strong basis for what makes the tokens containing claims as well as the relationship between the RP’s and STS’s secure, we don’t really need to fear the Claims model.

Now we just need to figure out how to replace our old code with the identity abstraction. Smile

* Strictly anecdotal evidence, mind you.

Managing Identity in SharePoint

Yet another presentation on the docket!  I submitted an abstract to SharePoint Summit 2011 and they accepted!  I will be presenting on SharePoint and how it manages Identity.  More specifically, how SharePoint 2010 uses WIF to handle Claims based authentication and Federation.

Here are the details

Event: SharePoint Summit 2011, January 31st 2011 – February 2nd, 2011

When: 11:30 a.m. - 12:45 p.m. February 1st, 2011

Where: Four Seasons Hotel, Toronto

Abstract: Managing identities within an organization is relatively easy. However, as business changes, we need to be able to adapt quickly. Identity is something that often gets overlooked in adaptation. In this session we will discuss the Windows Identity Foundation and how SharePoint uses it to adapt easily to change.

Link: http://www.sharepointsummit2011.com/Toronto/conference_day2.htm#session_7_3

Changing the Identity Game with the Windows Identity Foundation

Similar to the TVBUG presentation, I will be presenting on the Windows Identity Foundation to the Metro Toronto .NET User Group.

Here are the details:

When: November 10th, 2010

Where: KPMG, 333 Bay Street, 10th Floor, Toronto

Abstract: Identity is a tricky thing to manage. These days every application requires some knowledge of the user, which inevitably requires users to log in and out of the applications to prove they are who they are as well as requiring the application to keep record of the accounts. With the Windows Identity Foundation, built on top of a Claims-based architecture, there is a fundamental shift in the way we manage these users and their accounts. In this presentation we will take a look at the why's and dig into the how's of the Windows Identity Foundation by building an Identity aware application from scratch.