Monday, 29 March 2010

Book Review: Beginning ASP.NET Security

If you're doing web development with ASP.NET, you need this book. Simple as, end of.

And I'm not just saying that because I'm mentioned in it (page 235 for those of you playing along at home).

When I heard Barry was writing a book, I knew it'd be a good one to get, having seen Barry speak on security topics at several user groups and conferences. And now I've read it I can see it's going to become one of those books that never gets put away neatly on a shelf, it's always going to be open on someone's desk. Experienced developers shouldn't be put off by the 'Beginning ...' in the title, this book is for every ASP.NET/MVC/Silverlight/WCF developer who has security concerns. Which should be all of you.

The approach of the book is task-oriented; each chapter describes one or more vulnerabilities that a web developer may come across, and then describes how to mitigate against them. I started learning right from the first technical chapter, which covers validation: there are several things I've picked up about the ASP.NET validator controls, including how to validate input data against a .NET data type and how to write a custom validator. Cross-Site Request Forgery isn't quite what I thought it was either. Of course, things like Cross Site Scripting and SQL injection are covered, but also some of the more obscure vulnerabilities that are traps for the unwary; I'd never heard of things like traversal attacks and XPath injection. There is an excellent chapter on encryption covering all the options available in the .NET Framework for encypting and decrypting your data, although I'd have liked to see for each type of encryption some more suggested scenarios in which each method is appropriate. Coming right up-to-date Barry also covers how to use external authentication providers like OpenId, *ahem* LiveId and Windows Identity Foundation, and finally has a whole chapter on securing MVC applications, lest the lack of Viewstate and auto-encoding <%: tags leads MVC developers to believe there's nothing more they need to do.

Right, I'm off to do a security review of all our live sites. I may be some time...

Wednesday, 3 March 2010

What's New in AppFabric Caching Beta 2

Typical - just as I get an AppFabric Beta 1 caching cluster up and running for Edge UG this month, they release Beta 2!

This is, by all accounts, now a feature complete release for v1.0 with the RTM expected in Q3 this year. There is, however, no Go Live licence here, unlike Visual Studio. Let's take a look at AppFabric B2 and see what's changed (from a caching perspective)...

What's New in Installation
First of all, this release is aligned with the Release Candidate of .NET 4.0 and VS2010, so the dependency on the .NET Framework is moved up from the beta to the .NET 4.0 Release Candidate. Note that if you're removing the .NET 4.0 Beta in order to install AppFabric, you need to do this in Control Panel|Programs and Features, and uninstall the .NET 4.0 Framework Extended first, then the the .NET 4.0 Client Profile.

The installer seems to have had quite a bit of time spent on it for this release.
The set of features to install is largely the same as we saw in Beta 1, with the addition of an administration piece for the Dublin workflow component.

Post-installation, the AppFabric caching service has been renamed and no longer refers to the Velocity codename; it also now is not marked as a CTP (unlike the caching service in Appfabric Beta 1 which still showed as CTP4).

Installation and configuration have been decoupled into two separate wizards, which should make it possible to reconfigure a cluster without having to un- and re-install.The configuration wizard can be started at the end of installation, or separately from the Start menu.


What's New in Configuration
As before when configuring the caching piece you have to decide whether to store configuration information in SQL Server or using XML and a network share. There's still no guidance on when you should use one or the other, although included in this release is a comprehensive help file.

Selecting the SQL Server provider and clicking the Configure button opens this sub-dialog where you can build up the connection string to the configuration database. It's now explicit that if you enter the name of a database that doesn't exist and select the 'Create...' checkbox then the configurator will go and create the database for you. If you're adding a server to an existing cluster, then the 'Register...' checkbox is the one to select; if you unselect both checkboxes you lose the ability to enter any connection string information. However there seems to be a slight bug in that whether you create a new database from scratch or register a server to an existing database, when you return to the main configuration screen you can still choose whether you are creating a new cluster or joining an existing cluster.
As before, the configurator allows you set the size of the cluster to optimise the clusters' performance. The help file states that 'once you set the cluster size during configuration, you cannot change it later', however it's unclear how this fits in with the ability to re-run the configurator from the Start menu.

As I run my Velocity VM cluster with Windows Firewall disabled, I'm pleased to see that the Cache Node configuration page now detects when the firewall is disabled and accordingly disables the firewall exceptions checkboxes. This is a change to Beta 1 where the Velocity installer log would register a warning if the firewall was disabled.

