Skip to main content

Free 30-min security demo  — We'll scan your real code and show live findings, no commitment Book Now

Offensive360
Tools & Comparisons

.NET Static Code Analysis Tools (2026): SAST for C# & VB.NET

Best .NET static code analysis tools for 2026: Roslyn analyzers, SonarQube, Fortify, and Offensive360 compared by taint analysis depth, deployment options, and cost.

Offensive360 Security Research Team — min read
.NET static code analysis C# security SAST .NET security Roslyn analyzers static code analysis tools .net application security code analysis Visual Studio security .net sast

.NET applications — built on C#, VB.NET, and the ASP.NET web framework — are among the most commonly deployed enterprise systems in the world, powering banking platforms, healthcare systems, government portals, and e-commerce applications. They are also among the most frequently audited for security vulnerabilities, making .NET static code analysis a critical capability for any development team working in the Microsoft ecosystem.

Static code analysis for .NET examines your C# or VB.NET source code (or compiled IL bytecode) without running the application, finding security vulnerabilities, insecure coding patterns, and code quality issues before they reach production. This guide covers the top .NET static code analysis tools available in 2026 — how they work, what they find, and how to choose the right one for your organization.


What Makes .NET Static Code Analysis Different?

The .NET platform introduces specific security considerations that a good static analysis tool must understand:

ASP.NET request handling — The ASP.NET request pipeline, including HttpContext, Request.QueryString, Request.Form, model binding with [FromBody] and [FromQuery], and Razor view rendering are all sources of user-controlled input that must be tracked through taint analysis.

Entity Framework and ADO.NET — SQL injection in .NET most commonly occurs either through raw ADO.NET SqlCommand with string concatenation, or through Entity Framework’s FromSqlRaw() and ExecuteSqlRaw() methods called with interpolated strings. A .NET SAST tool must model both the parameterized-safe patterns and the dangerous raw SQL paths.

Serialization vulnerabilities — .NET’s BinaryFormatter, JavaScriptSerializer, XmlSerializer, and DataContractSerializer have well-documented deserialization attack surfaces. BinaryFormatter was deprecated in .NET 5+ specifically due to its inability to be used securely.

P/Invoke and unsafe code — C# allows interoperability with native code via P/Invoke and the unsafe keyword, introducing memory safety issues (buffer overflows, use-after-free) that don’t exist in managed code.

Cryptography pitfalls — .NET’s System.Security.Cryptography namespace exposes both secure and insecure APIs side by side: MD5, SHA1, DES, 3DES, and RC2 are available but cryptographically weak. A SAST tool should flag use of these algorithms for security-sensitive operations.


Top .NET Static Code Analysis Tools

1. Offensive360 — Full SAST + DAST + SCA Platform

Offensive360 is a comprehensive application security platform with deep .NET SAST support built on interprocedural taint analysis — not pattern matching.

C# / .NET capabilities:

  • Full taint analysis through ASP.NET Core and ASP.NET Framework request pipelines
  • Tracks data from HttpContext.Request, [FromBody], [FromQuery], [FromForm], and model binding through Razor views, API responses, SqlCommand, ExecuteSqlRaw(), Process.Start(), and file system operations
  • Detects SQL injection, second-order SQL injection, command injection, XSS in Razor views, path traversal, XML injection, SSRF, and insecure deserialization
  • Flags BinaryFormatter, weak cryptography (MD5, DES, RC2), insecure cookie flags, CORS misconfigurations, and missing security headers
  • Detects P/Invoke with unsanitized input, unsafe pointer arithmetic, and buffer operations
  • Supports both .NET Framework (4.x) and .NET Core/.NET 5+ / .NET 6/7/8/9

Platform advantages:

  • On-premise OVA deployment — your C# source code never leaves your network
  • DAST scanner included — test your live ASP.NET application for runtime vulnerabilities
  • SCA for NuGet packages — identify known CVEs in your .NET dependencies
  • Flat-rate annual licensing — no per-developer seat costs
  • CI/CD integrations: Azure DevOps, GitHub Actions, GitLab CI, Jenkins, TeamCity, and Bamboo

Best for: Enterprise .NET teams needing deep security analysis, regulated industries (finance, healthcare, government), and organizations with source code confidentiality requirements.


2. Microsoft Roslyn Analyzers

The Roslyn compiler platform is the foundation of the C# and VB.NET compilers in .NET 5+. The Roslyn Analyzer API allows rules to be written that run as part of the compilation process, producing warnings and errors alongside normal build diagnostics.

