Puma Scan User Guide

The Puma Scan Professional Edition has many editions and configuration options that allow development teams to perform source code scans from Visual Studio, automated command line tasks, and build pipelines. Optimal performance and accuracy for an application is achieved by configuring the rules, editing tainted sources, and adding cleanse methods. The User Guide shows how to use and configure Puma Scan after completing the Installation Guide.

The following configuration features are available in the profession version only. Community edition users should visit the GitHub Repository to view, fork, and customize the source code directly.

Configuration

Puma Scan Professional allows custom configuration for all editions. The settings configuration allows users to configure the default scanner settings, rule options, custom tainted sources, custom cleanse methods, and suppress false positives.

Teams can start by customizing the global settings with the End User Edition. Global configuration options are located in the Settings.json file in the PumaSecurity roaming application data directory. We recommend storing customized global settings files in a secure backup location, such as a version control repository to ensure the global scanner configuration history is properly tracked.

On first analysis, the End User Edition creates an application-specific settings file (.pumafile) in the code repository with the defaults defined by the global configuration file. The .pumafile lives in the source control repository to enable historical tracking of all changes to the file. The .pumafile should be placed in the same directory as the solution file (.sln) being analyzed or in the root of the source control repository.

The Server and Azure DevOps Editions leverage the .pumafile stored in source control, along with the application source code, to configure Puma Scan in the build pipeline.

The following sections show the location of the settings files (Settings.json and .pumafile) and describe the schema in detail for development and security teams to customize Puma Scan.

Global Settings File

End User Edition Settings

The End User Edition creates the global machine Settings.json file with the default settings during the analysis of the first solution. To generate this file:

  • Install the Puma Scan Visual Studio extension
  • Open a solution or project to analyze
  • Open Windows explorer and browse to the file location shown in Figure 1.


Server Edition Settings

The Server Edition’s installer creates the global machine Settings.json file during the installation. After completing the installation wizard, open Windows explorer and browse to the file location shown in Figure 1.


Azure DevOps Edition Settings

The Azure DevOps Edition is installed and executed on an ephemeral cloud hosted agent. No global machine Settings.json file exists. See the Azure DevOps User Guide for details on passing the path to the application-specific .pumafile to the Puma Scan build task.


Default Settings

Engineers can also view and download a sample default settings file to get started.

 

Figure 1: The End User and Server Edition’s global machine Settings.json file can be found in the following directory.

%appdata%\PumaSecurity\PumaScan

Local Settings File

On first analysis, individual applications will have the default global settings copied to a new .pumafile in the source control repository. The .pumafile should be committed to source control to ensure the Puma Scan configuration is consistent between between developer workstations, on-premise build servers, and Azure DevOps pipelines.

The .pumafile can be stored in the root of the source control repository or same directory as the solution file (.sln) being analyzed (if different). Figure 2 shows Puma Prey repository’s local .pumafile stored in the root.

 

Figure 2: The following screenshot shows the Puma Prey repository with a .pumafile in the root directory.

General Settings

The GeneralSettings section of the Settings.json file contains global options that affect how the scanner works. Puma Scan supports the following general configuration options:

DataflowAnalysisEnabled

Puma Scan Professional performs data flow analysis in many analyzers to determine if the source of an input comes from an untrusted source (e.g. request parameter, web service API, etc.). This setting turns the data flow feature on (true) or off (false). If you are experiencing performance issues with Puma Scan, disabling this feature will improve performance. However, more false positives will occur. The default value is true.

DataflowAnalysisReportIndeterminates

Puma Scan Professional performs data flow analysis in many analyzers to determine if the source of an input comes from an untrusted source (e.g. request parameter, web service API, etc.). In some cases, the data flow analyzer may be unable to perform a complete trace and cannot confidently determine if a vulnerability exists. These sinks are marked as indeterminate. This setting tells the scanner if indeterminate issues should be reported in the scan results (true) or be suppressed by the scanner (false). The default is false.

ProductionConfigurationTransform

Puma Scan Professional will perform a web.config transformation prior to running configuration analysis if a transform file exists. This setting tells the analyzer which configuration transform file you would like to use for analysis. For example, if your configuration transform is called “Web.Production.config”, then you should change this setting to “Production”. The default value is “Release”, which tells the analyzers to look for a file called “Web.Release.config”.

LogLevel

Puma Scan writes log events to the %localappdata%\PumaSecurity\PumaScan directory on the local machine.

The LogLevel value controls the level of detail written to the log file. The default value is Error.

  • Error: Error messages and exception details.
  • Info: Information messages, which are normally enabled in production environment.
  • Debug: Debugging information typically not enabled in production environment.
  • Trace: Very detailed logs, which may include high-volume information. This log level is typically only enabled during development.

 