What's New in Powershell
In a change from previous installs, there doesn't seem to be a Velocity Administration Powershell console installed by default; to access the Velocity Powershell commands you need to run up Powershell and then run 'import-module DistributedCacheAdministration'. Or you can add it to your Powershell profile - run 'get-help profiles' for details on doing this.
Looking at the list of Powershell commands available it seems that, unforgivably, there's still no commandlets for managing regions.The Install-Data and Install-Bits cmdlets that were in Beta 1 have disappeared.

A new feature is that it seems you can now use Powershell on any server with the Velocity cmdlets installed to manage any Velocity cluster, by using the 'Use-CacheCluster' cmdlet with a connection string to a configuration store (though the documentation talks about a connection string which implies this only works with the SQL Server provider). This cmdlet sets the context of subsequent commands e.g. Start-CacheCluster, Restart-CacheCluster. This enables you to manage multiple clusters from a server that isn't in any cluster. If you're running Use-CacheCluster on a server that is inside a cluster and has Cache Administration (from the installer) set up, you don't need to use any parameters, the current cluster is implied.

What's New in Client Configuration
The assemblies that you need to add to a project to use Velocity have been renamed, to Microsoft.ApplicationServer.Caching.Core.dll and Microsoft.ApplicationServer.Caching.Client.dll (in Windows\System32\AppFabric). The namespace has changed again, to Microsoft.ApplicationServer.Caching. And the requirement to also reference the Fabric assemblies has been removed, so there's only two references to add which makes the whole thing seem much cleaner.
The MSDN article on setting up the client environment states that there is a problem with referencing these DLLs as Visual Studio is unable to browse to Windows\System32\AppFabric, and that you need to hand-edit the project file to include these references. This seems to be incorrect, as I've just done it - I suspect that this may be due to the fact I'm running Visual Studio under an account which is an administrator on the server and thus has access to everything.
A couple of the old annoyances when writing client code are still there:
  • DataCacheFactory.GetCache is still not a static method, you still need to new up a DataCacheFactory.
  • Some of the code around using DataCacheServerEndpoints seems to have been refactored a little bit, but it still runs on an array, not a List(Of DataCacheServerEndPoint). But you can, of course, still get round this by using a List(Of DataCacheServerEndpoint) and then calling .ToArray on it.
That's all I've discovered that's new (for now), but I'll post more updates as I discover things!

Saturday, 20 February 2010

A Developer's Guide To Velocity on tour!

Following on from Liam's recent tour dates blog,I thought I should do something similar...

First of all I need to offer belated thanks to NxtGen Manchester for having me up to speak in January. I had a good time even though something went wonky in my VMs while I was running my demos that morning which meant I couldn't run the demos in the evening. I hope everyone still got an appreciation of the capabilities of Velocity.

I'm running this session again at Edge UG at Microsoft in London on 17th March - visit http://edgeug.net to sign up. I may be running it at DDD Scotland if I've been voted in. Subject to agreement on dates it'll be at NxtGen Southampton in June. I've also been talking to NxtGen Cambridge and NEBytes about doing it for them over the summer.
UPDATE: Well I didn't get voted in for DDD Scotland, but there'll be another opportunity to vote for me at DDD Southwest.And I now have a confirmed date for NxtGen Southampton - 24th June.

Sunday, 7 February 2010

What I Learned At DDD8

First thing on Saturday morning my Twitterstream was full of sleepy geeks converging on Reading - yes, it was time once again for DDD at Microsoft. DDDs are free one-day conferences where all the content is from the UK Microsoft developer community - Microsoft speakers are not allowed to speak, although they usually come just to hang out. The community also decide the sessions that form the agenda by voting on submissions. I was lucky enough to speak at DDD7, but my session didn't make it into DDD8 (which was for the best as hardware failure meant I wouldn't have been able to do any demos). They're also a good networking event - a useful addition this year was to have people's Twitter names on their badges, which meant that if, like me, you follow a number of people you've never met, you could start to spot them and say hello. In fact, at one point I thought 'this is just a social thing with some technical content tacked on'!