What Roslyn analyzers provide:

  • Microsoft.CodeAnalysis.NetAnalyzers — a large set of built-in rules covering code quality, performance, and reliability
  • SecurityCodeScan — an open-source security-focused analyzer targeting SQL injection, XSS, and other web vulnerabilities (community-maintained)
  • Roslynator — code quality and style rules
  • SonarAnalyzer.CSharp — SonarSource’s Roslyn rules, available separately from the SonarQube server

Strengths:

  • Deeply integrated into Visual Studio and VS Code — findings appear inline as the developer types
  • Part of the standard build process — no separate tooling required
  • Free and open source
  • Low configuration overhead

Limitations:

  • Security rules are limited — no deep interprocedural taint analysis
  • SecurityCodeScan covers some injection patterns but misses complex taint flows
  • No DAST, SCA, or unified reporting
  • Not suitable as a sole security tool; best as a complement to a dedicated SAST platform

3. SonarQube (with SonarAnalyzer.CSharp)

SonarQube’s C# analysis is delivered through SonarAnalyzer.CSharp, a Roslyn-based analyzer that runs during build and reports to the SonarQube server.

What it finds in C# code:

  • Code quality metrics: cyclomatic complexity, code duplication, cognitive complexity
  • Security Hotspots: potential injection points, hardcoded credentials, insecure randomness
  • Some vulnerability rules: SQL injection (basic patterns), LDAP injection, XPath injection, ReDoS

Limitations for security:

  • Security analysis is pattern-based, not full taint-flow-based
  • “Security Hotspots” require manual triage — they are not confirmed vulnerabilities
  • Misses second-order injection, complex data flows across classes and methods
  • Enterprise edition required for meaningful security scanning (Community Edition has very limited security rules)

Pricing:

  • Community Edition: free (limited security rules)
  • Developer Edition: from €150/year (adds branch analysis and some security rules)
  • Enterprise Edition: €20,000+/year

Best for: Code quality tracking and technical debt management in combination with a dedicated SAST tool for security.


4. Checkmarx

Checkmarx CxSAST and Checkmarx One both support C# and ASP.NET with taint-analysis-based scanning.

C# strengths:

  • Strong ASP.NET taint analysis, including MVC and Web API patterns
  • Good coverage of .NET-specific vulnerability patterns (deserialization, web.config issues)
  • Query customization through CxQL for tailoring rules to your codebase

Limitations:

  • SAST only — no built-in DAST
  • Per-seat or per-application pricing that increases significantly at scale
  • Complex licensing and deployment
  • Customers frequently report high false-positive rates requiring significant tuning

Pricing: Enterprise contracts typically start at $20,000+/year.


5. Veracode

Veracode supports .NET via a binary analysis approach — it analyzes the compiled DLL/EXE rather than source code, which means you don’t need to provide source code, but the analysis is less precise than source-level analysis.

C# / .NET capabilities:

  • SAST of compiled .NET assemblies (source code not required)
  • SCA for NuGet dependencies
  • DAST for ASP.NET web applications

Limitations:

  • SaaS-only — compiled assemblies are uploaded to Veracode’s cloud; no on-premise option
  • Binary analysis is less precise than source-level analysis for complex data flows
  • Per-seat pricing model

Pricing: Typically $30,000–$150,000+/year depending on team size.


6. Fortify Static Code Analyzer (SCA)

Fortify SCA by OpenText (formerly HP Fortify) has strong .NET support with source-level taint analysis.

C# / .NET capabilities:

  • Interprocedural taint analysis for ASP.NET applications
  • Strong detection of injection, cryptography issues, and .NET-specific patterns
  • Support for both .NET Framework and .NET Core

Limitations:

  • SAST and DAST (WebInspect) are separate products requiring separate purchase and integration
  • Very high price point — typically $50,000–$200,000+/year
  • Complex deployment and configuration
  • Slow scan speed compared to modern alternatives

Vulnerability Classes: What .NET SAST Should Detect

A complete .NET static code analysis tool should detect all of the following in C# and ASP.NET codebases:

SQL Injection (CWE-89)

The most common high-severity finding in .NET applications:

// VULNERABLE — string concatenation in SqlCommand
string username = Request.QueryString["username"];
string sql = "SELECT * FROM Users WHERE Username = '" + username + "'";
SqlCommand cmd = new SqlCommand(sql, connection);
// If username contains: ' OR '1'='1 — returns all users

