FxCop rules for securing WCF services
One of the coolest features (IMHO) that you will find in the september CTP version of the Web Service Software Factory project, in particular related to the WCF Security Guidance Package, is the new WCF Security Code Analysis feature. This new feature is basically a set of custom FxCop rules that are plugged into Visual Studio Static Analysis feature and have a couple of interesting things.
First, these rules not only detect defects regarding WCF security settings in code, but also in configuration files!. Yes, there are several custom rules that inspect settings in WCF sections of an application or web configuration file. The trick here is basically to get the configuration file that is located in the same folder as the target assembly, that is, the assembly being analyzed. This approach allows inspecting any configuration file and in particular, those that contains WCF sections in it.
Second, the provided solution in the aforementioned project contains unit tests for each rule so we can achieve a high level of confidence that each rule will be able to detect the required defect in code and configuration files as well.
WCF Security Code Analysis Implementation
Let’s see an example of how this is implemented. This diagram shows the hierarchy of classes that ends in the collection of implemented rules.
The root class, is simple a light wrapper of BaseIntrospectionRule that only set the required values in to the constructor.
protected SecurityInstrospectionRule(string name) : base(name, SecurityRulesUtilities.ResourceName, SecurityRulesUtilities.CurrentAssembly) {} |
Now the ConfigurationIntrospectionRule class is the one that actually handle the configuration file probing and create a System.Configuration.Configuration class that is passed in the Check method. Then, the Check override that does the actual process of loading the configuration file is the one that inspect the module and calls the implemented abstract Check override. The ConfigurationProbing function will try to get the config file from the current folder of the specified module (module.Directory) or from the parent folder in case of a web.config file, since this is typically copied to a temporary folder used in the prebuild process that is performed before the analysis process take place.
public abstract ProblemCollection Check(Configuration configuration); public override ProblemCollection Check(Microsoft.Cci.Module module) { Configuration configuration = ConfigurationProbing(module); if (configuration != null) { this.SourceFile = configuration.FilePath; return Check(configuration); } return base.Check(module); } |
Notice that if your rule just want to check any configuration section, you can just simple derive from this class and implement the Check(Configuration) method and do you analysis. But In our case, we only want to check the WCF configuration section (<system.serviceModel>) so we add an additional class that load this section and return a wrapper class that provides a handy way to interact with these sections. The ServiceModelConfigurationRule follow the same approach as the last class but in this case we get the ServiceModelConfigurationManager wrapper class.
public abstract ProblemCollection Check(ServiceModelConfigurationManager configurationManager); public override ProblemCollection Check(Configuration configuration) { if (configuration == null) { return base.Problems; } return this.Check(new ServiceModelConfigurationManager(configuration)); } |
Now an example of a rule implementation that checks if the attribute named 'certificateValidationMode' has a value other then 'ChainTrust'. This attribute is located in the clientCredentials/serviceCertificate section of the configuration file.
public override ProblemCollection Check(ServiceModelConfigurationManager configurationManager) { foreach (EndpointBehaviorElement behaviorElement in configurationManager.ServiceModelSection.Behaviors.EndpointBehaviors) { ClientCredentialsElement clientCredentials = ServiceModelConfigurationManager.GetBehaviorExtensionElement<ClientCredentialsElement> (behaviorElement); X509CertificateValidationMode validationMode = clientCredentials.ServiceCertificate.Authentication.CertificateValidationMode; if (validationMode != X509CertificateValidationMode.ChainTrust) { Resolution resolution = base.GetResolution(validationMode.ToString(), X509CertificateValidationMode.ChainTrust.ToString()); Problem problem = new Problem(resolution); problem.SourceFile = base.SourceFile; base.Problems.Add(problem); } } return base.Problems; } |
A simple unit test that will test this rule will be something like the following code:
[TestMethod] public void ShouldGetOneProblemWithRuleViolation() { UnTrustedServiceCertificateValidation rule = new UnTrustedServiceCertificateValidation(); Configuration configuration = ConfigurationLoader.LoadConfiguration ("UnTrustedServiceCertificateValidation.config"); ProblemCollection problems = rule.Check(configuration); Assert.IsNotNull(problems); Assert.AreEqual(1, problems.Count); } |
Along with the configuration checking rules we also added some code checking rules that use the standard pattern for writing custom FxCop rules (classes that derives form BaseControlFlowRule and BaseControlFlowRule bases classes).
Visual Studio Code Analysis Integration
We can add the rules assembly (WCFSecurityRules.dll located in project ‘WCF Security CodeAnalysis’) to the VS folder (\Program Files\Microsoft Visual Studio 8\Team Tools\Static Analysis Tools\FxCop\Rules) and then we get all the static analysis tool features in VS, like showed in the following figure:
Now you can test the rules from the option in Visual Studio right clicking on the specified project and selecting option “Run Code Analysis” or “Run Code Analysis on Web Site”. Or if you have the package, you can run with the following option:
Running the code analysis from the WCF Security Guidance Package will provide some other benefits like:
- Run only the WCF Security Rules so the Error List will filter any other code analysis rule.
- Analyze not only the selected project but all the rest of the project references.
- If a Web project does not contains any code on it (this is the case where all the code is in the references, like the sample generated with the WCF Guidance Package) the recipe will run the analysis without issue. The VS option will throw an error stating that there is no code for analysis.
The analysis results will be showed up as usual in the Error List window:
Before the final version of this project (Dec-06) you can expect to see more WCF security rules implemented with this strategy and more details about this as well. Hopefully this may be another tool for your SDL arsenal.
You can find the latest information regarding this project in the Web Service Software Factory Community Workspace or the Service Factory Blogs.
More information on using Code Analysis Tools here.