Home / My Disclaimer / Who am I? / Search... / Sign in

// Security

What Makes a Device a Business Device?

by Steve Syfuhs / March 26, 2013 05:40 PM

Last night I had the opportunity to meet up with some local west coast MVPs and as all good meet ups go some great conversations ensued. We talked about lots of things but towards the end of the night we got on the topic of personal devices and business devices.

The question was posed: is an iPhone/Windows Phone/iPad/Surface/etc a business device?

There was a resounding “no!” from a few people. Of course it [a given device] isn’t a business device… it was made for consumers.

It’s a valid argument based on the logic that there is a distinction between business-level and consumer-level devices. Business devices tend to have features that align with business requirements and consumer devices have features that align with consumer requirements. They tend to be branded as one or the other. Sure. Yep. Absolutely. Bang on.

Except people use their consumer devices at work, or they use their consumer devices at home to access resources at work.

Any time you use a device of any type to access business resources it is now a business device. Period.

This has security implications. The minute you use your own personal device to access business resources, for better or for worse, it is now under the purview of your organization’s security. It has to be. Security is there to protect the organization. If you access business resources from your device Security must be in place to protect the phone to protect the resources to protect the business. This makes it a business device.

I’m not saying it’s a good idea to use consumer-branded devices for business or a bad idea. I’m simply saying that if you use a device for work-related things, regardless of it’s intended usage, it is now a business device.

Real-time User Notification and Session Management with SignalR - Part 2

by Steve Syfuhs / March 24, 2013 02:31 PM

In Part 1 I introduced a basic usage of SignalR and talked about the goals we were trying to accomplish with the library.

In the next few posts I’m going to show how we can build a real-time user notification and session management system for a web application.

In this post I’ll show how we can implement a solution that accomplishes our goals.

Before diving back into SignalR it’s important to have a quick rundown of concepts for session management. If we think about how sessions work for a user in most applications it’s usually conceptually simple. A session is a mechanism to track user rights between the user logging in and logging out.  A session is usually tracked through a cookie attached to each request made to the server. A user has a session (or multiple sessions if they are logged in from another machine/browser) and each session is tied to a request or connection. Each time the user requests a page a new connection is opened to the server. As long as the session is active each connection is authorized to do whatever it needs to do (as defined by whatever authorization policies are in place).

image

When you kill a session each subsequent connection for that session is denied. The session is dead, no more access. Simple. A session is usually killed when a user explicitly logs out and destroys the session cookie or the browser is closed. This doesn’t normally kill any other sessions tied to the user though. The connections made from another browser are still authorized.

From a security perspective we may want to notify the user that another session is already active or was just created. We can then allow the user to destroy the other session if they want.

SignalR works really well in this scenario because it solves a nasty problem of timing. Normally when the server wants to tell the client something it has to wait for the client to make a request to the server and then the client has to act on the server’s message. A request to the server is usually only done when a user explicitly clicks something, or there’s a timer polling every 30 seconds or so. If we want to notify the user instantly of another session we can’t necessarily wait for the client to call. SignalR solves this problem because it can call the client directly from the server.

Now, allowing a user to control other sessions requires tracking sessions and connections. If we follow the diagram above we have a pretty simple relationship between users and sessions, and between sessions and connections. We could store this information in a database or other persistent storage, and in fact would want to for non-trivial applications, but for the sake of this post we’ll just store the data in memory.

Most session handlers these days (e.g. the SessionAuthenticationModule in WIF) create a cookie that contains everything the web application should know about the user. As long as that identity in the cookie is valid the user can do whatever the session handler allows. This is a mostly stateless process and aligns with various tenants of REST. Each request to the server contains the identity of the user, and the server doesn’t have to track anything. It’s simple and powerful.

However, in non-trivial applications this doesn’t always cut it. Security sometimes requires state. In this case we require state in the sense that the server needs to track all active sessions tied to a user. For this we’ll use the WIF SessionAuthenticationModule (SAM) and a custom SessionSecurityTokenHandler.

Before we can validate a session though, we need to track when a session is created. If the application is configured for federation you can create a custom ClaimsAuthenticationManager and call the session creation code, or if you are creating a session token manually you can call this code on login.

void CreateSession()
{
    string sess = CreateSessionKey();

    var principal = new ClaimsPrincipal(new[] { new ClaimsIdentity(new[] { new Claim(ClaimTypes.Name, "myusername"), new Claim(ClaimTypes.Sid, sess) }, AuthenticationTypes.Password) });

    var token = FederatedAuthentication.SessionAuthenticationModule.CreateSessionSecurityToken(principal, "mycontext", DateTime.UtcNow, DateTime.UtcNow.AddDays(1), false);

    FederatedAuthentication.SessionAuthenticationModule.WriteSessionTokenToCookie(token);

    NotificationHub.RegisterSession(sess, principal.Identity.Name);
}

private string CreateSessionKey()
{
    var rng = System.Security.Cryptography.RNGCryptoServiceProvider.Create();

    var bytes = new byte[32];

    rng.GetNonZeroBytes(bytes);

    return Convert.ToBase64String(bytes);
}

We’ll get back to the NotificationHub.RegisterSession method in a bit.

After the session is created, on subsequent requests the SessionSecurityTokenHandler validates whether a user’s session is still valid and authorized. The SAM calls the token handler when it receives a session cookie and generates an identity for the current request.

From here we can determine whether the user’s session was forced to logout. If we override the ValidateSession method we can check against the NotificationHub. Keep in mind this is an example – it’s not a good design decision to track session data in your notification hub. I’m also using ClaimTypes.Sid, which isn’t the best claim type to use either.