// SECURE — parameterized query
string username = Request.QueryString["username"];
string sql = "SELECT * FROM Users WHERE Username = @username";
SqlCommand cmd = new SqlCommand(sql, connection);
cmd.Parameters.AddWithValue("@username", username);

Entity Framework has its own injection risk via FromSqlRaw:

// VULNERABLE — string interpolation bypasses EF parameterization
var userId = Request.Form["id"];
var user = dbContext.Users
    .FromSqlRaw($"SELECT * FROM Users WHERE Id = {userId}")
    .FirstOrDefault();

// SECURE — use EF LINQ queries (auto-parameterized)
var userId = int.Parse(Request.Form["id"]);
var user = dbContext.Users.FirstOrDefault(u => u.Id == userId);

// OR use FormattableString with FromSqlInterpolated (auto-parameterized)
var user = dbContext.Users
    .FromSqlInterpolated($"SELECT * FROM Users WHERE Id = {userId}")
    .FirstOrDefault();

Cross-Site Scripting (XSS) in Razor Views (CWE-79)

@* VULNERABLE — Html.Raw bypasses encoding *@
@Html.Raw(Model.UserBio)

@* ALSO VULNERABLE — JavaScript context without encoding *@
<script>var userName = '@Model.Username';</script>

@* SECURE — Razor's default encoding *@
@Model.UserBio

@* SECURE — JavaScript encoding for JS context *@
<script>var userName = '@Html.JavaScriptStringEncode(Model.Username)';</script>

Insecure Deserialization (CWE-502)

// VULNERABLE — BinaryFormatter is insecure by design; deprecated in .NET 5+
BinaryFormatter formatter = new BinaryFormatter();
object obj = formatter.Deserialize(stream); // Arbitrary code execution

// ALSO VULNERABLE — JavaScriptSerializer with complex types
JavaScriptSerializer jss = new JavaScriptSerializer();
jss.RegisterConverters(new[] { new MyTypeConverter() });
var obj = jss.Deserialize<object>(Request.InputStream);

// SECURE — use System.Text.Json or Newtonsoft with type restrictions
var options = new JsonSerializerOptions { MaxDepth = 32 };
var obj = JsonSerializer.Deserialize<MySpecificType>(json, options);

Weak Cryptography (CWE-327 / CWE-326)

// VULNERABLE — MD5 for password hashing
using var md5 = MD5.Create();
byte[] hash = md5.ComputeHash(Encoding.UTF8.GetBytes(password));

// ALSO VULNERABLE — DES for data encryption
using var des = DES.Create();
// DES has a 56-bit effective key — trivially brute-forced

// SECURE — use modern algorithms
using var hasher = new Rfc2898DeriveBytes(
    password,
    salt,
    iterations: 600_000,
    HashAlgorithmName.SHA512
); // PBKDF2 with SHA-512

// For encryption — use AES-256-GCM
using var aes = new AesGcm(key, tagSizeInBytes: 16);

Command Injection (CWE-78)

// VULNERABLE — user input in Process.Start
string userInput = Request.QueryString["filename"];
Process.Start("cmd.exe", "/c convert " + userInput + " output.pdf");

// SECURE — validate input and use argument list
string filename = Request.QueryString["filename"];
if (!Regex.IsMatch(filename, @"^[a-zA-Z0-9_\-]+\.pdf$"))
{
    return BadRequest("Invalid filename");
}
var psi = new ProcessStartInfo
{
    FileName = "convert",
    ArgumentList = { filename, "output.pdf" }, // List form, no shell
    UseShellExecute = false
};
Process.Start(psi);

Path Traversal (CWE-22)

// VULNERABLE — user-controlled path without sanitization
string filename = Request.QueryString["file"];
string filePath = Path.Combine("/uploads/", filename);
return File(filePath, "application/octet-stream");
// Attacker: ?file=../../etc/passwd

// SECURE — normalize and validate the resolved path
string filename = Request.QueryString["file"];
string uploadDir = Path.GetFullPath("/uploads/");
string filePath = Path.GetFullPath(Path.Combine(uploadDir, filename));

if (!filePath.StartsWith(uploadDir, StringComparison.OrdinalIgnoreCase))
{
    return BadRequest("Invalid file path");
}
return File(filePath, "application/octet-stream");

Hardcoded Credentials (CWE-798)

// VULNERABLE — credentials in source code
private const string ConnectionString =
    "Server=prod-db;Database=AppDB;User=sa;Password=Admin123!";

private readonly string _apiKey = "sk-live-abc123def456";

