Modern .NET applications face growing security challenges: dependency vulnerabilities, insecure coding practices, and misconfigurations. Static Code Analysis (SAST) helps identify these issues early in the development cycle by scanning your source code without executing it.
This article explains how to apply static code analysis tools in .NET, integrate them into CI/CD, and enforce secure coding practices.
1. What Is Static Code Analysis?
Static code analysis inspects source code, assemblies, or IL (Intermediate Language) to detect:
Security vulnerabilities (SQL injection, XSS, and hardcoded secrets).
Code quality issues (unused variables, memory leaks, dead code).
Compliance with standards (OWASP, CWE, MISRA, PCI DSS).
Unlike dynamic testing (DAST), static analysis runs before deployment and is automatable in CI/CD pipelines.
2. Popular Static Code Analysis Tools for .NET Security
1. Roslyn Analyzers (Microsoft.CodeAnalysis)
Built into the .NET compiler platform.
Security analyzers catch unsafe APIs, missing disposal, insecure cryptography, etc.
Example: add to your project:
dotnet add package Microsoft.CodeAnalysis.FxCopAnalyzers
Configure in .editorconfig
:
dotnet_analyzer_diagnostic.severity = error
2. SonarQube / SonarCloud
Detects vulnerabilities and code smells.
Integrates with GitHub, Azure DevOps, and Jenkins.
Example GitHub Action:
- name: SonarQube Scan
uses: sonarsource/sonarqube-scan-action@v2
3. Security Code Scan (SCS)
4. DevSkim (Microsoft)
Lightweight static analysis for security rules.
Works as a Visual Studio Code extension and CLI tool.
Detects insecure regex, weak crypto, or unsafe string handling.
5. Commercial Tools
Checkmarx, Fortify, and Veracode → deep enterprise security scanning.
Better for large orgs with compliance needs.
3. Example: Security Code Scan in Action
Let’s say you have insecure C# code:
public class UserController
{
public void SaveUser(string username, string password)
{
// Hardcoded secret
var key = "SuperSecretKey123";
// Weak hash
var hashed = new System.Security.Cryptography.MD5CryptoServiceProvider()
.ComputeHash(Encoding.UTF8.GetBytes(password));
// SQL Injection risk
var sql = "INSERT INTO Users (Username, Password) VALUES ('" + username + "', '" + password + "')";
}
}
When you run Security Code Scan or Roslyn Analyzers, it will flag:
Hardcoded secret → “Do not store credentials in source code.”
Weak crypto (MD5) → “Use SHA-256 or PBKDF2.”
SQL string concatenation → “Use parameterized queries.”
Fix:
public void SaveUser(string username, string password)
{
using var hmac = new System.Security.Cryptography.HMACSHA256();
var hashed = hmac.ComputeHash(Encoding.UTF8.GetBytes(password));
var sql = "INSERT INTO Users (Username, Password) VALUES (@u, @p)";
using var cmd = new SqlCommand(sql);
cmd.Parameters.AddWithValue("@u", username);
cmd.Parameters.AddWithValue("@p", Convert.ToBase64String(hashed));
}
4. Automating Static Analysis in CI/CD
GitHub Actions Example
name: .NET Security Analysis
on: [push, pull_request]
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Setup .NET
uses: actions/setup-dotnet@v4
with:
dotnet-version: '8.x'
- name: Install analyzers
run: dotnet add package SecurityCodeScan.VS2019
- name: Build with analysis
run: dotnet build --configuration Release -warnaserror
- name: Vulnerable package scan
run: dotnet list package --vulnerable
Azure DevOps Example
- task: DotNetCoreCLI@2
inputs:
command: build
projects: '**/*.csproj'
arguments: '--configuration Release /p:TreatWarningsAsErrors=true'
5. Best Practices When Using Static Analysis
Shift Left: Run analyzers locally before pushing.
Fail fast:Treat security warnings as errors in CI.
Whitelist vs. Blacklist: Configure .editorconfig
to suppress irrelevant rules, focus on security-critical ones.
Combine SAST and DAST: Use static analysis with dynamic runtime testing (OWASP ZAP).
Monitor Dependencies: Run dotnet list package --vulnerable
regularly.
6. Quick Security Analyzer Checklist
Add Roslyn and FxCop analyzers.
Install Security Code Scan.
Configure .editorconfig
to treat security warnings as errors.
Integrate SonarQube in CI/CD.
Regularly scan NuGet dependencies for vulnerabilities.
Educate developers on resolving flagged issues.
Conclusion
Static code analysis is a must-have layer in securing .NET applications. By integrating tools like Roslyn Analyzers, Security Code Scan, and SonarQube into your CI/CD pipelines, you can catch security flaws early, reduce risks, and enforce best practices automatically.