The following JSON block shows the log level and general setting options:

"GeneralSettings": {
    "DataflowAnalysisEnabled": true,
    "DataflowAnalysisReportIndeterminates": false,
    "ProductionConfigurationTransform": "Release"
},
"LogLevel": "None"

Rule Options: General

Each analysis rule (e.g. SEC0001) is configurable in the RuleOptions list. All analysis rules have the following options:

Id

Read only field that describes the rule identifer the attributes will affect.

Name

Read only field that describes the rule name the attributes will affect.

RiskRating

Sets a risk rating for the rule. The risk rating is displayed in the detailed diagnostic message and used in downstream Puma Scan reports. Options include High, Medium, or Low. The default risk rating is determined per rule by Puma Security application security engineers.

Severity

Sets the build severity for the rule. This setting allows diagnostics to be raised as diagnostics in the Error List Window as an Error, Warning, or Info item. It is important to realize that using the “Error” option will cause the build to break.

Valid options include Error, Warning, or Info. The default severity for all rules in Warning.

Enabled

Turns an analysis rule on (true) or off (false). The default is true.

 

The following example shows the default configuration options that exist for all rules.

"RuleOptions": [
    {
        "Id": "SEC0001",
        "Name": "Debug Build Enabled",
        "RiskRating": "Low",
        "Severity": "Warning",
        "Enabled": true
    },
    ...
]

Rule Options: SEC0007

SEC0007 has an additional option allowing users to configure their forms authentication timeout policy.

TimeoutMax

Defines the maximum forms authentication timeout value (in minutes). The default value is 30.

 

The following example shows the SEC0007 TimeoutMax option for configuration a custom timeout.

{
    "Id": "SEC0007",
    "TimeoutMax": 30,
    "Enabled": true
},

Rule Options: SEC0017

SEC0017 has additional options allowing users to configure a custom password policy.

Length

Defines the minimum number of characters to require for the password length. The default value is 10.

RequireNumber

Indicates if the password complexity should require a numeric character. The default value is true.

RequireLowerCase

Indicates if the password complexity should require a lower case character. The default value is true.

RequireUpperCase

Indicates if the password complexity should require an upper case character. The default value is true.

RequireSpecialCharacter

Indicates if the password complexity should require a special character. The default value is true.

 

The following example shows the SEC0017 password configuration options.

{
    "Id": "SEC0017",
    "Length": 10,
    "RequireNumber": true,
    "RequireLowerCase": true,
    "RequireUpperCase": true,
    "RequireSpecialCharacter": true,
    "Enabled": true
},

Rule Options: SEC0020

SEC0020 has an additional option allowing users to configure their session state timeout policy.

TimeoutMax

Defines the maximum session state timeout value (in minutes). The default value is 30.

 

The following example shows the SEC0020 timeout configuration option.

{
   "Id": "SEC0020",
   "TimeoutMax": 30,
   "Enabled": true
},

Suppressing False Positives

Security analysts and engineers can suppress false positives in the Exceptions list. To support flexibility and allow security teams to closely audit exception entries, a number of options are available:

RuleIds

The RuleIds array limits the exception to specific rule ids. The bottom example on the right shows how to limit the exception to rule id SEC0032. The default value is an empty array (e.g. []), which means the exception will apply to all diagnostic rules.

Path

Relative path to the file containing the code to ignore. Wildcards (*) and single character matches (?) are supported. This field is required. Valid examples include:

  • app\* (Ignores all Puma Scan findings from files in the app directory)
  • tests\api\* (Ignores all Puma Scan findings from files in the tests\api directory)
  • app\web\file.?? (Ignores all Puma Scan findings in files starting with app\web\file.)


StartLine

Starting line number in the file that contains the code to ignore. Wildcard (*) is supported. The default is wildcard (*).

EndLine

End line number in the file that contains the code to ignore. Wildcard (*) is supported. The default is wildcard (*).

Checksum

SHA256 checksum (hex encoded) of the line(s) of code to ignore. Setting this value creates a valid exception based on the current code. If the line of code changes, the exception is no longer valid and the checksum must be recalculated after reviewing the code changes. This field is optional and defaults to empty.

The checksum property is experimental at this time. Generating the checksum is currently a manual process. We recommend using CyberChef to generate the SHA256 checksum value.

ApprovedBy

Username of the lead engineer or security analyst approving the exception. This field is optional and defaults to empty.

Reason

Justification from the lead engineer or security analyst for approving the exception. This field is optional and defaults to empty.

Timestamp

