In this second article of the series (see first article here), I’ll continue sharing security and Silverlight lessons learned while moving an application to Azure. Specifically let’s extend what we discussed in part one to include:
· More details about securing the on-premise service calls.
· Continue addressing the dangers of “*” in clientaccesspolicy.xml.
· Explain why a domain naming standard is desirable.
In part one we imagined moving our ASP.NET application to the cloud and extended it to host a Silverlight application which makes calls to on-premise services. We also imagined impressing management with our mastery of the cloud and starting the weekend early. Hey, it’s doable.
Moving the application was easy and required mainly web.config changes to enable passive federated security as shown in the patterns & practices ASP.NET to AD with Claims scenario. There were challenges getting Silverlight to call the on-premise service due to cross domain and cross security zone restrictions so we discussed RIA Services’ design pattern. Our application might look like this:
The first “SL Code” block shows Silverlight code running on the client calling RIA Services, which then in turn calls the on-premise services through the AppFabric service bus. The call between the Silverlight code and RIA Services uses passive, WS-Federation authentication in which SAML tokens are passed via an encrypted cookie. Part one explained how redirection to the ADFS server occurred during the initial call to the web site and WIF wrote the cookie to minimize further redirection.
There are two typical choices for securing the calls between RIA Services and the on-premise services. The easier of the two is to use X.509 certificates and pass the SAML tokens as a parameter in the service calls. The more architecturally correct approach uses WS-Trust 1.4’s ActAs capability. Even here at Microsoft getting ActAs configured is challenging; it has got to get easier. In either case we’ve had to change the configuration and possibly some code of the existing services to get this to work.
The second “SL Code” block shows Silverlight calling the on-premise services directly. In this case Silverlight will likely work with the existing services as-is except for needing to deploy the clientaccesspolicy.xml file and dealing with URL access restrictions in Silverlight.
Why is attack of the STS, such as Active Directory Federation Services (ADFS), especially dangerous? Well your STS contains the keys to your kingdom! It has lots of private information about your employees (the claims) and a well-known interface. Its URL is even well known because you’ve exposed it to the internet for federation with the cloud. It is a prime target for attack!
1. Educate yourself and your company about the protections Silverlight offers.
2. Carefully craft your clientaccesspolicy.xml files. Subdomain wildcard ("http://*.mycompany.com", for example) are the most open wildcards I’ll use for on-premise clientaccesspolicy.xml files.
3. Craft a domain naming standard for your local intranet security zone.
Part of the education is getting people to understand that installing software, and that includes allowing out-of-browser with elevated trust Silverlight applications, is not to be taken lightly. Software you install on your computer isn’t sandboxed and can access the STS as you. If that software is from badguys.com they’ve just requested your claims and used the token to access federated on-premise, cloud, and partner based systems impersonating you. Luckily SAML contains conditions which control when the token is valid so badguys.com will not be you indefinitely. The strongest mitigation is to use an asymmetric proof token with a protected private key, such as from a smart card, because badguys.com will not be able to prove ownership of the token. Silverlight does not support this asymmetric crypto though.
Don’t get overly perplexed by what I wrote above. It is still easier for an attacker to pop a dialog saying you’ve lost connection with Exchange, please enter your username and password. I’m only pointing out the details so you don’t open up a new attack surface unknowingly.
“Security Guidance for Writing and Deploying Silverlight Applications” is an excellent, although slightly dated, document which deep dives on the topic.
OK, how is a domain naming standard going to help you? In part one we talked about Silverlight’s cross-zone restrictions and either manually configuring IE or pushing Group Policy settings to specify domains which are part of the local intranet zone. By default your Azure hosted Silverlight application is loaded from a domain name ending in cloudapp.net. You need IE to consider this domain name part of the local intranet zone for the direct on-premise request to succeed. You don’t want to go through this step each time you deploy a new Azure application. You also don’t want to add http://*.cloudapp.net and let everyone’s Azure application into your local intranet zone.
The solution is to define a subdomain for your company’s cloud application, perhaps cloudapp.mycompany.com, and define a CNAME DNS entry for each application so that myapp.cloudapp.mycompany.com maps to myapp.cloudapp.net. See the note about CNAME at the bottom of Brandon Werner’s blog.
Now you can use the subdomain wildcard http://*.mycompany.com or http://*.cloudapp.mycompany.com as desired in clientaccesspolicy.xml files plus STS, IE and Group Policy settings. The upside is that you’ll onboard new cloud applications into your local intranet via a CNAME entry in your DNS without having to change all these other settings. The downside, for the socially energized individuals among us, is that you’ll coordinate with far fewer people and groups to get your new Silverlight cloud app working.
Silverlight’s URL access restrictions impact other functionality beyond making service calls so I recommend creating a domain naming standard even though a RIA Services application will happily run in IE’s internet zone.
Note that “Security Guidance for Writing and Deploying Silverlight Applications” discusses configuring access limitations down a particular URL for maximum safety. I agree that is the safest approach but I wonder how practical it is to maintain complex clientaccesspolicy.xml files especially considering that the file resides at the root of a web site and is for all the web applications within the site. Using a subdomain wildcard and a naming standard seems like a reasonable tradeoff.
Additionally the document suggests using a different top-level domain for cross-domain access, say mycompany.net for cross-domain and mycompany.com otherwise, to ensure cookies are not shared. The suggestion is defeated if badguys.com gets a user to follow a link to mycompany.net and the site doesn’t specifically ensure mycompany.com is used while writing cookies. The suggestion may also prevent you from using passive, WS-Federation authentication since it relies on cookies.
Next time we’ll step into the world of active, WS-Trust federation and look at what the Identity Developer Training Kit and RIA Services offer for making use of claims on the Silverlight client.