Tuesday, June 25, 2019

FxCop on the beat

This blog makes heavy use of these web pages.
https://docs.microsoft.com/en-us/visualstudio/code-quality/install-fxcop-analyzers?view=vs-2019
https://docs.microsoft.com/en-us/visualstudio/code-quality/use-roslyn-analyzers?view=vs-2019
https://docs.microsoft.com/en-us/visualstudio/code-quality/fxcop-rule-port-status?view=vs-2019

I was talking to our security guy yesterday and discussing development tools that can aid in making applications more secure. He was telling me about a $50,000 tool he wanted to buy (that's the educational discount) and I was telling him about FxCop which is free and integrates into Visual Studio. It's from Microsoft, who have extensive experience in writing insecure code.

Let's focus on SQL Injection, which is one of my pet peeves. Until recently, I had a colleague who, despite having a Masters degree, still didn't understand the dangers of SQL Injection. Maybe I should have explained it to him by logging onto his educational system and entering my name as "';DROP TABLE Students;". Let's create a project that uses FxCop and break a few rules.

Create a new C# Console project called FxCop. I'm using Visual Studio 2019 and targeting Framework 4.6.2.

Once we have the project, we need to add FxCop.

  • Navigate Tools -> Nuget Package Manager -> Package Manager Console
  • In the Packet Manager Console execute "Install-Package Microsoft.CodeAnalysis.FxCopAnalyzers"

This installs some Analyzers which you can see if you expand the project's Dependencies node


Now let's go break some rules. I'm going to write a sub main that has two types of dependency injections - one via the command's constructor and one via the CommandText property. This will generate two different warnings.


using System.Data.SqlClient;

namespace FxCop
{
    class Program
    {
        static void Main(string[] args)
        {
            string SQL = "SELECT * FROM Person.person WHERE FirstName='" + args[0] + "'";
            using (SqlConnection oConn = new SqlConnection("SomeConnectionString"))
            {
                using (SqlCommand oComm = new SqlCommand(SQL, oConn))
                {
                    oComm.ExecuteScalar();
                }

                using (SqlCommand oComm = new SqlCommand())
                {
                    oComm.Connection = oConn;
                    oComm.CommandText = SQL;
                }
            }
        }
    }
}

In Visual Studio the underlined text looks more like this, but you get the idea.


The error list window shows the two warnings that FxCop has generated.


FxCop has detected that I'm about to assign a string of questionable provenance to the CommandText property of a SqlCommand. If someone chose to run this application with a parameter of ';DROP TABLE Person.person; I would have been hacked.

Reading through the list of rules that FxCop checks for, you start to realize how many attack vectors there are even in a simple application. SQL, XML, XAML, deserializers, process.start, HTML, XSLT, and many other technologies we commonly use can all be exploited.

Tuesday, June 18, 2019

MVVM Message Boxes through Dependency Injection

This blog is going to combine subjects from several recent blogs in a concrete example.

Pure MVVM does not allow the view-model to interact with the UI in any way. This also applies to message boxes. We often need to alert the user or get confirmation from them, but when automatically testing view-models we don't want those message boxes displayed because they cause the test to wait for user interaction. One approach, which unfortunately needs to be built in from the start, is to use dependency injection to specify which mechanism to use for interacting with the user.

You start by defining a MessageBox interface, then write a class that wraps the standard message box and another class that provides the same functionality without using a UI. Each view-model receives an instance of one of these two classes via its constructor (or a property or event) and executes the Show method when it needs to.

In this example, I have split the view-model away from the view's code-behind because it is purer than my usual technique of putting the view-model in the code-behind. Unfortunately it makes the example a lot more complex.

Start a new WPF C# project called "Message Box With Dependency Injection" and target framework 4.0 or later. I'm using Visual Studio 2019.

MainWindow contains two tabs. The first launches a user control. This is the user control we are going to test. The second tab contains a user control that tests the first user control. When we click the button on the first user control it does something and displays a confirmation and then an alert. When we click the button on the second user control it does the same thing, but we don't see the confirmation or alert. Instead the confirmation returns the default button and the alert is written to the output window. The difference is in the MessageBox class that we pass to the constructor (inject into the view-model).

Here is MainWindow.xaml. You do't need to modify MainWindow.xaml.cs

<Window x:Class="Message_Box_with_Dependency_Injection.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Message_Box_with_Dependency_Injection"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Window.Resources>
        <local:DoSomething x:Key="DoSomething"/>
        <local:TestSomething x:Key="TestSomething"/>
    </Window.Resources>
      <TabControl>
        <TabItem Header="A Window" Content="{StaticResource DoSomething}"/>
        <TabItem Header="Test the other Window" Content="{StaticResource TestSomething}"/>
    </TabControl>
</Window>


Before we go any further we need to define RelayCommand. This is needed because the CanExecute and Executed event handlers are in a separate class instead of the code-behind. This also means we have to define the relay commands in code, rather than defining RoutedCommands in XAML.

Add a class and call it RelayCommand. You can find this code in all WPF MVVM projects.

using System;
using System.Windows.Input;

namespace Message_Box_with_Dependency_Injection
{
    public class RelayCommand<T> : ICommand
    {
        readonly Action<T> _execute = null;
        readonly Predicate<T> _canExecute = null;

        public RelayCommand(Action<T> execute, object p)
            : this(execute, null)
        {
        }

        public RelayCommand(Action<T> execute, Predicate<T> canExecute)
        {
            if (execute == null)
                throw new ArgumentNullException("execute");

            _execute = execute;
            _canExecute = canExecute;
        }

        public bool CanExecute(object parameter)
        {
            return _canExecute == null ? true : _canExecute((T)parameter);
        }

        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }
            remove { CommandManager.RequerySuggested -= value; }
        }

        public void Execute(object parameter)
        {
            _execute((T)parameter);
        }
    }
}