Timestamp the lead engineer or security analyst approves the exception. JSON formated timestamps are required. This field is optional and defaults to empty.

 

The following example shows an exception that suppresses all Puma Scan warnings raised from all files (*) in the test directory.

"Exceptions": [
    {
       "Path": "test\\*",
       "ApprovedBy": "Eric Johnson",
       "Reason": "Test directory is not deployed to live environments.",
       "Timestamp": "2018-10-25T22:27:58.6444584Z"
    }
]

The following example shows an exception that suppresses SEC0032 diagnostics raised in the AuthenticationController class on line 14 if the checksum of the line matches a specific value.

"Exceptions": [
    {
        "RuleIds": [
            "SEC0032"
        ],
        "Path": "src\\api\\Authentication\\AuthenticationController.cs",
        "StartLine": "14",
        "EndLine": "14",
        "Checksum": "9bf1d66c0e0764bb2179efc0a8f085de99200b441f2ace2a7ba8b78e113ba491",
        "ApprovedBy": "Eric Johnson",
        "Reason": "Request parameter is passed through strict validation routines before being passed to the process start argument.",
        "Timestamp": "2018-10-25T22:27:58.6444584Z"
    }
]

Server Edition

Puma Scan Server Edition provides a command line interface for executing the Puma Scan security analyzers. The Server Edition installation adds PumaScan.exe to the Windows PATH, which can be invoked from cmd.exe and PowerShell prompts.

Command Line Options

To get started, first run the PumaScan.exe --help command to view the options screen:

--project (-p)

Full path to the solution (.sln) or project (.csproj) file to analyze. Argument is required. Examples:

  • C:\code\puma-prey\PumaPrey.sln
  • C:\code\puma-prey\Fox\Fox.csproj

--settings (-s)

Full path to the Puma Scan configuration settings file to use for the scan (e.g. Settings.json or repository specific .pumafile). Argument is required. Example:

  • C:\code\puma-prey.pumafile

--format (-f)

Comma delimited list of export formats for the generated scan results. Options include json, html, msbuild, and vso. Each file will be written to the output directory specified by the --output switch. Argument is required.

--output (-o)

Output file path and name for the generated scan results. The file extension will automatically be added for each file format specified by the --format switch. Argument is required.

--verbose (-v)

True / false value that enables verbose scan diagnostic data to be written to the console during analysis. Argument is not required. The default is false.

In VSTS / Azure DevOps builds, enabling the Verbose flag and the VSO (Visual Studio Online) output formats allows Puma Scan to add security warnings to the MSBuild results summary. WARNING: An Azure DevOps limitation shows only the first 11 warnings. More details can be found in the Azure Forum #187596.

--threshold-high

Sets a threshold on the allowable number of high risk results before the build task fails. For example, setting the value to 10 would stop the build if more than 10 high risk scan results are found during analysis. Argument is optional. The default value is empty string.

--threshold-medium

Sets a threshold on the allowable number of medium risk results before the build task fails. For example, setting the value to 10 would stop the build if more than 10 medium risk scan results are found during analysis. Argument is optional. The default value is empty string.

--threshold-low

Sets a threshold on the allowable number of low risk results before the build task fails. For example, setting the value to 10 would stop the build if more than 10 low risk scan results are found during analysis. Argument is optional. The default value is empty string.

--version

Displays the Puma Scan version information.

--help

Displays the help text screen.

 

The following example shows the Server Edition command line options using the --help switch.

Command Line Example

The image on the right shows an example command to execute the Puma Scan Server Edition.

Command Arguments

  • -p: C:\code\puma-prey\PumaPrey.sln
  • -s: C:\code\puma-prey\.pumafile
  • -f: json,html
  • -o: C:\code\puma-prey\PumaScan-Results
  • --threshold-high: 5

Puma Scan Results

The console output from the scan shows details as the scan executes.

Project Summary
Shows details about the given solution or project file including the location on disk, number of projects, and number of documents to be included in the scan.

Scan Summary
Displays details about the Puma Scan analysis:

  • The location on disk of the scan settings file used for the analysis (Settings.json or .pumafile).
  • The Puma Scan engine version for tracking scan result trends over time.
  • Total number of security diagnostic warnings grouped by rule id.
  • Total number of security diagnostic warnings grouped by risk severity.

Output Summary
Shows the output files generated for the scan results and the location on disk.

Threshold Validation
Shows details for any threshold comparisons made against the scan results. In this example, a value of 5 was given for the --threshold-high parameter. The output shows the threshold verification failed because 9 high risk findings were identified.