Once I was at Microsoft and checked in, the first person I saw was Simon Harriyott, who I met for the first time the preceding Thursday at Barry Dorrans' leaving drinks. Of which more later. As I was getting my sausage sandwich and coffee, I also bumped into VBUG Chair Tim Leung and had a quick catch-up with him before it was time to head into the first session of the day...

Barry Carr - Contractual Obligations: Getting Up and Running With Code Contracts
I walked into this session and pleasingly got a seat next to virtualisation guru and all-round good guy Liam Westley, and behind Guy Smith-Ferrier and Gary Short. I picked this session as it sounded to be similar to some work that was done at my last company, and it proved to be a very interesting talk. The concept of code contracts stems from some work done by the not-yet-dead Bertrand Meyer, father of the Eiffel programming language. Contracts allow you to specify pre- and post-conditions on methods, functioning like Asserts. One of the most interesting demos was where Barry stepped through some code, which had both pre- and post-conditions declared at the start of a function followed by the body of the function; as Barry stepped through the code Visual Studio seemed to be jumping around the code instead of following the flow of code as written, due to the way that Code Contracts amends the IL that your .NET code outputs. However the highlight of this talk was probably when one delegate had the temerity to ask a question; his reward was a USB stick, however Barry threw it to him unintentionally hard and nearly took him out!

I followed this with ...
Neil Robbins - Hello Document Databases
Neil said up front that he's a new speaker and that this was his first DDD session, and proceeded to give a blinding talk on NoSQL and CouchDB. CouchDB (and its' GUI, Futon) are all based around a mantra of Relax, which several of us shouted out from the audience at certain points when Neil got tied up by some Linuk case-sensitivity issues :-) Neil's demos were done with CouchDB running on Ubuntu, which was a slight disappointment for me as it effectively means CouchDB is something I won't be able to run at work; Neil's comment is that the installer for CouchDB on Windows is only a beta. Which is a shame as CouchDB looks like exactly the kind of technology we could do with at work for asset management software - we've had several conversations recently around the Entity-Attribute-Value pattern, which seems to be the major problem that CouchDB solves.
Andy Gibson - Web Application Testing with Selenium
This was an introduction to using Selenium, which is something I need to look into further, however I have to confess to too much Twittering and not enough paying attention in this session, particularly after John Nolan tweeted that he needed some water (Memphis was by now getting seriously warm) and minutes later Craig Murphy brought some in for him!

Simon Sabin - Entity Framework - How to Stop Your DBA Having a Heart Attack
I went into this session intending to pick up some knowledge about the Entity Framework, as I basically don't have any and one of my colleagues is intending to use it on his next project.But for that, and for me really, it was the wrong session. I still took some points away from it though, the key one being that although the SQL produced by the Entity Framework can look like it won't perform well, you can spend a lot of time trying to optimise it yourself but get only comparable results. Another good takeaway concerned the DATE datatype in  SQL Server 2008 - traditionally when trying to restrict results to a single date, we've used a SQL BETWEEN clause with the bounds set to midnight and 23:59 for the date in question; in SQL 2008 we can cast DATETIME values to DATE and just search for rows where the date is the date in question.
Oh, and for my personal future reference it's pronounced Say-bin.

Barry Dorrans - A Developers Guide To Encryption
And on to the last session of the day, and Barry's last DDD presentation before leaving the UK to go and work for Microsoft in Redmond. I first met Barry back at DDD1 and I've seen him speak a few times since then, and he's always been good. However, I already knew that his session was going to have some disruption, having had a chat with Phil Winstanley about it at the aforementioned leaving drinks. And also having provided to Phil and Craig Murphy, the organisers, a video of a rather younger Barry when he was on The Crystal Maze. And we weren't disappointed, either by the session (very good) or the disruptions (very funny). Barry wasn't too fazed by the videos that kept appearing on the big screen (or by Jon Skeet and others pointing out both mistakes in his code and typos on his slides). It started with coverage of hashing (which is NOT encryption), and then proceeded to show symmetric and asymmetric (private/public key) encryption, X.509 certificate encryption and XML encryption. I think everyone will remember Barry's key point about symmetric encryption keys, which can become diluted the more they are used for: Barry's message is keys are like condoms, don't re-use them. The only thing I would have liked to see would have been for each level of encryption the kind of data you might protect with it e.g. the correct level of encryption for storing, say, credit card data. 

