Search icon CANCEL
Arrow left icon
Explore Products
Best Sellers
New Releases
Books
Videos
Audiobooks
Learning Hub
Conferences
Free Learning
Arrow right icon
Arrow up icon
GO TO TOP
ASP.NET Core 5 Secure Coding Cookbook

You're reading from   ASP.NET Core 5 Secure Coding Cookbook Practical recipes for tackling vulnerabilities in your ASP.NET web applications

Arrow left icon
Product type Paperback
Published in Jul 2021
Publisher Packt
ISBN-13 9781801071567
Length 324 pages
Edition 1st Edition
Languages
Arrow right icon
Author (1):
Arrow left icon
Roman Canlas Roman Canlas
Author Profile Icon Roman Canlas
Roman Canlas
Arrow right icon
View More author details
Toc

Table of Contents (15) Chapters Close

Preface 1. Chapter 1: Secure Coding Fundamentals 2. Chapter 2: Injection Flaws FREE CHAPTER 3. Chapter 3: Broken Authentication 4. Chapter 4: Sensitive Data Exposure 5. Chapter 5: XML External Entities 6. Chapter 6: Broken Access Control 7. Chapter 7: Security Misconfiguration 8. Chapter 8: Cross-Site Scripting 9. Chapter 9: Insecure Deserialization 10. Chapter 10: Using Components with Known Vulnerabilities 11. Chapter 11: Insufficient Logging and Monitoring 12. Chapter 12: Miscellaneous Vulnerabilities 13. Chapter 13: Best Practices 14. Other Books You May Enjoy

Fixing command injection

Web applications such as the ones developed with ASP.NET Core have a plethora of components and libraries that enable them to execute OS commands in the host. If not written securely, the code that composes and runs these commands can likely expose the ASP.NET Core web application to command injection exploitation. Shell commands can be executed unexpectedly if this security flaw in code is not prevented.

In this recipe, we will identify the command injection vulnerability in code and fix the security vulnerability.

Getting ready

Using Visual Studio Code, open the sample Online Banking app folder at Chapter02\command-injection\before\OnlineBankingApp.

Testing command injection

Here are the steps:

  1. Navigate to Terminal | New Terminal in the menu or simply press Ctrl + Shift + ' in Visual Studio Code.
  2. Type the following command in the terminal to build and run the sample app:
    dotnet run
  3. Open a browser and go to http://localhost:5000/Backups/Create.
  4. The browser will display the web page for initiating database backup, as shown in the following screenshot:
    Figure 2.5 – Backup page

    Figure 2.5 – Backup page

  5. Enter this command injection payload, backup & calc, in the Backup Name field, and hit the Create button.
  6. Notice that the page redirected to the list of backup pages and the backup was created. However, the calculator app has appeared:
Figure 2.6 – Successful command injection

Figure 2.6 – Successful command injection

If this security bug is not handled, this problem could also expose the underlying hosts to Remote Code Execution (RCE).

How to do it…

Let's take a look at the steps for this recipe:

  1. Launch Visual Studio Code and open the starting exercise folder by typing the following command:
    code .
  2. Navigate to Terminal | New Terminal in the menu or simply press Ctrl + Shift + ' in Visual Studio Code.
  3. Type the following command in the terminal to build the sample app to confirm that there are no compilation errors:
    dotnet build
  4. Open the Services/BackupService.cs file and locate the vulnerable part of the code in the BackupDB(string backupname) method:
    public async Task BackupDB(string backupname)
    {
        using (Process p = new Process())
        {
            string source =             Environment.CurrentDirectory +                 "\\OnlineBank.db";
            string destination =            Environment.CurrentDirectory +                "\\backups\\" + backupname;
            p.StartInfo.Arguments =             " /c copy " + source + " " + destination;
            p.StartInfo.FileName = "cmd";
            p.StartInfo.CreateNoWindow = true;
    ...code removed for brevity
  5. To remediate the command injection vulnerability, add a new method that utilizes the built-in file copying function:
    public async Task FileCopyAsync(string sourceFileName,    string destinationFileName,     int bufferSize = 0x1000,     CancellationToken cancellationToken =         default(CancellationToken))
    {
        using (var sourceFile =         File.OpenRead(sourceFileName))
        {
            using (var destinationFile =            File.OpenWrite(destinationFileName))
            {
                await             sourceFile.CopyToAsync(destinationFile,                bufferSize, cancellationToken);
            }
        }
    }      
  6. Rewrite the entire body of the BackupDB method and use the newly created method:
    public async Task BackupDB(string backupname)
    {
        string source =         Environment.CurrentDirectory +             "\\OnlineBank.db";
        string destination =         Environment.CurrentDirectory + "\\backups\\"             + backupname;
        await FileCopyAsync(source, destination);
    }

We have refactored the BackUpDB method to use the FileCopyAsync method to limit your code to just perform file copying tasks, thereby preventing the execution of unwanted shell commands.

How it works…

In our sample solution, administrators are allowed to provide a name to create a database backup. The BackUpDB method accepts a user-controlled input parameter of the string type. The input string is used to form a command that will initiate a command shell to have files copied from the source to the destination.

The added input string is expected to have the destination filename, but this can be manipulated to include commands that are more than just a value for an argument. Without validation or sanitization, this could cause the application to execute unwanted shell commands under the web application's identity and authorization.

There's more…

One option of stopping OS command injection is to implement proper validation through the whitelisting technique. This technique can be achieved by using regular expressions (see the Input validation recipe in Chapter 1, Secure Coding Fundamentals):

  1. Add a reference to the System.Text.RegularExpressions namespace:
    using System.Text.RegularExpressions;
  2. Then, use the RegEx class and its IsMatch method to validate the input against a pattern to only accept valid characters:
    public async Task BackupDB(string backupname)
    {
        var regex = new Regex(@"^[a-zA-Z0-9]+$");
        if (!regex.IsMatch(backupname)) return;
        using (Process p = new Process())
        {
            string source =             Environment.CurrentDirectory +                "\\OnlineBank.db";
            string destination =             Environment.CurrentDirectory +                "\\backups\\" + backupname;
            p.StartInfo.Arguments = " /c copy " + source +             " " + destination;
            p.StartInfo.FileName = "cmd";
            p.StartInfo.CreateNoWindow = true;
    // code removed for brevity

We have now added a whitelisting validation with the use of the IsMatch method. The IsMatch method prevents non-alphanumeric characters and input from being processed in the succeeding lines of code, mitigating the risk of command injection.

You have been reading a chapter from
ASP.NET Core 5 Secure Coding Cookbook
Published in: Jul 2021
Publisher: Packt
ISBN-13: 9781801071567
Register for a free Packt account to unlock a world of extra content!
A free Packt account unlocks extra newsletters, articles, discounted offers, and much more. Start advancing your knowledge today.
Unlock this book and the full library FREE for 7 days
Get unlimited access to 7000+ expert-authored eBooks and videos courses covering every tech area you can think of
Renews at €18.99/month. Cancel anytime