Exit Code
Puma Scan will exit with an exit code of Success (0) if the scan completes successfully with no errors and the threshold verification step passes all criteria.

  • 0: Success
  • 1: InvalidArguments
  • 2: InvalidSolutionFile
  • 3: InvalidSettingsFile
  • 4: ScanError
  • 5: InvalidLicense
  • 6: ThresholdHigh
  • 7: ThresholdMedium
  • 8: ThresholdLow
  • 100: UnknownError

 

The following code snippet shows an example command scanning the Puma Prey solution.

PumaScan.exe -p "C:\code\puma-prey\PumaPrey.sln" -s "C:\code\puma-prey\.pumafile" -f json,html -o "C:\code\puma-prey\PumaScan-Results" --threshold-high 5

The following screenshot shows the output from the code analysis.

Azure DevOps (On-Premise)

Integrating the Puma Scan Professional Server Edition into Azure DevOps on-premise (formerly VSTS) build pipelines requires DevSecOps teams to add two new build tasks.

Command Line Task

Start by adding a new Command Line build task (Figure 1) to the pipeline. Then, configure the task to execute the Puma Scan Server Edition. The following fields must be set to successfully execute a scan (Figure 2):

Display Name
Enter a self describing name for the build task, such as Puma Scan. This value is displayed in the pipeline’s web interface as each task executes.

Tool
Enter the full path to where PumaScan.exe is installed on the build agent. This should match the directory selected when installing the Puma Scan Server Edition. For on-premise VSTS installations, consider installing Puma Scan in the C:\TfsBuildAgent\externals directory.

Arguments
Set the command line options required to run Puma Scan. Figure 2 shows a scan instructing Puma Scan to scan the PumaPrey-Scan.sln solution with the settings in the .pumafile, export the findings to HTML and JSON formats, store the results in the PumaResults directory, and fail the build if there are more than 5 high risk findings. See the Command Line Options for more details:

  • -p: $(Build.Repository.LocalPath)\src\PumaPrey-Scan.sln
  • -s: $(Build.Repository.LocalPath).pumafile
  • -f: html,json
  • -o: $(Build.Repository.LocalPath)\PumaResults\PumaScan
  • --threshold-high: 5


Publish Artifact Task

To archive the Puma Scan reports stored in the PumaResults directory, add a new Publish Build Artifacts build task (Figure 3) to the pipeline. Then, configure the task to store the Puma Scan reports on the build server. The following fields must be set to successfully store the reports (Figure 4):

Display Name
Enter a self describing name for the build task, such as Puma Scan Publish. This value is displayed in the pipeline’s web interface as each task executes.

Path to Publish
Enter the directory containing the Puma Scan reports. This directory should match the directory used in the --output (-o) command line argument. Continuing the example above, this field would be set to $(Build.Repository.LocalPath)\PumaResults.

Artifact Name
Enter a self describing name for the Puma Scan artifacts, such as Puma Scan. This is an arbitrary value that will be displayed on the Artifact Summary screen after the build completes.

Artifact Type
Select Server to store the artifacts in the web directory. Select File to access the files directly from the file system.

Run this task
Set this value to Even if a previous task has failed, unless the build was canceled to ensure the Puma Scan reports are archived even if the Puma Scan task fails due to threshold violations.







Puma Scan Build Summary

After the build completes, select the Puma Scan task to view the execution logs (Figure 5). The console output will display the project summary, scan summary, output summary, threshold violations, and exit code details.

Continuing the example above, the Puma Scan task displays a red X indicating that the task failed. The task is failing because the Puma Prey application contains more than 5 high risk findings, which exceeds the high threshold value. A successful code scan will produce a green check and allow the build pipeline to proceed through the remaining tasks.

See the Command Line Example for more details on the console output.









Build Artifacts

To view the Puma Scan reports (Figure 6):

1) Select the Build Id (e.g. Build 20190225.6) to view the Summary screen.

2) Select the Artifacts tab to view any files archived by the pipeline.

3) Press the Explore button to download and view the Puma Scan reports.

















Artifact Explorer

Use the Artifact Explorer to download and view the Puma Scan reports (Figure 7). In the example above, the --format (-f) switch was set to html,json, which instructs Puma Scan to create both .html and .json formatted files to be stored in the build archives.

 

Figure 1: Add a new Command Line build task to the pipeline.

Figure 2: Configure the Command Line build task to run Puma Scan.

Figure 3: Add a new Publish Build Artifacts build task to the pipeline.

Figure 4: Configure the Publish Build Artifacts build task to archive the Puma Scan results.

Figure 5: After the build completes, select the Puma Scan build task to view the execution logs.

Figure 6: Select the Build Id and view the Artifacts tab.

Figure 7: Explore and download the Puma Scan reports.

Jenkins Integration

Jenkins Freestyle Job