// SECURE — credentials from configuration or Key Vault
private readonly string _connectionString;

public MyService(IConfiguration config)
{
    _connectionString = config.GetConnectionString("DefaultConnection");
    // Connection string lives in appsettings.json (excluded from source),
    // environment variables, or Azure Key Vault
}

.NET-Specific SAST Checklist

Use this as a review guide for C# / ASP.NET security:

Input Handling:

  • All Request.QueryString, Request.Form, Request.Headers, and route parameters treated as untrusted
  • Model binding classes do not expose properties that should not be user-controlled
  • [BindNever] or [BindProperties] used to prevent mass assignment

Data Access:

  • No SqlCommand with string-concatenated queries — all use @parameter placeholders
  • FromSqlRaw() not used with interpolated strings — use FromSqlInterpolated() or LINQ
  • Entity Framework raw SQL calls reviewed and parameterized

Output / Rendering:

  • No @Html.Raw() with user-controlled content in Razor views
  • JavaScript contexts in Razor templates use @Html.JavaScriptStringEncode()
  • Content-Security-Policy header configured and restricts inline scripts

Cryptography:

  • No MD5, SHA1, DES, 3DES, or RC2 for security-sensitive operations
  • BinaryFormatter and JavaScriptSerializer not used for untrusted input
  • Passwords hashed with PasswordHasher<T> (ASP.NET Identity) or PBKDF2/Argon2
  • RNGCryptoServiceProvider or RandomNumberGenerator.GetBytes() used for tokens (not System.Random)

Configuration:

  • <customErrors mode="On"> in web.config (Framework) or error handling middleware (Core) prevents stack trace disclosure
  • debug="false" in web.config for production builds
  • <httpRuntime enableVersionHeader="false"> removes version disclosure headers
  • Authentication cookies use HttpOnly, Secure, and SameSite=Strict

Secrets Management:

  • Connection strings and API keys stored in Azure Key Vault, user secrets (development), or environment variables — never in source code
  • appsettings.Production.json with secrets excluded from version control

Comparing .NET SAST Tools

ToolTaint Analysis.NET CoverageOn-PremiseDAST IncludedPricing
Offensive360✅ Deep interproc.C#, VB.NET, ASP.NET, EF✅ OVA✅ YesFlat rate
Roslyn Analyzers❌ Pattern onlyC#, VB.NET✅ (built-in)❌ NoFree
SonarQube⚠️ LimitedC#, VB.NET, ASP.NET✅ Enterprise❌ NoFrom €150/yr
Checkmarx✅ YesC#, ASP.NET, EF⚠️ Complex❌ Separate$20k+/yr
Veracode✅ Binary analysis.NET assemblies❌ SaaS only✅ Separate$30k+/yr
Fortify SCA✅ YesC#, ASP.NET✅ Yes❌ Separate$50k+/yr

Integrating .NET SAST Into Azure DevOps and GitHub Actions

Most .NET teams use Azure DevOps or GitHub Actions for CI/CD. Both integrate cleanly with modern SAST tools:

Azure DevOps Pipeline Example

# azure-pipelines.yml
trigger:
  - main
  - develop

pool:
  vmImage: 'windows-latest'