All in all another excellent day at Microsoft, I should like to say a big thank you and well done once again to the organisers, looking forward to DDD9!

Thursday, 28 January 2010

Extensible Output Caching with Velocity

This morning Scott Gu posted an article on his blog about the extensibility points now built into output caching in ASP.NET 4.0. Steve Robbins said to me that it looked easy to wire up Velocity, and I was pleased to see that when ASP.NET 4.0 ships there will be a set of samples showing how to use Velocity as an output cache provider, however since Scott said that writing an output cache provider is just a case of inheriting from System.Web.Caching.OutputCacheProvider and overriding four methods, I decided to have a look at it at lunchtime.

And it does seem remarkably simple - here's my code:
Imports Microsoft.Data.Caching
Public Class VelocityOutputCacheProvider
    Inherits System.Web.Caching.OutputCacheProvider
Private Const cacheName As String = "VelocityOutputCache"
Private mCache As DataCache
Public Sub New()
    Dim factory As DataCacheFactory

    Try
        factory = New DataCacheFactory

        mCache = factory.GetCache(cacheName)
    Catch ex As Exception
        Throw
    Finally
        factory = Nothing
    End Try
End Sub

Public Overrides Function Add(ByVal key As String, ByVal entry As Object, ByVal utcExpiry As Date) As Object
    Try
        mCache.Add(key, entry, (utcExpiry - DateTime.UtcNow))
    Catch ex As Exception
        Throw
    Finally
    End Try
End Function

Public Overrides Sub Remove(ByVal key As String)
    Try
        Call mCache.Remove(key)
    Catch ex As Exception
        Throw
    Finally
    End Try
End Sub
Public Overrides Function [Get](ByVal key As String) As Object
Dim cachedObject As Object
    Try
        cachedObject = mCache.Get(key)
        Return cachedObject
    Catch ex As Exception
       Throw
    Finally
    End Try
End Function
Public Overrides Sub [Set](ByVal key As String, ByVal entry As Object, ByVal utcExpiry As Date)
    Try
        Call mCache.Put(key, entry, (utcExpiry - DateTime.UtcNow))
    Catch ex As Exception
        Throw
    Finally
    End Try
    End Sub
End Class

The only thing I'm a little fuzzy on is what object the Add method should return. It's slightly awkward that the Velocity Cache.Add method takes a TimeSpan parameter where the OutputCacheProvider passes in a point in time, so I've calculated a TimeSpan by subtracting the current time from the passed-in Date.
 
Something that's slightly unclear is how this would behave in a server farm. It depends whether each server maintains it's own set of cached pages, or the cached pages are common and available to all servers. If the latter then this would be a truly awesome boost to scalability since for any given web page only the first server that picked up a request for a given URL would need to compile it - other servers in the farm would then be able to pick up the cached copy and return it to the client.

Update: When the Add method is called, you don't need to return anything, just put the object into the cache and ASP.NET takes care of the rest. You get a warning that the function doesn't return anything but this can be ignored.

Wednesday, 6 January 2010

Installing AppFabric Caching Beta 1, Part 4

I'm pleased to report that I've (at last) had a measure of success with the AppFabric installer :-)

I mentioned in my last entry that I'd posted on the MSDN AppFabric Caching forum about the problems I'd been having with the installer. I also made two of my installation logs available. I'm indebted to Rahul Kaura from Microsoft, who pointed out that these were AppFabric general installation logs and steered me towards the cache-specific installation logs. These logs are found in the same place as the AppFabric logs i.e. your %TEMP% folder, are called DistributedCacheAppServerConfig(DateTime).log and I've found them invaluable in diagnosing and fixing installation problems.

So what were the problems I was having? From reading the log they seem to be largely around permissions to the Registry:
2010-01-06 11:52:52, Info DCACHE Adding access for NT AUTHORITY\NETWORK SERVICE on registry key HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Microsoft Distributed Cache\Version