protected override void ValidateSession(SessionSecurityToken securityToken)
{
    base.ValidateSession(securityToken);

    var ident = securityToken.ClaimsPrincipal.Identity as IClaimsIdentity;

    if (ident == null)
        throw new SecurityTokenException();

    var sessionClaim = ident.Claims.Where(c => c.ClaimType == ClaimTypes.Sid).FirstOrDefault();

    if(sessionClaim == null)
        throw new SecurityTokenExpiredException();

    if (!NotificationHub.IsSessionValid(sessionClaim.Value))
    {
        throw new SecurityTokenExpiredException();
    }
}

Every time a client makes a request to the server the user’s session is validated against the internal list of valid sessions. If the session is unknown or invalid an exception is thrown which kills the request.

To configure the use of this SecurityTokenHandler you can add it to the web.config in the microsoft.identityModel/service section. Yes, this is still WIF 3.5/.NET 4.0.  There is no requirement for .NET 4.5 here.

<securityTokenHandlers>
    <remove type="Microsoft.IdentityModel.Tokens.SessionSecurityTokenHandler, Microsoft.IdentityModel" />
    <add type="Syfuhs.Demo.CustomSessionSecurityTokenHandler, MyDemo" />
</securityTokenHandlers>

Now that we can track sessions on the server side we need to track connections. To start tracking connections we need to start at our Hub. If we go back to our NotificationHub we can override a few methods, specifically OnConnected and OnDisconnected. Every time a page has loaded the SignalR hubs client library, OnConnected is called and every time the page is unloaded OnDisconnected is called. Between these two methods we can tie all active connections to a session. Before we do that though we need to make sure that all requests to our Hub are only from logged in users.

To ensure only active sessions talk to our hub we need to decorate our hub with the [Authorize] attribute.

[Authorize(RequireOutgoing = true)]
public class NotificationHub : Hub
{
    // snip
}

Then we override the OnConnected method. Within this method we can access what’s called the ConnectionId, and associate it to our session. The ConnectionId is unique for each page loaded and connected to the server.

For this demo we’ll store the tracking information in a couple dictionaries.

private static readonly Dictionary<string, string> UserSessions = new Dictionary<string, string>();

private static readonly Dictionary<string, List<string>> sessionConnections = new Dictionary<string, List<string>>();

public override Task OnConnected()
{
    var user = Context.User.Identity as IClaimsIdentity;

    if (user == null)
        throw new SecurityException();

    var sessionClaim = user.Claims.Where(c => c.ClaimType == ClaimTypes.Sid).FirstOrDefault();

    if (sessionClaim == null)
        throw new SecurityException();

    sessionConnections[sessionClaim.Value].Add(Context.ConnectionId);

    return base.OnConnected();
}

On disconnect we want to remove the connection associated with the session.

public override Task OnDisconnected()
{
    var user = Context.User.Identity as IClaimsIdentity;

    if (user == null)
        throw new SecurityException();

    var sessionClaim = user.Claims.Where(c => c.ClaimType == ClaimTypes.Sid).FirstOrDefault();

    if (sessionClaim == null)
        throw new SecurityException();

    sessionConnections[sessionClaim.Value].Remove(Context.ConnectionId);

    return base.OnDisconnected();
}

Now at this point we can map all active connections to their various sessions. When we create a new session from a user logging in we want to notify all active connections that the new session was created. This notification will allow us to kill the new session if necessary. Here’s where we implement that NotificationHub.RegisterSession method.

internal static void RegisterSession(string sessionId, string user)
{
    UserSessions[sessionId] = user;
    sessionConnections[sessionId] = new List<string>();

    var message = "You logged in to another session";

    var context = GlobalHost.ConnectionManager.GetHubContext<NotificationHub>();

    var userCurrentSessions = UserSessions.Where(u => u.Value == user);

    foreach (var s in userCurrentSessions)
    {
        var connectionsTiedToSession = sessionConnections.Where(c => c.Key == s.Key).SelectMany(c => c.Value);

        foreach (var connectionId in connectionsTiedToSession)
            context.Clients.Client(connectionId).sessionRegistered(message, sessionId);
    }
}

This method will create a new session entry for us and look up all other sessions for the user. It will then loop through all connections for the sessions and notify the user that a new session was created.

So far so good, right? This takes care of almost all of the server side code. But next we’ll jump to the client side JavaScript and implement that notification.

When the server calls the client to notify the user about a new session we want to write the message out to screen and give the user the option of killing the session.

HTML:

<div class="notification"></div>

JavaScript:

var notifier = $.connection.notificationHub;

notifier.client.sessionRegistered = function (message, session) {
    $('.notification').text(message);

    $('.notification').append('<a class="killSession" href="#">End Session</a>');
    $('.notification').append('<a class="DismissNotification" href="#">Dismiss</a>');
    $('.killSession').click(function () {
        notifier.server.killSession(session);
        $('.notification').hide(500);
    });

    $('.DismissNotification').click(function () {
        $('.notification').hide(500);
    });
};

On session registration the notification div text is set to the message and a link is created to allow the user to kill the session. The click event calls the NotificationHub.KillSession method.

Back in the hub we implement the KillSession method to remove the session from the list of active sessions.

public void KillSession(string session)
{
    var connections = sessionConnections[session].ToList();

    sessionConnections.Remove(session);
    UserSessions.Remove(session);

    foreach (var c in connections)
    {
        Clients.Client(c).sessionEnded();
    }

}

Once the session is dead a call is made back to the clients associated with that session to notify the page that the session has ended. Back in the JavaScript we can hook into the sessionEnded function and reload the page.

notifier.client.sessionEnded = function () {
    location.reload();
}

Reloading the page will cause the browser to make a request to the server and the server will call our custom SessionSecurityTokenHandler where the ValidateSession method will throw an exception. Once this exception is thrown the request is stopped and all subsequent requests within the same session will have the same fate. The dead session should redirect to your login page.