steps:
  - task: DotNetCoreCLI@2
    displayName: 'Build Solution'
    inputs:
      command: 'build'
      projects: '**/*.csproj'
      arguments: '--configuration Release'

  # Offensive360 SAST scan (via CLI or API)
  - task: PowerShell@2
    displayName: 'Run SAST Scan'
    inputs:
      targetType: 'inline'
      script: |
        # Upload code for scanning
        Invoke-RestMethod -Uri "https://api.offensive360.com/scan/code" `
          -Method POST `
          -Headers @{ "X-API-Key" = "$(O360_API_KEY)" } `
          -Body @{ path = "$(Build.SourcesDirectory)" }

  # Roslyn analyzers run automatically during build
  # Review warnings as errors in Production builds:
  - task: DotNetCoreCLI@2
    displayName: 'Build with Security Analysis'
    inputs:
      command: 'build'
      arguments: '--configuration Release /warnaserror:CA2100,CA3001,CA3002,CA3006,CA3007'
      # CA2100: SQL Injection, CA3001-CA3007: Injection, XSS, Path Traversal, etc.

GitHub Actions Example

name: .NET Security Scan

on:
  pull_request:
    branches: [main]

jobs:
  security-analysis:
    runs-on: windows-latest
    steps:
      - uses: actions/checkout@v4

      - name: Setup .NET
        uses: actions/setup-dotnet@v4
        with:
          dotnet-version: '8.x'

      - name: Build and Analyze
        run: |
          dotnet build --configuration Release \
            /p:RunAnalyzersDuringBuild=true \
            /p:AnalysisLevel=latest-recommended
        # Roslyn security analyzers run automatically

      - name: Run Offensive360 SAST
        env:
          O360_API_KEY: ${{ secrets.O360_API_KEY }}
        run: |
          # Submit code for analysis via Offensive360 API
          curl -X POST https://api.offensive360.com/scan/code \
            -H "X-API-Key: $O360_API_KEY" \
            --data-binary @./src

Frequently Asked Questions

Does .NET static code analysis require the full source code?

Most source-level SAST tools (Offensive360, Checkmarx, Fortify SCA) require source code for the deepest analysis. Veracode uses binary analysis and only requires the compiled assemblies. Source-level analysis is generally more accurate because it can trace data flows through framework internals that binary analysis cannot fully model.

Can static code analysis find vulnerabilities in .NET Framework apps?

Yes. All major .NET SAST tools support both .NET Framework (4.x) and modern .NET (Core, .NET 5/6/7/8/9). For legacy .NET Framework applications using older ASP.NET Web Forms or WCF, look for tools that explicitly list Framework support rather than only advertising .NET Core coverage.

What are the most common security vulnerabilities found in C# applications?

Based on security assessment data across enterprise .NET codebases, the most frequent high-severity findings are:

  1. SQL injection — usually in legacy code using SqlCommand with string concatenation
  2. Hardcoded credentials — connection strings, API keys, and service account passwords in appsettings.json committed to version control
  3. Insecure deserialization — use of BinaryFormatter or JavaScriptSerializer with user-controlled input
  4. Weak cryptography — MD5 or SHA1 for password hashing in legacy code
  5. XSS via @Html.Raw() — developers bypassing Razor’s built-in encoding for “flexibility”
  6. Path traversal — unsanitized file paths from user input in file download or upload handlers

How does Roslyn static analysis compare to dedicated SAST tools?

Roslyn analyzers are excellent for code quality and some security patterns — and they run during the build process, providing the fastest possible feedback. However, they lack the deep interprocedural taint analysis that a dedicated SAST tool provides. Roslyn analyzers will catch obvious patterns (a SqlCommand built with + concatenation in the same method), but they miss complex injection chains that cross class or assembly boundaries. For environments with real security requirements, Roslyn analyzers and a dedicated SAST tool are complementary — not alternatives.

Is NuGet dependency scanning part of .NET SAST?

Dependency scanning (Software Composition Analysis, or SCA) is usually a separate capability from SAST, though some platforms include both. SCA for .NET scans your packages.lock.json, *.csproj, and project.assets.json for NuGet packages with known CVEs in the National Vulnerability Database. Offensive360 includes SCA alongside SAST in the same platform.


Getting Started with .NET Static Code Analysis

The most practical starting point for a .NET team:

  1. Enable Roslyn security analyzers — add Microsoft.CodeAnalysis.NetAnalyzers to your project and enable AnalysisLevel=latest-recommended in your .csproj. This adds security rules to your existing build at zero cost.

  2. Run a baseline SAST scan — before committing to a subscription, use a one-time code scan ($500) to understand the current vulnerability profile of your codebase. Many teams discover high-severity findings — SQL injection, hardcoded credentials, weak crypto — that were completely invisible to their existing tooling.

  3. Prioritize high-severity findings — focus first on Critical and High severity findings (injection, deserialization, hardcoded credentials). These represent real exploitable risk, not theoretical concerns.

  4. Integrate into Azure DevOps or GitHub Actions — once you have a baseline, configure the SAST scan to run on every pull request. This prevents new vulnerabilities from being introduced as the team continues development.

  5. Combine SAST with DASTOffensive360’s DAST scanner tests your running ASP.NET application for runtime vulnerabilities — authentication flaws, business logic issues, and misconfigurations that SAST cannot detect from source code alone.


Offensive360 supports C#, VB.NET, ASP.NET Framework, and ASP.NET Core with deep interprocedural taint analysis. Run a one-time SAST scan of your .NET codebase for $500 — results within 48 hours, source code stays on your server. Or book a demo to see the full platform.

Offensive360 Security Research Team

Application Security Research

Find vulnerabilities before attackers do

Run Offensive360 SAST and DAST against your applications and get a full vulnerability report in minutes.