2010-01-06 11:53:16, Error DCACHE System.InvalidOperationException: This access control list is not in canonical form and therefore cannot be modified.
at System.Security.AccessControl.CommonAcl.ThrowIfNotCanonical()
at System.Security.AccessControl.CommonAcl.AddQualifiedAce(SecurityIdentifier sid, AceQualifier qualifier, Int32 accessMask, AceFlags flags, ObjectAceFlags objectFlags, Guid objectType, Guid inheritedObjectType)
at System.Security.AccessControl.DiscretionaryAcl.AddAccess(AccessControlType accessType, SecurityIdentifier sid, Int32 accessMask, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
at System.Security.AccessControl.CommonObjectSecurity.ModifyAccess(AccessControlModification modification, AccessRule rule, Boolean& modified)
at System.Security.AccessControl.CommonObjectSecurity.AddAccessRule(AccessRule rule)
at Microsoft.Data.Caching.InstallConfig.Program.SetResetLocalPermissions(Boolean grant)
at Microsoft.Data.Caching.InstallConfig.Program.PostConfigServiceInstallSteps()
at Microsoft.Data.Caching.InstallConfig.Program.Install()
at Microsoft.Data.Caching.InstallConfig.Program.Main(String[] args)


2010-01-06 11:53:16, Error DCACHE Unexpected Error: This access control list is not in canonical form and therefore cannot be modified.


2010-01-06 11:53:16, Info DCACHE Configuration failed, Rolling back...

which is sort of annoying as I've been running the installer under an account that is a Domain Administrator, and the Domain Admins group is part of the Administrators group on each of my cache servers. The solution was to add the account I'm using to install AppFabric to the ACL for HKEY_LOCAL_MACHINE with full permission.

The installer still reports that it fails to configure AppFabric, but this is because the log includes a Warning that the Windows Firewall is disabled, which I'm reasonably sure I can ignore.

So, I now have an AppFabric caching cluster with three servers. Onward to actually using it!

Friday, 18 December 2009

Installing AppFabric Caching Beta 1, Part 3

In Part 1 of this (unintentional) series, I talked about how the AppFabric installer works only with Integrated Security and so I needed a domain before I could install it, and in Part 2 I talked about how I then built said domain. At this point I tried once again to install AppFabric on CACHESERVER1, with all it's Integrated Security goodness. And failed. When the installer got to the configuration screen, I entered SQLSERVER in the connection string dialog, then clicked on the dropdownlist to get the list of databases on SQLSERVER. I then got a Timeout error in trying to retrieve the list of databases. No matter what I tried, I couldn't get this to work. I created a UDL file on CACHESERVER1, running Integrated Security, pointing at SQLSERVER, and confirmed that I could not only see SQLSERVER and retrieve a list of databases, but successfully connect to a database. I raised this as a question on StackOverflow and on the MSDN AppFabric Caching forum (where it looks like I'm not the only one having trouble with installations). And whilst it looks like at least some of the AppFabric team have been answering questions on the MSDN forum, I've had no answer at all to my posts.

Since then, my development laptop has been rebuilt with Windows 7, which has necessitated rebuilding my server environment from scratch with Virtual PC for Windows 7 (though there was a flirtation with VirtualBox, which I may yet go back to, although at the moment I find the process for setting up differencing disks a little too involved for my taste). With a rebuilt set of servers, I turned back to the AppFabric install, however there was one subtle difference in the server builds this time around. In trying to use the UDL files to verify that the server could contact the database ahead of the install, I encountered a problem that the SQL Server Native Client provider was not installed, so to fix this I installed the Client Connectivity bits from the SQL Server 2008 disc. When I then tried the AppFabric installer, this resolved the issue of not being able to any databases on the server. Result!

Well, not really. Although this let me proceed with the installation, the installation failed with error code 2. And no explanation for what this error means or how to fix it. And once again, the MSDN Forum has (so far) been no help. I've tried a few other things since then, including using the XML Provider for storing the configuration information instead of SQL Server. This I actually watched as it created a ClusterConfig.xml file on the network share I'd set up (thus proving that the account had enough rights on the folder), and then  removed the file again. The installation failed with error code 2. Tonight I tried something else - when you select the SQL Server provider and go to enter the connection string, you can enter your own connection string, or leave it selected at Default. I tried it with Default, thinking that this would create, perhaps, a SQLExpress database that I could then transfer to my SQL Server. At the very least it would give me a working AppFabric installation that I could play with. No. Leaving the Default radio button checked does, from what I can see, nothing. There is no 'Default' connection string, in fact the installer doesn't even allow you to continue if you select this, making it the stupidest UI possible.

All of which leaves me totally stalled on working with AppFabric since I have yet to find a working configuration. It's all very tiresome.