Documentation coming soon.

Jenkins Declarative Syntax

Documentation coming soon.

 

Azure DevOps Edition

Puma Scan Azure DevOps Edition is an extension for Azure DevOps Build and Release pipelines. After installing the Puma Scan extension in an Azure DevOps organization, DevOps teams can perform secure code analysis inside cloud-hosted build pipelines.

NOTE: The Azure DevOps extension is not supported for on-premise Azure DevOps (VSTS) hosted build agents. See the Azure DevOps (On-Premise) Integration for details on configuring the Server Edition for hosted agents.

The following settings are available when configuring the Azure DevOps Puma Scan build task.

Build Task Settings

Path to Solution File

Relative path to the solution or project file to analyze. For example, MyApplication.sln or MyProject.csproj.

Path to Settings File

Relative path to the Puma Scan settings file (.pumafile) in the code repository. The field is optional and the default is empty, which runs Puma Scan with the default settings.

Puma Scan License

The Puma Scan Professional Azure DevOps license can be obtained from pumascan.com. Store the value in an encrypted pipeline variable. Then, reference the variable name in the build step. The default variable name is $(PumaLicense).

Scan Results Format

Select the export formats for the generated scan results: json, html, or msbuild. Each file will be uploaded to the build archives.

Output File Name

Output file name for the generated scan results [MyApplication-PumaScan]. The file extension will automatically be added for each selected scan results format. All output files will automatically be added as build artifact.

Verbose

True / false value that enables verbose scan diagnostic data to be written to the console during analysis.

Threshold High

Sets a threshold on the allowable number of high risk results before the build task fails. For example, setting the value to 10 would stop the build if more than 10 high risk scan results are found during analysis.

Threshold Medium

Sets a threshold on the allowable number of medium risk results before the build task fails. For example, setting the value to 10 would stop the build if more than 10 medium risk scan results are found during analysis.

Threshold Low

Sets a threshold on the allowable number of low risk results before the build task fails. For example, setting the value to 10 would stop the build if more than 10 low risk scan results are found during analysis.

 

The following example shows a build task with example settings.

The following example shows how to set the PumaLicense pipeline variable.

The following example shows how to view the Puma Scan build artifacts.

The following example shows how to view the Puma Scan result details.

Tainted Sources

The Puma Scan Professional Edition scanner performs data flow analysis from data entering a vulnerable sink to the original source of the data. For rules performing data flow analysis, the source type (e.g. request parameter) ultimately determines if a diagnostic is raised by the scanner. The following documentation provides a list of the sources automatically built into the scanner and examples showing how to create custom tainted sources.

Default Tainted Sources

The following tainted sources are built into the scanner out of the box:

Web

  • System.Web.HttpRequest
  • System.Web.UI.Page.Request
  • System.Web.UI.WebControls
  • System.Web.UI.HtmlControls
  • System.Web.Mvc.Controller
  • Microsoft.AspNetCore.Mvc.Controller
  • Microsoft.AspNetCore.Http.Request

Web Service

  • System.ServiceModel.ClientBase
  • System.Web.Services.Protocols.SoapHttpClientProtocol
  • System.Net.Http.HttpClient
  • System.Web.Http.ApiController
  • Microsoft.AspNetCore.Mvc.Controller

Database

  • System.Data.SqlClient.SqlDataReader
  • System.Data.Linq.DataContext
  • System.Data.Entity.DbContext
  • Microsoft.EntityFrameworkCore.DbContext

 

The following example shows a default tainted source that flags all data coming from the System.Web.HttpRequest object as tainted.

{
    "RuleIds": [],
    "Flag": "Web",
    "Syntax": "ElementAccessExpressionSyntax",
    "Namespace": "System.Web",
    "Type": "HttpRequest",
    "Property": "this[]",
    "Method": "*"
}

The following example shows a default tainted source that flags all methods (including the parameters) in classes inheriting from System.Web.Mvc.Controller as tainted.

{
    "RuleIds": [],
    "Flag": "Web",
    "Syntax": "SimpleBaseTypeSyntax",
    "Namespace": "System.Web.Mvc",
    "Type": "Controller",
    "Property": "*",
    "Method": "*"
}

Custom Tainted Sources

The Puma Scan Professional Edition allows users to define custom tainted sources to help identify third party or custom entry points that should be marked as tainted. Common examples include third party frameworks that accept user request data or libraries that retrieve external data from web service APIs.

Custom Tainted Source Schema

The following section describes the schema for adding custom tainted sources to the scanner:

RuleIds

