Skip to main content

C#

This article shows you how to analyze your applications written in C# using preZero. It assumes that you have already set up and authenticated with Qwiet.

Requirements

See Prerequisites for more information.

Preparing your application for analysis

Before analyzing your code with preZero, we recommend:

  • Restoring the dependencies of your application;
  • Building your application (since this will implicitly restore your application's dependencies and produce additional artifacts that may be useful for analysis).

.NET application

You can restore and build a .NET application as follows:

  1. Launch a command prompt
  2. Navigate to your project location
  3. Restore NuGet packages by running
dotnet restore <MySolution.sln>
  1. Start the build by running
dotnet build <MySolution.sln>

If you are using a .NET SDK of .NET Core 3.1 or greater, then you can skip the dotnet restore ....

.NET Framework application

You can restore and build a .NET Framework application with the following:

  1. Launch the Developer Command Prompt for Visual Studio
  2. Navigate to your project location
  3. Restore NuGet packages by running
nuget.exe restore <MySolution.sln>
  1. Start the build by running
msbuild <MySolution.sln>

Analyzing your C# application

note

Qwiet offers a sample application that you can use to run and test preZero. It also includes a functioning configuration file to demonstrate how you can leverage Azure Pipelines or GitHub Actions to automate code analysis whenever you open a new Pull Request (PR).

To analyze your C# application, run:

# Ensure your application dependencies are restored
sl.exe analyze --app <name> --csharp [<path>]

Non-Windows users should invoke the Qwiet CLI using sl instead of sl.exe.

ParameterDescription
--app <name>The name of the application to be analyzed (maximum length: 100 characters)
--csharp2cpg-signed-binary(Optional) On macOS, use a signed self-contained analysis binary instead of using the system dotnet as a driver.
--csharpThe flag identifying the application's language
<path>The location of the application's .csproj or .sln file to be analyzed

See the CLI reference for additional sl.exe analyze options.

Additional parameters

The analysis accepts additional parameters after a double hyphen --.

Additional parameterDescription
--cpg-root-dirAbsolute or relative path to a directory from which all filepaths will be relative to. If this CLI option and parameter are not specified, then it defaults to the directory of the first input solution, project file, or .cs file. Does not expand special path characters like ~.
--excludeAbsolute or relative path(s) to directories whose contents should be excluded from analysis. No .sln, .csproj, or .cs files contained in this directory or its subdirectories will be included in the generated CPG. Symbolic links are not followed. Special characters like ~ are not expanded. Commas are taken only as path separators and not as filename components. Path syntax should be consistent with the current OS, otherwise, the behavior is undefined.
--exclude-regexA double-quoted regex specifying the files to exclude during the analysis. The match is to the absolute file path. No .sln, .csproj, or .cs files contained in this directory or its subdirectories will be included in the generated CPG. Symbolic links are not followed. Syntax should be accepted by the .NET's regex library (System.Text.RegularExpressions.Regex), which is similar to PCRE.

Sample usage of additional parameters

To adjust all paths that the C# application is relative to, use the following. In this example, all paths will become /repo/root/path/app1/example:

sl analyze --app <name> --csharp [<path>] -- --cpg-root-dir /repo/root/path

SCA

To identify open-source vulnerabilities, Qwiet preZero automatically searches for build manifests in the project path you provided when running sl.exe analyze. However, depending on how your project repo is structured, you may need to provide --oss-project-dir <project-path> so that Qwiet preZero can identify your dependencies.

tip

Ensure that the application was built to include all used dependencies.

Tagging results with your branch name

To include the branch name in your preZero results, allowing you to distinguish one set of results from another, add the following to your invocation of Qwiet:

sl.exe analyze --tag branch=`git symbolic-ref --short HEAD`

If you're working in a GitHub environment (e.g., GitHub Actions), you can also use --tag branch=${{ github.head_ref }} to populate your branch name.

If you don't provide a branch name, but Qwiet detects one available in your environment, it will use that name.

Enabling log information

By default, we print logs at the Information level. If you would like more detailed information, pass in the --verbose flag:

sl.exe analyze --csharp --verbose --app Xyz app.csproj

You can find the logs generated by Qwiet in the Windows temp directory.

Memory

When running code analysis, we recommend using a heap size that includes an additional 20% to ensure sufficient physical memory on your server for other requirements.

Setting either the "heap limit percent" or "heap limit" can accomplish this, e.g. by exporting the settings as an environment variable:

# for *nix systems
export DOTNET_GCHeapHardLimitPercent=80 # 80% _OR_
export DOTNET_GCHeapHardLimit=34359738368 # 32GB

# for Windows systems
set DOTNET_GCHeapHardLimitPercent=80 # 80% _OR_
set DOTNET_GCHeapHardLimit=34359738368 # 32GB

Refer to the documentation about runtime configuration options for garbage collection for more details.

Troubleshooting

If you have any issues scanning your project, please see our general troubleshooting page, as well as our C#-specific suggestions that follow.

Recursively finding and scanning your solution/project files

The following example shows you how to modify the sl.exe analyze invocation to recursively find all .sln files and scan them with Qwiet:

# Recursively find all .sln files and scan them with Qwiet preZero
# Be sure to change the app.group value from "test-appgroup" to your preferred name
Get-ChildItem -Path . -Filter *.sln -Recurse -ErrorAction SilentlyContinue -Force | ForEach-Object {
sl.exe analyze --csharp --oss-project-dir $($_.Directory) --tag app.group=test-appgroup --app $($_.Name -replace '.sln', '') $($_.FullName)
}

Alternatively, you can recursively find and scan all .csproj files if .sln-based scans are taking too long:

# Recursively find all .csproj files and scan them with Qwiet preZero
# Use this when .sln based scans are taking too long
# Be sure to change the app.group value from ß"test-appgroup" to your preferred name
Get-ChildItem -Path . -Filter *.csproj -Recurse -ErrorAction SilentlyContinue -Force | ForEach-Object {
sl.exe analyze --csharp --oss-project-dir $($_.Directory) --tag app.group=test-appgroup --app $($_.Name -replace '.csproj', '') $($_.FullName)
}

Improving performance by omitting Razor files from the scan

By default, preZero looks for and scans Razor files included in your project. If you would like to disable this functionality to improve performance, you can pass in --disable-razor after a double hyphen:

sl.exe analyze --app yourApp --csharp <path-to-sln-or-csproj> -- --disable-razor

Excluding projects from the scan

preZero allows you to exclude one or more projects from your scan. This is helpful if:

  • You'd like to avoid scanning test projects;
  • You'd like to exclude a project to improve performance;
  • A project within your application is causing your scan to fail.

To exclude projects, pass in --ignore-project after a double hyphen:

sl analyze ... -- --ignore-project /tmp/app/libA.csproj /tmp/app/libB.csproj ...

You can pass in either full or relative file paths, and you can use wildcards when passing in either path type:

# ignore .csproj files in any sub-directory of tests
sl analyze ... -- --ignore-project tests/**/*.csproj

To ensure that preZero recognized the file path provided as part of --ignore-project, look for the following log message:

found via --ignore-project: <your/file/path>

Deprecated flags

The --dotnet, --dotnet-core, and --dotnet-framework flags have been deprecated, since Qwiet AI will automatically select the best option for the application. However, Qwiet AI is backward compatible, so including one of these flags will present no problem.

The --msbuild-proj and --msbuild-proj-iter flags have been deprecated. These were previously used to control how transitive project dependencies are included in the scan. The new behavior of Qwiet AI is to always include these transitive dependencies by including them similar to how the compiler includes them during compilation. This behavior can be avoided by specifying the --without-ProjectReference flag, but specifying this flag may cause Qwiet AI to miss security vulnerabilities since not all types and dependencies will be available during analysis:

sl.exe analyze --app yourApp --csharp <path-to-sln-or-csproj> -- --without-ProjectReference