Now we need to define our MessageBox interface and two implementations of it. Add a file called IMessageBox. It defines a single method called Show. I am not supporting the MessageBox icon parameter.

using System.Windows;

namespace Message_Box_with_Dependency_Injection
{
    interface IMessageBox
    {
         MessageBoxResult Show(string Text, string Title = "", MessageBoxButton buttons = MessageBoxButton.OK, MessageBoxResult defaultResult = MessageBoxResult.OK);
    }
}

Add a class called MyMessageBox which contains an implementation of IMessageBox that will act like a regular MessageBox.

using System.Windows;

namespace Message_Box_with_Dependency_Injection
{
    class MyMessageBox : IMessageBox
    {
        public  MessageBoxResult Show(string Text, string Title = "", MessageBoxButton buttons = MessageBoxButton.OK, MessageBoxResult defaultResult = MessageBoxResult.OK)
        {
            return MessageBox.Show(Text, Title, buttons, new MessageBoxImage(), defaultResult);
        }
    }
}

Also add a class called TestMessageBox which will contain an implementation of IMessageBox that is suitable for testing. It logs the text to the console and returns the default button.

using System;
using System.Windows;

namespace Message_Box_with_Dependency_Injection
{
    class TestMessageBox:IMessageBox
    {
        public MessageBoxResult Show(string Text, string Title = "", MessageBoxButton buttons = MessageBoxButton.OK, MessageBoxResult defaultResult = MessageBoxResult.OK)
        {
            Console.WriteLine(Text);
            return defaultResult;
        }
    }
}

Now we have to write the two user controls referenced by MainWindow. Let's start with DoSomething. This represents a complete Window, Page, or UserControl. In this example it's a huge button that executes a relay command. That command displays a confirmation and an alert. Add a new user control and call it DoSomething. The XAML looks like this. You don't have to modify the code-behind.

<UserControl x:Class="Message_Box_with_Dependency_Injection.DoSomething"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Message_Box_with_Dependency_Injection"
        mc:Ignorable="d">
    <UserControl.DataContext>
        <local:DoSomethingVM/>
    </UserControl.DataContext>
    <Grid>
        <Button Content="Do Something"  Command="{Binding DoSomethingCommand}"/>
    </Grid>
</UserControl>

Add a new class called DoSomethingVM. This is where we put the view-model for DoSomething. Note it has two constructors. The default constructor, which is what the framework will call, will use MyMessageBox to handle confirmations and alerts. The other constructor takes an explicit implementation of IMessageBox. The test page will use this second constructor to inject a reference to the TestMessageBox class.

using System.Windows;
using System.Windows.Controls;

namespace Message_Box_with_Dependency_Injection
{
    class DoSomethingVM : UserControl
    {
        IMessageBox theMessageBox;
        public DoSomethingVM()
        {
            theMessageBox = new MyMessageBox();
            DoInitialization();
        }

        public DoSomethingVM(IMessageBox MessageBox)
        {
            theMessageBox = MessageBox;
            DoInitialization();
        }

        private void DoInitialization()
        {
            DoSomethingCommand = new RelayCommand<object>(ExecuteDoSomething, true);
        }

        public RelayCommand<object> DoSomethingCommand
        {
            get;
            private set;
        }

        private void ExecuteDoSomething(object o)
        {
            MessageBoxResult result;
            result = theMessageBox.Show("Are you sure you want to do something?", "Confirm", MessageBoxButton.YesNo, MessageBoxResult.Yes);
            theMessageBox.Show("You clicked " + result.ToString());
        }
    }
}

Now we need to create the Test user control. This instantiates the view-model above using the second constructor, then executes the DoSomething command. The XAML looks like this. Note I'm being lazy here and putting the view-model in the code-behind.

<UserControl x:Class="Message_Box_with_Dependency_Injection.TestSomething"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Message_Box_with_Dependency_Injection"
        mc:Ignorable="d">
    <UserControl.Resources>
        <RoutedCommand x:Key="TestSomethingCommand"/>
    </UserControl.Resources>
    <UserControl.CommandBindings>
        <CommandBinding Command="{StaticResource TestSomethingCommand}" Executed="CommandBinding_Executed"/>
    </UserControl.CommandBindings>
    <Grid>
        <Button Content="Test Something" Command="{StaticResource TestSomethingCommand}"/>
    </Grid>
</UserControl>

The code-behind looks like this.

using System.Windows.Controls;
using System.Windows.Input;

namespace Message_Box_with_Dependency_Injection
{
    public partial class TestSomething : UserControl
    {
        IMessageBox MessageBox = new TestMessageBox();

        public TestSomething()
        {
            InitializeComponent();
        }

        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)
        {
            DoSomethingVM MV = new DoSomethingVM(MessageBox);
            MV.DoSomethingCommand.Execute(null);
        }
    }
}

If you click on the "Do Something" button you see the following message boxes.




If you move to the Test tab and click "Test Something" you don't see any message boxes but the Output window looks like this.


There's lots of fiddly bits in this project so I zipped it up here.