The RuleIds array limits the custom tainted source to a set rule id or ids. The example to the right shows how to limit the custom source to only rule id SEC0106, SEC0107, and SEC0108. The default value is an empty array (e.g. []), which means the new tainted source will apply to all diagnostic rules.

Flag

Logical grouping to help define the custom tainted source. This field is not required for the analyzers to pick up additional sources. Valid options are as follows:

  • None
  • Web
  • Service
  • Database

The default is None.

Syntax

The dotnet compiler API represents the different syntax nodes nodes in a syntax tree with classes inside the Microsoft.CodeAnalysis namespace. This property is required to be set to the appropriate syntax type to register the new custom source with the scanner. For more information on how to locate the correct syntax type, please see Syntax Visualizer section.

Namespace

The namespace containing the custom tainted sources. In the Telerik example to the right, the namespace containing the object to add to the tainted sources list is Telerik.Web.UI. This field is required.

Type

Filters the tainted source in a namespace down to an individual object type. This could also be referred to as the class name. In the example to the right, the tainted sources in the Telerik.Web.UI namespace is filtered down to only instances coming from the RadAutoCompleteBox type. This field is required and supports the wildcard character (*) to tell the scanner to taint all types in a given namespace.

Property

Filters the tainted source in an object down to a specific property (getter / setter). In the example to the right, the tainted source will only come from the “Text” property, which will contain user supplied input. This field is required and supports the wildcard character (*). If identifying a method only (see below), set this field to the wildcard character (*).

Method

Filters the tainted source in an object down to a specific method. This attribute can be used independently of the property field above (e.g., Object.DoSomething()). Or in combination with the property field above to filter a property down to the getter (e.g., “get”) or setter (e.g., “set”). In the example to the right, the tainted source will only come from the “get” method called on the “Text” property. This field is required and supports the wildcard character (*).

 

The following example shows how to create a new tainted source identifying unsafe data coming from the third party Telerik RadAutoCompleteBox control.

{
    "RuleIds": ["SEC0106", "SEC0107", "SEC0108"],
    "Flag": "Web",
    "Syntax": "ElementAccessExpressionSyntax",
    "Namespace": "Telerik.Web.UI",
    "Type": "RadAutoCompleteBox",
    "Property": "Text",
    "Method": "get"
}

Custom Tainted Source Example

Let’s walk through an example showing how to create a custom tainted source. Consider the code snippet to the right. In this example, the GenerateReport method reads a Report from a shared library and passes the data into a vulnerable Entity Framework query. Should this code block raise a SQL Injection warning? Well, it depends on the source of the report.Name data element.

Let’s assume that the Report library is an internal DLL and we don’t have the source code. Puma Scan’s source code analyzer is unable to trace calls into reference DLLs (aka third party libraries) to determine the source of the report data. By default, no warning will be raised.

In cases like this, you need to tell the source code analyzer if specific properties or methods in external libraries should be treated as unsafe (e.g., tainted).

 

The following example shows the GenerateReport GET request action reading a user’s report data and using the Name field to construct a SQL query. While it is obviously vulnerable to SQL Injection, exploiting the issue depends on the source of the Name value.

[HttpGet]
public ActionResult GenerateReport()
{
    //Get report data for the current user
    Guid userId = new Guid(User.Identity.GetUserId());
    Report report = Report.GetReport(userId);

    //Mark the report as generated
    using (var context = new RabbitDBContext())
    {
            string query = string.Format("UPDATE Report SET Status = 1 WHERE Name = {0}", report.Name);
            context.Database.ExecuteSqlCommand(query);
    }

    //Return report data to the view
    return View(report);
}

.NET Compiler SDK

To do this, ensure you have installed the .NET Compiler Platform SDK.

Visual Studio 2017

In Visual Studio 2017, run the Visual Studio Installer, press “Modify”, and browse to “Individual Components > Compilers, Build Tools, and Runtimes”. Select and install the “.NET Compiler Platform SDK” (shown to the right in Figure 3).

Visual Studio 2015

In Visual Studio 2015, this is a Visual Studio Extension available in the Visual Studio Marketplace.

 

Figure 3: Visual Studio 2017 - Adding the Compiler SDK option

Syntax Visualizer

Using the Syntax Visualizer, inspect the tainted source code and identify the syntax type of the custom source. To do this:

  • Open the View > Other Windows > Syntax Visualizer window.
  • Open the document containing the new custom source
  • Highlight the line of code and observe Syntax Visualizer filling in the details
  • Note the Syntax Type (highlighted in red in Figure 4)