To test this out all we have to do is load up our application and log in. Then if we create a new session by opening a new browser and logging in, e.g. switching from IE to Chrome, or within IE opening a new session via File > New Session, our first browser should notify you. If you click the End Session link you should automatically be logged out of the other session and redirected to your login page.

Pretty cool, huh?

Real-time User Notification and Session Management with SignalR - Part 1

by Steve Syfuhs / March 07, 2013 10:21 PM

As more and more applications and services are becoming always on and accessible from a wide range of devices it’s important that we are able to securely manage sessions for users across all of these systems.

Imagine that you have a web application that a user tends to stay logged into all day. Over time the application produces notifications for the user and those notifications should be shown fairly immediately. In this post I’m going to talk about a very important notification – when the user’s account has logged into another device while still logged into their existing session. If the user is logged into the application on their desktop at work it might be bad that they also just logged into their account from a computer on the other side of the country. Essentially, what we want is a way to notify the user that their account just logged in from another device. Why didn’t I just lead with that?

In the next few posts I’m going to show how we can build a real-time user notification and session management system for a web application.

To accomplish this task I’m going to use the SignalR library:

ASP.NET SignalR is a new library for ASP.NET developers that simplifies the process of adding real-time web functionality to your applications. Real-time web functionality is the ability to have server-side code push content to connected clients instantly as it becomes available.

Conceptually it’s exactly what we want to use – it allows us to notify a client (the user’s first browser session) from the server that another client (another browser or device) has logged in with the same account.

SignalR is based on a Remote Procedure Call (RPC) design pattern allowing messages to flow from the server to a client. The long and the short of it is that whenever a page is loaded in the browser a chunk of JavaScript is executed that calls back to the server and opens a connection either via websockets when supported or falls back to other methods like long polling or funky (but powerful) iframe business.

To understand how this works it’s necessary to get SignalR up and running. First, create a new web project of your choosing  in Visual Studio and open the Nuget Package Manager. Search online for the package “Microsoft.AspNet.SignalR” and install it. For the sake of simplicity this will install the entire SignalR library. Down the road you may decide to trim the installed components down to only the requisite pieces.

Locate the global.asax file in your project and open it. In the Application_Start method add this bit of code:

RouteTable.Routes.MapHubs();

This will register a hub (something we’ll create in a minute) to the “~/signalr/hubs” route. Next open your MasterPage or View and add the following script references somewhere after a reference to jQuery:

<script type="text/javascript" src="scripts/jquery.signalR-1.0.1.js"></script>
<script type="text/javascript" src="signalr/hubs"></script>

You’ll notice the second script reference is the same as our route that was added earlier. This script is dynamically generated and provides us a proxy for communicating with the hub on the server side.

At this point we haven’t done much. All we’ve done is set up our web application to use SignalR. It doesn’t do anything yet. In order for communication to occur we need something called a Hub.

A hub is the thing that offers us that RPC mechanism. We call into it to send messages. It then sends the messages to the given recipients based on the connections opened by the client-side JavaScript. To create a hub all we need to do is create a new class and inherit from Microsoft.AspNet.SignalR.Hub. I’ve created one called NotificationHub.

public class NotificationHub : Hub
{
    // Nothing to see here yet
}

A hub is conceptually a connector between your browser and your server. When a message is sent from your browser it is received by a hub and the hub sends it off to a given recipient. A hub receives messages through methods defined by you.

Before digging into specifics a quick demo is in order. In our NotificationHub class let’s create a new method:

public void Hello(string message)
{
     Debug.WriteLine(message);

}

For now that’s all we have to write server-side for the sake of this demo. It will receive a message and it will write it to the debug stream. Next, go back to your page to write some HTML and JavaScript.

First create a <div> and give it an Id of connected:

<div id=”connected”></div>

Then add some JavaScript:

$.connection.hub.start().done(function () {
        $('#connected').text('I'm connected with Id: ' + $.connection.hub.id);
    });
}

What this will do is open a proxy connection to the hub(s) and once it’s completed the connection dance, the proxy calls a function and sets the text to the Id of the proxy connection. This Id value is a unique identifier created every time the client connects back to the server.

Now that we have an open connection to our hub we can call our Hello method. To do this we need to get the proxy to our notification hub, which is done through the $.connection object.

var notifier = $.connection.notificationHub;

For each hub we create and map to a route, the connection object has a pointer to it’s equivalent JavaScript proxy. Mind the camel-casing though. Once we have our proxy we can call our method through the server property. This property maps functions to methods in the hub. So to call our Hello method in the hub we call this JavaScript:

notifier.server.hello(‘World!’);

Lets make that clickable.

<a id=”sayHi” href=”#”>Say Hello!</a>