In this example, the syntax type is the InvocationExpressionSyntax, which should be entered for new the custom source’s Syntax property.
Next, use the Syntax Visualizer to locate the Namespace, Type, Property, and Method values (highlighted to the right in Figure 5). To locate these values, right click the node in the Syntax Tree and select “View Symbol”. The following properties will provide the remaining fields:

  • Namespace: The ContainingNamespace property will indicate the namespace.
  • Type: The ContainingType property will list the fully qualified type. Use the type name in the last position.
  • Property: The Kind property will guide this value. If the Kind is a Method, then this attribute does not matter. Just enter a wildcard (*) and move on. If the Kind is a Property, then the *Name property will tell you the value to enter.
  • Method: The Kind property will guide this value. If the Kind is a Property, then enter one of the following values: Wildcard (*), “get”, or “set”. If the Kind is a Method, then the Name property will tell you the name of the method.

More details on using the Syntax Visualizer can be found in the Roslyn Documentation.

 

Figure 4: Syntax Visualizer - Finding the Syntax Type*

Figure 5: Syntax Visualizer - Symbol Properties*

Adding A New Tainted Source

Finally, let’s add the new tainted source identifying the Puma.Prey.Common.Report.GetReport method as unsafe.

  • Open the Settings.json file and locate the CustomTaintedSources array.
  • Add a new array and set the required properties.
  • Using the data gathered above in the Syntax Visualizer, enter the values shown in the code snippet shown to the right.
  • Save the Settings.json file
  • Restart Visual Studio for the changes to take effect.

 

The following example shows the new custom tainted source to identify the Puma.Prey.Common.Report.GetReport method as a tainted source.

"CustomTaintedSources": [
    {
        "RuleIds": [] ,
        "Flag": "Web",
        "Syntax": "InvocationExpressionSyntax",
        "Namespace": "Puma.Prey.Common",
        "Type": "Report",
        "Property": "*",
        "Method": "GetReport"
    }
]

Cleanse Methods

The Puma Scan Professional Edition performs data flow analysis from data entering a vulnerable sink back to the original source of the data. For rules performing data flow analysis, data passing through a valid cleanse method will suppress the diagnostic warning. The following documentation provides a list of cleanse methods built into the scanner and examples showing how to create custom cleanse methods.

Default Cleanse Methods

The following cleanse methods are built into the scanner out of the box to suppress diagnostics related to injection vulnerabilities:

Data Types

  • System.Decimal
  • System.Double
  • System.DateTime
  • System.DateTimeOffset
  • System.Int16
  • System.Int32
  • System.Int64
  • System.Guid

Internal Methods

  • System.Convert.ToBoolean
  • System.Convert.ToDateTime
  • System.Convert.ToDecimal
  • System.Convert.ToDouble
  • System.Convert.ToInt16
  • System.Convert.ToInt32
  • System.Convert.ToInt64
  • System.Convert.ToUInt32
  • System.Convert.ToUInt32

Cross-Site Scripting Cleanse Methods

Cross-site Scripting rules (SEC0024, SEC0100, SEC0101, SEC0102, SEC0103, SEC0104, SEC0105) will suppress tainted sources passing through the following methods:

  • Microsoft.Security.Application.Encoder.HtmlEncode
  • System.Web.HttpServerUtility.HtmlEncode
  • System.Text.Encodings.Web.HtmlEncoder.Encode
  • System.Text.Encodings.Web.JavaScriptEncoder.Encode
  • System.Text.Encodings.Web.UrlEncoder.Encode

LDAP Injection Cleanse Methods

LDAP Injection rules (SEC0014) will suppress tainted sources passing through the following methods:

  • Microsoft.Security.Application.LdapFilterEncode
  • Microsoft.Security.Application.LdapDistinguishedNameEncode

Unvalidated Redirect Cleanse Methods

Unvalidated redirect rules (SEC0109, SEC0110) will suppress tainted sources passing through the following methods:

  • System.Web.Mvc.IsLocalUrl
  • System.Uri.TryCreate
  • Microsoft.AspNetCore.Mvc.UrlHelper.IsLocalUrl

 

The following example shows a custom cleanse method that will cleanse XSS tainted source data before raising a diagnostic in cross-scripting rules. The configuration marks data passing through an InvocationExpressionSyntax in the System.Web.Security.AntiXss.AntiXssEncoder.HtmlEncode method as safe.

{
    "RuleIds": ["SEC0024", "SEC0100", "SEC0101", "SEC0102", "SEC0103", "SEC0104", "SEC0105"],
    "Flag": "Web",
    "Syntax": "InvocationExpressionSyntax",
    "Namespace": "System.Web.Security.AntiXss",
    "Type": "AntiXssEncoder",
    "Method": "HtmlEncode"
},

Custom Cleanse Methods

The Puma Scan Professional Edition allows users to define custom cleanse methods to identify security controls within the application and eliminate false positives. Common examples include validation routines and encoding libraries.

Custom Cleanse Method Schema


RuleIds

The RuleIds array limits the custom cleanse methods to a set rule id or ids. The example to the right shows how to limit the custom source to only rule id SEC0024. The default value is an empty array (e.g. []), which means the new cleanse method will apply to all diagnostic rules.

Flag

Logical grouping to help define the custom cleanse methods. This field is not required for the analyzers to pick up new cleanse methods. Valid options are as follows:

  • None
  • Web
  • Service
  • Database

The default is None.

Syntax

The dotnet compiler API represents the different syntax nodes nodes in a syntax tree with classes inside the Microsoft.CodeAnalysis namespace. This property is required to be set to the appropriate syntax type to register the new cleanse method with the scanner. For more information on how to locate the correct syntax type for a given method, please see Syntax Visualizer section.

Namespace

The namespace containing the cleanse method. In the example to the right, the namespace containing the cleanse method is is Microsoft.Security.Application. This field is required.

Type

Filters the cleanse methods in a namespace down to an individual object type. This could also be referred to as the class name. In the example to the right, the class containing the cleanse method in the Microsoft.Security.Application namespace is filtered down to the Encoder class type. This field is required and supports the wildcard character (*) to register all classes in the namespace.

Method

Filters the cleanse method in an class to a specific method name. In the example to the right, the cleanse method is set to HtmlEncode. This field is required and supports the wildcard character (*).

 

The following example shows a custom cleanse method that will cleanse XSS tainted source data before raising a diagnostic in SEC0024. The configuration marks data passing through an InvocationExpressionSyntax in the Microsoft.Security.Application.Encoder.HtmlEncode method as safe.

{
    "RuleIds": ["SEC0024"],
    "Flag": "Web",
    "Syntax": "InvocationExpressionSyntax",
    "Namespace": "Microsoft.Security.Application",
    "Type": "Encoder",
    "Method": "HtmlEncode"
},

Custom Cleanse Method Example

Prerequisites

To create a custom cleanse method, ensure you have done the following:


Adding A New Cleanse Method

Let’s walk through an example showing how to create a custom cleanse method. Consider the code snippet to the right. In this example, the Download method accepts a request parameter called fileName that is eventually concatenated into a file path used to download a file from the file system. Should this code block raise a path tampering vulnerability? Well, it depends on the effectiveness of the Validator.IsValidFilePath method.

During our code review, we determine that the Validator.IsValidFilePath method is using strong whitelist validation to restrict input to alphanumeric characters. But, the Puma Scan analyzer is raising a diagnostic warning because this method is not registered as a valid cleanse method.

In cases like this, you need to tell the source code analyzer that the custom cleanse method mitigates the vulnerability. Doing so will suppress the diagnostic warning if a tainted source passes through the cleanse method.

Let’s add the new cleanse method and prevent the path tampering false positive. To do this:

  • Open the Settings.json file and locate the CustomCleanseMethods array.
  • Use the Syntax Visualizer to find the syntax type of the cleanse method.
  • Fill in the appropriate fields. The example is shown in the snippet to the right and described below.
  • Save the Settings.json file and restart Visual Studio for the changes to take effect.


RuleIds

The path tampering false positive is from rule id SEC0111. As shown in the configuration to the right, add “SEC0111” to the RuleIds array.

Flag

This flag can help with grouping and querying the cleanse methods. In this case, because the cleanse method is in a web entry point, we can set the value to “Web”. You can set this to “None” if you do not want to use this field.

Syntax

Using the Syntax Visualizer, we identified that the invocation of the cleanse method is a InvocationExpressionSyntax type.

Namespace

The namespace containing the path tampering validation method is Puma.Prey.Common.Validation.

Type

The type / class name is Validator.

Method

The cleanse method is called IsValidFilePath.

 

The following code example shows a download method accepting a fileName request parameter, which is then validated by a custom method called Validator.IsValidFilePath.

[HttpPost]
public ActionResult Download(string fileName)
{
    if (!Validator.IsValidFilePath(fileName))
        return new HttpNotFoundResult();

    return new FilePathResult("C:\\temp\\downloads\\" + fileName, "application/octet-stream");
}

The following custom cleanse method removes SEC0111 warnings when source data passes through the Puma.Prey.Common.Validation method.

"CustomCleanseMethods": [
    {
        "RuleIds": [
        "SEC0111"
        ],
        "Flag": "Web",
        "Syntax": "InvocationExpressionSyntax",
        "Namespace": "Puma.Prey.Common.Validation",
        "Type": "Validator",
        "Method": "IsValidFilePath"
    }
]