$(‘#sayHi’).click(function() { notifier.server.hello(‘World!’); });

If you click that you should now see “World!” in your Debug window.

That’s all fine and dandy for sending messages to the server, but AJAX already does that. Boring! Let’s go back to our hub and update that Hello method. Add the following line of code:

public void Hello(string message)
{
    Clients.All.helloEveryone(message);
}

What this will do is broadcast our message to All connected clients. It will call a function on the client named helloEveryone. For more information on who can receive messages take a look at the Hubs documentation. However, for our clients to receive that message we need to hook in a function for our proxy to call when it receives the broadcast. Back in the HTML and JavaScript add this:

<div id=”msg”></div>

notifier.client.helloEveryone = function(message) {
    $('#msg').text(message);
}

We’ve hooked a function into the client object so that when the proxy receives the message to call the function, it will call our implementation. It’s really easy to build out a collection of calls to communicate both directions with this library. All calls that should be sent to the server should call notifier.server.{yourHubMethod} and all calls from the hub to the clients should be mapped to notifier.client.{eventListener}.

If you open a few browsers and click that link, all browsers should simultaneously receive the message and show “World!”. That’s pretty cool.

At this point we have nearly enough information to build out our session management and notification system. In the next post I’ll talk about how we can send messages directly to a specific user, as well as how to send messages from outside the scope of a hub.

Windows Azure Active Directory Federation In Depth (Part 2)

by Steve Syfuhs / December 07, 2012 10:02 PM

In my last post I talked a little bit about the provisioning and federation processes for Office 365 and Windows Azure Active Directory (WAAD). This time around I want to talk a little bit about how the various pieces fit together when federating an on premise Active Directory environment with WAAD and Office 365. You can find lots of articles online that talk about how to configure everything, but I wanted to dig a little deeper and show you why everything is configured the way it is.

Out of the box a Windows Azure Active Directory tenant manages users for you. You can create all your users online without ever having to configure anything on premise. This works fairly well for small businesses and organizations that are wanting to stop managing identities on premise altogether. However, for more advanced scenarios organizations will want to synchronize their on-premise Active Directory with WAAD. Getting this working revolves around two things: the users, and the domain.

First off, lets take a quick look at the domain. I’m using the Microsoft Online Services Module for PowerShell to query for this information. I’m going to use my domain as an example: syfuhs.net.

PS C:\Users\Steve\Desktop> Get-MsolDomain -DomainName syfuhs.net | fl *

Authentication : Managed
Capabilities   : Email, OfficeCommunicationsOnline
IsDefault      : True
IsInitial      : False
Name           : syfuhs.net
RootDomain     :
Status         : Verified

The important thing to look at is the Authentication attribute. It shows Managed because I haven’t configured federation for this domain.

If we then take a look at a user we see some basic directory information that we entered when the user was created. I’ve removed a bit of the empty fields but left an important one, the ImmutableId field.

PS C:\Users\Steve\Desktop> Get-MsolUser -UserPrincipalName steve@syfuhs.net | fl *

DisplayName                 : Steve Syfuhs
FirstName                   : Steve
ImmutableId                 :
LastName                    : Syfuhs
OverallProvisioningStatus   : Success
UserPrincipalName           : steve@syfuhs.net
ValidationStatus            : Healthy

The Immutable ID is a unique attribute that distinguishes a user in both on-premise Active Directory and Windows Azure Active Directory. Since I haven’t configured federation this value is blank.

Skip ahead a few pages after running the Convert-MsolDomainToFederated cmdlet and my domain is magically federated with my local Active Directory. If I re-run the first command we’ll see the Authentication attribute set to Federated. However, running the second command doesn’t return an Immutable ID and if I tried logging in through ADFS I get an error. What gives?

If we look at the token that is passed from ADFS to WAAD after sign in we see that there is actually a claim for an Immutable ID. This ID is what is used to determine the identity of the user, and if Office 365 has no idea who has that value it can’t trust that identity.

This particular problem is solved through directory synchronization using the DirSync service. DirSync is configured to get all users from Active Directory and add them to Windows Azure Active Directory. It synchronizes most attributes configured for a user including the objectGUID attribute. This attribute is synchronized to the ImmutableID attribute in WAAD. It’s the anchor that binds an on-premise user with a cloud user.

Two questions tend to arise from this process:

  1. Why not just use the UPN for synchronization?
  2. Why do you need to synchronize in the first place?

Both questions are fairly simple to answer, but the answers depend on one another. You cannot synchronize against a UPN because a user’s UPN can easily change. You need a value that will never change across the lifetime of a user account (hence the name “immutable”). You need the value to stay constant because synchronization will happen often. You need to synchronize any time a value changes in the on-premise Active Directory. Examples of changes include address changes or name changes. Changing your name can often result in changing your UPN.

It’s preferred to keep these attributes up to date in both systems because then applications can trust that they are getting the right values when requested from either system. This still begs the question though, why do you need to synchronize in the first place? Some people may ask this because it’s theoretically possible to provision new users as they first sign into an application. If the user doesn’t exist when they log in just create them. Simple.

The problem of course is that certain systems require knowledge of the user before the user ever logs in. A perfect example is Exchange. Imagine if a user is on vacation while the transition to Office 365 occurs. If the user doesn’t log in until they get back, that means they wouldn’t have received any email while they were away. Admittedly, not receiving a few weeks of email might be the preferred scenario for some, but I digress.

So we have to configure DirSync. Skip ahead a few more pages and DirSync executed and synchronized all my users. If we take a look back at my account we now see a value for the immutable ID:

PS C:\Users\Steve\Desktop> Get-MsolUser -UserPrincipalName steve@syfuhs.net | fl *

DisplayName                 : Steve Syfuhs
FirstName                   : Steve
ImmutableId                 : lHh/rEL830q6/mStDnD4uw==
UserPrincipalName           : steve@syfuhs.net
ValidationStatus            : Healthy

At this point I should now be able to log in.

If I navigate to https://portal.microsoftonline.com I’m redirected to https://login.microsoftonline.com and prompted for credentials. However, as soon as I type in my username it prompts telling me I have to go else where to sign in.

image

The sign in screen is smart enough to parse the domain name from my user and lookup the Authentication type tied to that domain. If the domain is configured as Federated the sign in page is told to redirect to ADFS. If we return back to that first PowerShell command we’ll see the authentication is set to Federated. This was set by the Convert-MsolDomainToFederated  command. Two things happened when it was called.

First, ADFS was configured to allow sending tokens to Windows Azure Active Directory. Second, WAAD was configured to receive tokens from ADFS.

We can take a look at exactly what was configured in WAAD by running more PowerShell.

PS C:\Windows\system32> Get-MsolDomainFederationSettings -DomainName syfuhs.net

ActiveLogOnUri         : << adfs server and username mixed endpoint >>
FederationBrandName    : syfuhs.net
IssuerUri              : urn:syfuhs:net
LogOffUri              : << adfs signout url >>
MetadataExchangeUri    : << adfs server mex endpoint >>
NextSigningCertificate :
PassiveLogOnUri        :
https://login.syfuhs/adfs/ls/
SigningCertificate     : MIICzDCCAbSgA.....sh37NMr5gpFGrUnnbFjuk9ATXF1WZ

I’ve stripped out a few things to make it a little more readable. The key is that PassiveLogOnUri field. That is the URL passed back to the sign in page and is what is used to compose a WS-Federation signin request.

If I click the link I’m redirected to ADFS and if the computer I’m using is a member of the same domain as ADFS I shouldn’t be prompted for credentials. After Windows Authentication does it’s thing ADFS determines that WAAD sent us because the wtrealm URL parameter is set to urn:federation:MicrosoftOnline which is WAAD's Audience URI.

When Convert-MsolDomainToFederated was called, ADFS was instructed to create a Relying Party Trust for WAAD. That trust had a set of claims issuance rules that query Active Directory for various things like a user’s objectGUID and UPN. These values are formatted, bundled into a SAML token, and signed with the ADFS signing key. The token is then POST’ed back to WAAD.

The SigningKey field we saw in the Get-MsolDomainFederationSettings command is the public key to the ADFS signing key. It was configured when Convert-MsolDomainToFederated was called. It is used to verify that the token received from ADFS is valid.  If the token is in fact valid the domain is located based on the Issuer URI and UPN, and the user is located in the domain. If a user is found then WAAD will create a new token for the user and issue it to whichever service initially requested login, which in our case is https://portal.microsoftonline.com.

From this point on any time I browse to an Office 365 service like Exchange, I’m redirected back to https://login.microsoftonline.com, and if my session is still valid from earlier, a new token is issued for Exchange. Same with SharePoint and Dynamics, Windows Intune, and any other application I’ve configured through Windows Azure Active Directory – even the Windows Azure management portal.

Federation with Office 365 through Windows Azure Active Directory is a very powerful feature and will be a very important aspect of cloud identity in the near future. While federation may seem like a complex black box, if we start digging into the configuration involved we start to learn a lot about the all the various moving parts, and hopefully realize its not too complex.

Introduction to Windows Azure Active Directory Federation Part 1

by Steve Syfuhs / November 30, 2012 12:19 AM

Earlier this week Microsoft released some interesting numbers regarding Windows Azure Active Directory (WAAD) authentication.

Since the inception of the authentication service on the Windows Azure platform in 2010, we have now processed 200 BILLION authentications for 50 MILLION active user accounts. In an average week we receive 4.7 BILLION authentication requests for users in over 420 THOUSAND different domains.

[…] To put it into perspective, in the 2 minutes it takes to brew yourself a single cup of coffee, Windows Azure Active Directory (AD) has already processed just over 1 MILLION authentications from many different devices and users around the world.  Not only are we processing a huge number of authentications but we’re doing it really fast!  We respond to 9,000 requests per second and in the U.S. the average authentication takes less than 0.7 seconds.

Whoa.

Now, some people may be wondering what this is all about. Where are all these requests coming from? What domains? Who? Huh? What? It’s actually pretty straightforward: 99.99999999% of all these requests are coming from Office 365 and Dynamics CRM.

Windows Azure Active Directory started as the authentication service for Office 365. The service is built on the Microsoft Federation Gateway, which is the foundation for Windows Live/Microsoft accounts. As the platform matured Microsoft opened the system to allow more applications to authenticate against the service. It has since transitioned into it’s proper name Windows Azure Active Directory.

The system at it’s core is simply a multitenant directory of users. Each tenant is tied to at least one unique domain. Each tenant can then allow applications to federate. This is basically how Office 365 works. When you create a new Office 365 account, the provisioning system creates a new tenant in WAAD and ties it to a subdomain of onmicrosoft.com, so you would for instance get contoso.onmicrosoft.com. Once the tenant is created the provisioning system then goes off to the various services you’ve selected like Exchange, SharePoint, CRM, etc and starts telling them to create their various things necessary for service. These services now know about your WAAD tenant.

This is all well and good, but you’re now using contoso.onmicrosoft.com, and you would rather use a different domain like contoso.com for email and usernames. Adding a domain to Office 365 requires telling both WAAD and the various services that a new domain is available to use in the tenant. Now WAAD has two domains associated with it.

Now we can create users with our custom domain contoso.com, but there’s like a thousand users and you have Active Directory locally. It would be much better if we could just log into Office 365 using our own Active Directory credentials, and it would be so much nicer on the administrator if he didn’t have to create a thousand users. This calls for federation between WAAD and AD through Active Directory Federation Services (too. many. AD-based. names!).

Things get a little more complicated here. Before looking at federation between WAAD and AD we should take a look at how authentication normally works in Office 365.

First a user will try to access an application like SharePoint. SharePoint doesn’t see a session for the user so it redirects the user to login.microsoftonline.com, which is the public face of Windows Azure Active Directory. The user enters their credentials managed through your WAAD tenant, and is then redirected back to SharePoint with a token. SharePoint consumes the token and creates a session for the user. This is a standard process called passive federation. The federation is between SharePoint and WAAD. SharePoint and the various other services trust login.microsoftonline.com (and only login.microsoftonline.com) to issue tokens, so when a user has a token issued by login.microsoftonline.com its understood that the user has been authenticated and is now trusted. Clear as mud, right?

Allowing authentication via your on premise Active Directory complicates things a little. This involves creating a trust between Windows Azure Active Directory and your Active Directory through a service called Active Directory Federation Services. A trust is basically a contract that states WAAD will understand and allow tokens received from ADFS. With this trust in place, any authentication requests to WAAD through login.microsoftonline.com will be passed to your ADFS server. Once your ADFS server authenticates you, a token is generated and sent back to login.microsoftonline.com. This token is then consumed, and a new token is generated by login.microsoftonline.com and issued to whichever service asked for you to log in. Remember what I said above: Office 365 services only trust tokens issued by login.microsoftonline.com. Everything flows through WAAD.

That was a pretty high-level discussion of how things work, but unfortunately it’s missing a few key pieces like DirSync. In my next post I’ll dive much deeper into the inner workings of all these bits and pieces explaining how Windows Azure Active Directory federates with your on premise Active Directory.

Self-Serving Single Sign On

by Steve Syfuhs / September 17, 2012 01:34 PM

When I wrote Enough with the Pain of Passwords someone told me it was completely self-serving. Actually, it was.

My day job is building a commercial Single Sign On product so I’m terribly biased toward people using it. I quite like my job, and I really like my product so I’m more than happy to get people to buy our stuff. This doesn’t actually change how I feel about passwords though.image

I hate passwords. In current form they are an archaic mechanism for authentication and that mechanism is more often than not flawed.

Archaic is, I think, an appropriate word because we are fairly limited in how we can use passwords. This is because passwords are shared secrets. Both you and the application need to know the password – the secret. This makes it difficult to properly secure the secret because frankly, more than one entity knows the secret. However, shared secrets are a useful method for authenticating a principal because they are so simple to use, but they can be a challenge to use securely. Shared secrets tend to be static. They don’t change often because there often isn’t an easy way to change them.

Shared secrets create barriers between systems because each and every system in play needs to know the secret. Either you let everyone know the secret, or nobody new know the secret. The latter increases security (in theory) but reduces usability, while the former decreases security, and increases usability (in theory). When it comes to integrating such systems we don’t need yet another thing getting in the way. Sure we could argue that it’s more secure that way, but it’s not. It can’t be. If the business really needs these things to talk they will make them talk in ways that were never originally in the plans. That means security boundaries will likely be circumvented in ways the original developers never imagined. This can either be in a rich desktop client, or through a web browser.

This of course isn’t just true in a business – it applies to the internet as a whole. Users tend to consume data from one service and do something with it in another. If it’s a pain to move between those two services then the user is annoyed and that means they may just decide its not worth it – or worse they go the easy route and use the same password between the services so they don’t have to think. The less we make someone think about things other than what they are working on the better because they will do as much as possible to think as little as possible. As a user, I will do as much as possible to be able to think as little as possible when logging into things.

I might be mixing ideas here. In some cases the systems could be artificial like a server and applications, or it could be a person consuming content from one of the applications and trying to share it in another application. It could either occur through back channel API’s or through a user copying and pasting from browser tab to browser tab.

Imagine that you have an application, and to use the application you need an identity – in other words, its not anonymous. To get an identity you need to prove you are who you say you are. This is authentication. Normally we use passwords, and this means we have to manage passwords. We need a process to change them. To issue them. To reset them. To authenticate them. To store them. We tell our users to use something complex and secure. We tell them not to reuse it. We tell them not to write it down. All the while this is going to slow down the user because they aren’t going to remember the friggen thing anyway. Rinse, wash, and repeat for every application someone uses.

This does not scale. Either a user stops using new applications (or stops using older applications) or more likely the user just starts repeating their passwords. Let me repeat that, since very few developers seem to get this: passwords do not scale.

This is why we want federation. It’s not a new concept. Get someone else to do it. We have to be careful though. It’s not one size fits all – one single provider can’t be the sole source for identity information. Nor can we support every possible provider under the sun. That’s why last time I used the term persona. Business persona, personal persona, play persona, student persona, etc.

Imagine your target audience. Are you wanting to deal with businesses? Are you trying to do something useful for peoples personal lives? If you build in federation, they will use it. Maybe not immediately, but eventually there will be a critical mass of passwords and people will start transitioning to federated identities.

Does this solve our problem though? Is it secure? As all good answers are cop outs, it depends. The short answer is, it can be. It depends on how much we want to trust the identity provider, as well as how much we can trust the identity provider.

In other words, how much do we trust that the data we receive from the identity provider is accurate, and how much do we trust that it really is the person we want logging into the identity provider? For the first half its pretty simple: I trust the government to provide the SIN/SSN of the user accurately, but I don’t really trust Twitter to provide an accurate home address. Part of this is common sense. The other half revolves around how the identity provider authenticates its users.

We know passwords are weak so if the identity provider only allows passwords, maybe we don’t trust it to secure our intellectual property.  I trust Twitter to authenticate users for my new super-cool social media thingamajig, but I certainly wouldn’t trust it for my new business financial management solution. If the identity provider is using two-factor authentication then perhaps we can trust it a bit more. Does the identity provider allow for elevated contexts? Can we authenticate with passwords for generic access, but then request a stronger authentication method for certain things?

Now that’s an interesting thought. If you have an identity provider that can do this for you, you now have a new feature. Suppose your application is used in team scenarios. Multiple people accessing stuff might require management and administration. Anyone can read or create, but to modify or delete you need to elevate. Oops, heading off on a tangent.

Anyway, back on message: your authentication sucks and if I have to create another bloody password to use your new application, I’m not going to use your new application.

That might be a bit too harsh. Passwords can’t scale because I can’t remember anymore new passwords. If you require me to use a new password, I’m not going to remember it, so I can’t use your application.

This is a self-serving plea from me to developers: I hate passwords because I can’t remember them. Please make my life easier.

Enough with the Pain of Passwords

by Steve Syfuhs / August 21, 2012 02:44 PM

Passwords suck. This is a well known fact. Of course, we have conditioned ourselves to using passwords in painful ways so we accept this fact and move on with our lives. Except, I can’t take it anymore.

Every week it seems there’s another breach, and every week there’s yet another security guru spouting the need for better-stronger-more-secure passwords. If you create a “strong” password that meets xyz requirements then it will take 42.3 bajillion years to crack regardless of what hash algorithm the application is using. The problem with this though is that “strong” passwords are ridiculously hard to remember and passwords that are easy to remember are easy to crack.

So we promote the use of password managers -– tools that we use to store our super-strong-secure passwords in a secure way and we get our passwords from said manager every time we need to use a password.

Fuck. That.

I mean, yes they work for storing password securely, but the underlying problem is that we use passwords for authentication for nearly everything. This isn’t necessarily a bad thing in theory, but in practice passwords don’t scale for humans. As we become more and more connected to more and more applications we realize we have more and more passwords that we need to remember on an almost daily basis, and they are all very different, variations on a theme, or the same password reused over and over again. Using a password manager for this is complicated and slow, and slow or complicated security processes fail. Often.

No wonder we hear about passwords all the time.

Then we hear about the blame. We blame users for not using secure passwords when things go south.

“Oh that’s why you got hacked… your passwords aren’t secure.”

Of course we blame the users! Don’t believe me? Check the news. We point out that 58% of all passwords breached are under some arbitrary length requirement that normal users don’t understand let alone care about. Sure we do it as a service to others, but we do it in a condescending way as if people should know better.

Or we blame the application developers.

“You didn’t hash your passwords with a key-derived function with 100 iterations so attackers can brute force the passwords if they have an offline copy of your database.

Really? What the hell does that mean? Especially to a developer that doesn’t understand basic abstraction let alone cryptography? Oh, I’m supposed to use at least 1000 iterations?

Passwords are a mess.

As the old joke goes

“Doctor, it hurts when I do this.”
”Then don’t do that!”

We need to stop using passwords. There will always be uses for passwords, but as a defacto authentication scheme? No. Stop it. Just stop it.

How do we do that then?

The standard answer is to get our identity from somewhere else. This is Federation or Single Sign On. Instead of doing the work yourself, get someone else to do it.

Consider the problem: for the bulk of the applications we use we have one persona, or a set of personas for various groups of applications. Business applications get my business persona; personal applications get my personal persona; educational applications get my student persona; etc. If we use the same basic persona (or identity) for a set of applications why on earth should I have to create a different identity for each application? Why should each application have their own way of authenticating me?

The resistance we see though is the application developer not wanting to give up control of that password. If they control the password, they control the users fate in the application. Actually, it’s a little understandable.

This is a call to action to all those developers: stop it!

Let go of the passwords. Just let go. Loosen your grip. Easy there. I know it’s tough, but it’s time to let go.

In fact, you don’t want to manage those passwords. Do you really want to get blamed when all of your users passwords are stolen because you didn’t know any better? This means less risk for you.

Risk bad. Less risk good.

But wait! Don’t go hooking up with every identity provider you meet. Only hook up with those you like. If you’re building a business application, go federate with the customer’s company; if you’re building a slick new social media site federate with Twitter or Facebook or LiveID or Google.

Keep it simple. You like Twitter as a provider. Joe’s Fish Taco and Identity notsomuch. Having too many providers will confuse your users because they will forget which provider they used.

If you don’t have any user passwords to manage anymore, that means you don’t have any user passwords to manage! Less work. Less hassle. Less annoyed customers because they can’t remember their password.

Nice, right?

As users we need to beg the developers of the applications we use to talk with other identity providers, otherwise they won’t see the need. We have to convince them passwords suck.

Is that too much to ask?

Six Bugs and Eight Bytes

by Steve Syfuhs / May 22, 2012 01:07 PM

Over on the Chromium blog there is a post that discusses one of the vulnerabilities that allows remote code execution in the Chrome browser.

This vulnerability was submitted through the Pwnium competition.

What struck me as interesting was the amount of work required to execute code remotely. This particular attack requires hitting six different bugs across various components of the browser and only being able to play with eight bytes of arbitrary data. Go read the post for more information.

I bring this up because it’s a good example of why it can be difficult to find security vulnerabilities -– not all bugs are shallow.

If you want secure software you have to start secure. The development process, the development environment, the architecture, the testing, the developers, they all have to be secure.

The development process needs to be secure. Work with a Security Development Lifecycle.

The development environment needs to be secure. Make sure the development machines are always patched, including build machines and QA machines. They need to be locked down. This means making sure developers aren’t running as admin. To all the developers that just groaned: suck it up. You don’t need admin privileges. If you do, you’re doing something wrong.

The architecture of the software needs to be secure. Use models that are deemed secure. Reuse trusted designs, and for the love of all things holy don’t roll your own security systems.

The tests need to broad and deep. Code coverage is a good thing. Not only do you need functional and UI tests, you also need proper vulnerability testing. Fuzz testing is your friend. Test the attack surface. Run code analysis at it’s highest sensitivity. Oh, and be sure to test the binaries themselves. Compilers can do funny things.

Finally, the developers need to be secure. That’s kind of a funny phrase. Developers need to know how to develop securely. Training is key. Get the developers in a room playing Elevation of Privilege. It may not seem like you’re doing work, but you are creating a threat model of the application.

I've written about this before and I will likely continue writing about this until its hammered into everyone.

Part of the problem I think is the community of security. There are hundreds of security conferences every year, except most of them focus on why you’re insecure. The majority of sessions talk about different types of vulnerabilities and new attack vectors. Does anyone else see a problem with that? If all you are taught is how to spot vulnerabilities, you are missing one very important part: how to fix the bloody vulnerability.

The community needs to rethink how we teach people security. Being able to spot vulnerabilities is a necessary skill, but it doesn’t do us much good if we can’t fix the vulnerability.

Dana Epp on the Landscape of Risk

by Steve Syfuhs / May 07, 2012 11:26 AM

I don’t get to say it enough, but I really love my job. I get to work on a pretty awesome product and I get to work with a bunch of really smart people.

One of them is my boss Dana Epp. Without sounding like a kiss-ass, I have to say I really like working for Dana. There’s so much I learn from the guy, and his presentations rock. I wanted to point out a presentation he did last week at the Kaseya Connect 2012 conference in Las Vegas on The landscape of risk. Go watch it. He starts at about 37 minutes in.

And remember it the next time you connect to the WiFi at a conference. Smile

Study of Commercially Deployed Single Sign On

by Steve Syfuhs / April 25, 2012 05:40 PM

Microsoft Research published a paper sometime last month analyzing Single Sign On services hosted by various commercial entities.

Go Read it: Signing Me onto Your Accounts through Facebook and Google: a Traffic-Guided Security Study of Commercially Deployed Single-Sign-On Web Services.

The paper had been sitting on my desk for a couple weeks (literally) before I had a chance to read through it. It actually made it’s rounds through the company before I had a chance to read it.

In any case, I thought it would be good to post a link for people to read because it outlines some very important implications of using a Single Sign On service.

Abstract:

With the boom of software-as-a-service and social networking, web-based single sign-on (SSO) schemes are being deployed by more and more commercial websites to safeguard many web resources. Despite prior research in formal verification, little has been done to analyze the security quality of SSO schemes that are commercially deployed in the real world. Such an analysis faces unique technical challenges, including lack of access to well-documented protocols and code, and the complexity brought in by the rich browser elements (script, Flash, etc.). In this paper, we report the first “field study” on popular web SSO systems. In every studied case, we focused on the actual web traffic going through the browser, and used an algorithm to recover important semantic information and identify potential exploit opportunities. Such opportunities guided us to the discoveries of real flaws. In this study, we discovered 8 serious logic flaws in high-profile ID providers and relying party websites, such as OpenID (including Google ID and PayPal Access), Facebook, JanRain, Freelancer, FarmVille, Sears.com, etc. Every flaw allows an attacker to sign in as the victim user. We reported our findings to affected companies, and received their acknowledgements in various ways. All the reported flaws, except those discovered very recently, have been fixed. This study shows that the overall security quality of SSO deployments seems worrisome. We hope that the SSO community conducts a study similar to ours, but in a larger scale, to better understand to what extent SSO is insecurely deployed and how to respond to the situation.

The gist of the paper is that when it comes to verification and validation of the security of SSO protocols, we tend to do formal tests of the protocols themselves, but we don’t ever really test the implementations of the protocols. Observation showed that most developers didn’t fully understand the security implications of the most important part in an SSO conversation – the token exchange:

Our success indicates that the developers of today’s web SSO systems often fail to fully understand the security implications during token exchange, particularly, how to ensure that the token is well protected and correctly verified, and what the adversary is capable of doing in the process.

Think about it. The token received from the IdP is the identity. The relying party trusts the validity of the identity by verifying the token somehow. If verification isn’t done properly an attacker can inject information into the token and elevate their privileges or impersonate another user. This is a fundamental problem:

For example, we found that the RPs of Google ID SSO often assume that message fields they require Google to sign would always be signed, which turns out to be a serious misunderstanding (Section 4.1).

Not all of the data in a token needs to be signed. In fact, if the IdP isn’t the authoritative source of the particular piece of data it may not want to sign that data. If the IdP can’t or wont sign the data, do you really want to trust it?

What’s the rule that’s always hammered into us when writing code? Do not trust user input. Even if it’s supposed to have come from another machine:

[…] when our browser (i.e., Bob’s browser) relayed BRM1 [part 1 of the message exchange], it changed openid.ext1.required (Figure 8) to (firstname,lastname). As a result, BRM3 [part 3 of message exchange] sent by the IdP did not contain the email element (i.e., openid.ext1.value.email). When this message was relayed by the browser, we appended to it alice@a.com as the email element. We found that Smartsheet accepted us as Alice and granted us the full control of her account.

If you receive a message that contains something you need to use you, not only do you have to validate that it’s in the right format, but you have to validate that it hasn’t been modified or tampered with before it hits your code.

This is something I’ve talked about before, but in a more generalized nature. Validate-validate-validate!

As an aside, an interesting observation made in the research is that all of this was done through black-box testing. The researchers didn’t have access to any source code. So if the researchers could find problems this way, the attackers could find problems the same way:

Our study shows that not only do logic flaws pervasively exist in web SSO deployments, but they are practically discoverable by the adversary through analysis of the SSO steps disclosed from the browser, even though source code of these systems is unavailable.

This tends to be the case with validation problems. Throw a bunch of corrupted data at something and see if it sticks.

They also realized that their biggest challenge wasn't trying to understand the protocol, but trying to understand the data being used within the protocol.

For every case that we studied, we spent more time on understanding how each SSO system work than on reasoning at the pure logic level.

The fundamental design of a Single Sign On service doesn’t really change between protocols.  The protocols may use varying terms to describe the different players in the system, but there are really only three that are important: the IdP, the RP, and the client. They interact with each other in fundamentally similar ways across most SSO protocols. It’s no surprise that understanding the data was harder than understanding the logic.

They didn’t go into much detail about why they spent more time studying data, but earlier they talked about how different vendors used different variations on the protocols.

[…] the way that today’s web SSO systems are constructed is largely through integrating web APIs, SDKs and sample code offered by the IdPs. During this process, a protocol serves merely as a loose guideline, which individual RPs often bend for the convenience of integrating SSO into their systems. Some IdPs do not even bother to come up with a rigorous protocol for their service.

In my experience the cost of changing a security protocol for the sake of convenience is usually protocol security. It usually doesn’t end well.

// About

Steve is a renaissance kid when it comes to technology. He spends his time in the security stack.