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

Static Code Analysis for C#: Top 6 Tools 2026

Best C# static code analysis tools: Roslyn, SonarQube, Checkmarx and Offensive360 ranked by taint depth, ASP.NET Core coverage, EF support and pricing.

Offensive360 Security Research Team — min read
C# static code analysis tools C# static analysis C# SAST static code analysis .NET security Roslyn analyzers CSharp static analysis C# security tools ASP.NET security static analysis tools for C# .NET static code analysis C# code analysis static code analysis C# static analysis C# C# code analyzer .net static code analysis

C# static code analysis tools examine your C# source code — without running it — to find security vulnerabilities, code quality issues, and insecure coding patterns before they reach production. For teams building ASP.NET Core APIs, .NET web applications, or enterprise .NET services, a C# static analysis tool is one of the highest-value investments in your security program.

This guide compares the best C# static code analysis tools available in 2026, covering how each works, what it detects, and when to use it.

Quick answer: For deep security analysis with genuine taint analysis across ASP.NET request pipelines, Offensive360 is the strongest C# SAST option. For free, IDE-integrated analysis during development, Roslyn analyzers (built into the .NET SDK) are the starting point. Jump to the comparison table for the side-by-side view.


Why C# Applications Need Dedicated Static Analysis

C# and the ASP.NET framework introduce several security-specific patterns that a good static analysis tool must understand:

  • ASP.NET request pipelineHttpContext.Request, [FromBody], [FromQuery], [FromForm], Razor model binding, and SignalR hubs are all sources of untrusted user input that must be tracked through the application
  • Entity Framework raw SQLFromSqlRaw() and ExecuteSqlRaw() are injection-safe when used with parameters but dangerous with interpolated strings; distinguishing these requires data-flow analysis
  • BinaryFormatter — deprecated in .NET 5+ due to known remote code execution risk; should be flagged in any .NET Framework codebase still using it
  • Weak cryptographyMD5, SHA1, DES, and RC2 are available in System.Security.Cryptography alongside secure algorithms; legacy code frequently uses them
  • Hardcoded secrets — connection strings and API keys in appsettings.json or hardcoded in class fields are common in .NET projects
  • P/Invoke and unsafe code — interop with native code introduces memory safety issues absent in managed C#

A general-purpose static analysis tool that doesn’t model these ASP.NET and .NET-specific patterns will miss the most common C#-specific vulnerability classes.


Top C# Static Code Analysis Tools

1. Offensive360 — Deep C# SAST + DAST + SCA

Offensive360 is a unified application security platform with one of the deepest C# SAST engines available. It performs interprocedural taint analysis specifically modeled on ASP.NET Core and ASP.NET Framework request pipelines.

C# and ASP.NET capabilities:

  • Taint analysis from ASP.NET sources (HttpContext.Request, [FromBody], [FromQuery], [FromForm], route parameters, Request.Headers, Request.Cookies) through controller action methods, service classes, repository layers, and into sinks (SQL, command execution, file I/O, Razor output, HTTP responses)
  • SQL injection detection for both raw ADO.NET (SqlCommand with string concatenation) and Entity Framework (FromSqlRaw(), ExecuteSqlRaw() with interpolated strings)
  • Second-order SQL injection — tracks data written to the database in one request and unsafely reused in another query
  • XSS in Razor views — detects @Html.Raw() with user-controlled content, unsafe JavaScript context rendering, and missing [OutputCache] patterns
  • Command injection via Process.Start() with shell arguments
  • Path traversal in file system operations
  • SSRF via HttpClient with user-controlled URLs
  • BinaryFormatter and JavaScriptSerializer deserialization detection
  • Weak cryptography: MD5.Create(), SHA1.Create(), DES.Create(), RC2.Create()
  • Hardcoded credentials in connection strings, field assignments, and appsettings.json
  • Insecure cookie flags (missing HttpOnly, Secure, SameSite)
  • P/Invoke with unsanitized input

Deployment:

  • On-premise OVA virtual appliance — C# source code never leaves your network
  • Air-gapped operation available
  • CI/CD integrations: Azure DevOps, GitHub Actions, GitLab CI, Jenkins, TeamCity, Bitbucket

Pricing: Flat annual license (no per-developer seat costs). One-time scan available for $500.

Best for: Enterprise .NET teams with security requirements, regulated industries, on-premise requirements, or organizations where source code cannot be uploaded to a third-party SaaS.


2. Roslyn Analyzers (Built into .NET SDK)

The Roslyn compiler platform underlies both the C# and VB.NET compilers in modern .NET. Roslyn analyzers run as part of the compilation pipeline, producing findings alongside normal build diagnostics.

What Roslyn analyzers include:

  • Microsoft.CodeAnalysis.NetAnalyzers — the built-in rule set included in .NET 5+ SDK. Contains performance, reliability, and security rules. Security rules include:
    • CA2100 — SQL injection in SqlCommand (single-method detection)
    • CA3001–CA3012 — injection rules for XSS (CA3001), LDAP (CA3002), XPath (CA3008), XML (CA3075), regex (CA3012), and more
    • CA5350, CA5351 — weak cryptography (3DES, MD5)
    • CA5369, CA5371 — insecure deserialization
  • SecurityCodeScan.VS2019 — community-maintained security-focused Roslyn analyzer for ASP.NET
  • SonarAnalyzer.CSharp — SonarSource’s Roslyn rules (runs as a Roslyn analyzer, separate from the SonarQube server)

How to enable:

<!-- In your .csproj — enable latest recommended Roslyn rules -->
<PropertyGroup>
  <AnalysisLevel>latest-recommended</AnalysisLevel>
  <RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
  <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
  <!-- Enable specific security rules as errors -->
  <WarningsAsErrors>CA2100;CA3001;CA3006;CA5350;CA5351</WarningsAsErrors>
</PropertyGroup>

Strengths:

  • Free — included in the .NET SDK
  • Integrated into Visual Studio and VS Code — findings appear inline as you type
  • Zero setup for teams already using .NET 5+
  • Runs during dotnet build — no separate tooling required

Limitations:

  • Security rules are intra-procedural — they detect injection in a single method but miss multi-function injection chains
  • No taint analysis across class boundaries or files
  • Cannot detect second-order injection, stored XSS, or complex data flows
  • No DAST, no SCA, no unified reporting

Best for: A fast, free first layer of defense during development. Not a standalone security solution — pair with a dedicated SAST tool.


3. SonarQube (with SonarAnalyzer.CSharp)

SonarQube’s C# analysis runs via SonarAnalyzer.CSharp, a Roslyn-based analyzer that feeds results to the SonarQube server. It focuses primarily on code quality metrics — cyclomatic complexity, code duplication, technical debt — with security as a secondary capability.

C# security coverage:

  • SQL injection (basic patterns — same limitations as Roslyn-based detection)
  • Hardcoded credentials (pattern-matching for common patterns like password =)
  • Insecure cookie configuration
  • Weak randomness

Limitations for security:

  • Security rules are pattern-based — misses taint-flow vulnerabilities
  • “Security Hotspots” are not confirmed vulnerabilities; they require manual triage
  • No interprocedural taint analysis
  • Community Edition has very limited security rules
  • Enterprise Edition required for meaningful security scanning ($20,000+/year)

Best for: Code quality tracking and technical debt management. Complementary to a dedicated SAST tool, not a replacement.


4. Checkmarx

Checkmarx CxSAST and Checkmarx One support C# with genuine taint analysis, including ASP.NET Web API and ASP.NET Core patterns.

C# strengths:

  • Interprocedural taint analysis for ASP.NET applications
  • Good coverage of MVC/Web API controller-to-database patterns
  • CxQL allows custom rule writing for specific vulnerability patterns
  • OWASP compliance reporting

Limitations:

  • SAST only — no built-in DAST (requires separate purchase of DAST product)
  • Per-seat or per-application pricing (enterprise contracts from $20,000+/year)
  • Complex on-premise deployment
  • High false-positive rates in some configurations require significant tuning

Best for: Enterprise teams already in the Checkmarx ecosystem or with existing Checkmarx contracts.


5. Fortify Static Code Analyzer (SCA)

Fortify SCA by OpenText has strong C# and ASP.NET support with source-level taint analysis. However, it requires separate purchase from Fortify WebInspect (DAST), is among the most expensive tools in the market, and has slower scan performance than modern alternatives.

C# capabilities:

  • Interprocedural taint analysis for ASP.NET
  • Strong detection of injection, crypto issues, and .NET-specific patterns
  • Support for both .NET Framework 4.x and modern .NET

Limitations:

  • SAST and DAST are separate products — not unified
  • $50,000–$200,000+/year pricing
  • Complex deployment and steep learning curve
  • Slow scan speed

6. Veracode

Veracode analyzes compiled .NET assemblies (DLL/EXE) rather than C# source code. This means source code is not required, but analysis is less precise than source-level analysis.

C# / .NET capabilities:

  • SAST of compiled assemblies
  • SCA for NuGet packages
  • DAST available as a separate product

Limitations:

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

C# Vulnerability Classes: What Static Analysis Should Detect

A complete C# static analysis tool should detect all of the following vulnerability classes:

SQL Injection in ADO.NET (CWE-89)

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

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

SQL Injection in Entity Framework (CWE-89)

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

// SECURE — LINQ query (always parameterized)
var id = int.Parse(Request.Form["id"]);
var user = dbContext.Users.FirstOrDefault(u => u.Id == id);

// ALSO SECURE — FromSqlInterpolated (parameterizes the interpolated string)
var user = dbContext.Users
    .FromSqlInterpolated($"SELECT * FROM Users WHERE Id = {id}")
    .FirstOrDefault();

XSS in Razor Views (CWE-79)

@* VULNERABLE — bypasses Razor's automatic HTML encoding *@
@Html.Raw(Model.UserBio)

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

@* SECURE — Razor encodes by default *@
@Model.UserBio

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

Insecure Deserialization (CWE-502)

// VULNERABLE — BinaryFormatter allows arbitrary code execution
// (deprecated in .NET 5+, removed in .NET 7+)
BinaryFormatter formatter = new BinaryFormatter();
object obj = formatter.Deserialize(requestStream);

// SECURE — use System.Text.Json with a specific type
var options = new JsonSerializerOptions { MaxDepth = 32 };
var obj = JsonSerializer.Deserialize<MySpecificType>(jsonString, 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));
// 56-bit effective key space — cracked in seconds with modern hardware

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

// SECURE — PBKDF2 with SHA-512 for passwords
using var kdf = new Rfc2898DeriveBytes(
    password, salt, iterations: 600_000, HashAlgorithmName.SHA512
);

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

Path Traversal (CWE-22)

// VULNERABLE — user-controlled filename in file path
string filename = Request.QueryString["file"];
string path = Path.Combine("/uploads/", filename);
return File(path, "application/octet-stream");
// ?file=../../etc/passwd reads system files

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

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

Hardcoded Credentials (CWE-798)

// VULNERABLE — connection string in source code
private const string ConnStr =
    "Server=prod-db;Database=App;User=sa;Password=Admin123!";

// SECURE — load from configuration (Azure Key Vault, environment variables,
//           user secrets for development)
private readonly string _connStr;

public MyRepo(IConfiguration config)
{
    _connStr = config.GetConnectionString("DefaultConnection");
}

Comparison Table

ToolTaint AnalysisC# / ASP.NET CoverageOn-PremiseDAST IncludedPricing
Offensive360✅ Deep interproc.C#, VB.NET, ASP.NET MVC, ASP.NET Core, EF✅ OVA + air-gap✅ IncludedFlat rate
Roslyn Analyzers⚠️ Single-method onlyC#, VB.NET✅ Built-in❌ NoFree
SonarQube⚠️ Pattern-basedC#, VB.NET, ASP.NET✅ Enterprise❌ No€150–€20k+/yr
Checkmarx✅ YesC#, ASP.NET⚠️ Complex❌ Separate$20k+/yr
Fortify SCA✅ YesC#, ASP.NET✅ Yes❌ Separate$50k+/yr
Veracode✅ Binary analysis.NET assemblies❌ SaaS only✅ Separate$30k+/yr

Integrating C# Static Analysis into Azure DevOps and GitHub Actions

Azure DevOps Pipeline

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

pool:
  vmImage: 'windows-latest'

steps:
  # Step 1: Build with Roslyn security analyzers enabled
  - task: DotNetCoreCLI@2
    displayName: 'Build with Security Analysis'
    inputs:
      command: 'build'
      projects: '**/*.csproj'
      arguments: >
        --configuration Release
        /p:RunAnalyzersDuringBuild=true
        /p:AnalysisLevel=latest-recommended

  # Step 2: Treat critical security analyzer warnings as errors
  - task: DotNetCoreCLI@2
    displayName: 'Security-Gated Build'
    inputs:
      command: 'build'
      arguments: >
        --configuration Release
        /warnaserror:CA2100,CA3001,CA3002,CA3006,CA5350,CA5351

  # Step 3: Run Offensive360 SAST (deep taint analysis)
  - task: PowerShell@2
    displayName: 'Run SAST Scan'
    inputs:
      targetType: 'inline'
      script: |
        # Submit source for deep C# taint analysis
        Invoke-RestMethod -Uri "https://api.offensive360.com/scan/code" `
          -Method POST `
          -Headers @{ "X-API-Key" = "$(O360_API_KEY)" }

GitHub Actions

name: C# Security Analysis

on:
  pull_request:
    branches: [main]
  push:
    branches: [main]

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

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

      - name: Build with Roslyn Analyzers
        run: |
          dotnet build --configuration Release `
            /p:RunAnalyzersDuringBuild=true `
            /p:AnalysisLevel=latest-recommended

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

Important: When running dotnet ef migrations in the same pipeline, pass -- /p:RunAnalyzersDuringBuild=false to the EF command to avoid analyzer conflicts with the design-time build. See our dotnet ef RunAnalyzersDuringBuild guide for the complete pattern.


Frequently Asked Questions

What is the best free C# static code analysis tool?

The best free C# static code analysis tool is the built-in Roslyn analyzer suite (Microsoft.CodeAnalysis.NetAnalyzers), which ships with the .NET SDK and requires no additional setup. Enable it by adding <AnalysisLevel>latest-recommended</AnalysisLevel> to your .csproj. For security-specific rules, add SecurityCodeScan.VS2019 as a NuGet analyzer reference. These tools are free but limited in taint-analysis depth — they miss multi-method injection chains.

Can Roslyn analyzers find SQL injection in C#?

Roslyn analyzers can find first-order SQL injection within a single method — for example, a SqlCommand built with string concatenation on the same line as the Request.QueryString read. They cannot reliably find injection chains that span multiple methods, services, or classes. For those, you need interprocedural taint analysis from a dedicated SAST tool like Offensive360.

What C# vulnerabilities does SAST miss that DAST finds?

SAST tools find code-level vulnerabilities — injection flaws, hardcoded secrets, weak cryptography, insecure code patterns. They cannot detect:

  • Authentication bypass vulnerabilities that depend on application state
  • Business logic flaws (e.g., price manipulation, privilege escalation through UI workflows)
  • Misconfigurations in the deployment environment (server headers, TLS version, cookie flags set by middleware)
  • Race conditions that only manifest under load

DAST tests your running ASP.NET application and can find runtime-level issues that SAST cannot. Offensive360 includes both SAST and DAST in the same platform.

Does .NET Framework (4.x) SAST work differently from .NET 8?

The .NET Framework and modern .NET use the same C# language but have different class libraries, request pipeline models (System.Web vs. ASP.NET Core middleware), and deployment patterns. A good C# SAST tool must model both. Offensive360 supports both .NET Framework 4.x (WebForms, MVC 5, Web API 2, WCF) and modern .NET (ASP.NET Core, Minimal APIs, gRPC, SignalR).

How does C# static analysis handle Entity Framework?

Entity Framework has two main SQL execution paths: LINQ queries (which EF parameterizes automatically and are safe) and raw SQL methods (FromSqlRaw(), ExecuteSqlRaw(), SqlQuery()). A good C# SAST tool must:

  1. Recognize LINQ queries as safe (they don’t need to be flagged)
  2. Detect FromSqlRaw() called with string interpolation as a SQL injection vulnerability
  3. Recognize FromSqlInterpolated() as safe (it uses FormattableString for parameterization)
  4. Track data from user input through service layers to raw EF query calls

Getting Started with C# Static Code Analysis

Step 1: Enable Roslyn analyzers (free, immediate)

Add to your .csproj:

<PropertyGroup>
  <AnalysisLevel>latest-recommended</AnalysisLevel>
  <RunAnalyzersDuringBuild>true</RunAnalyzersDuringBuild>
</PropertyGroup>

Then add security-focused analyzers:

<PackageReference Include="SecurityCodeScan.VS2019" Version="5.6.7">
  <PrivateAssets>all</PrivateAssets>
  <IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>

Step 2: Run a one-time SAST scan to understand your baseline

Before committing to a subscription, use a one-time C# SAST scan ($500) to see what deep taint analysis finds in your codebase. Many .NET teams discover high-severity findings — second-order SQL injection, complex XSS chains, insecure deserialization — that were completely invisible to their Roslyn-based tooling.

Step 3: Integrate into Azure DevOps or GitHub Actions

Once you have a baseline, configure the SAST scan to run on every pull request. Block merges on Critical findings. This prevents new vulnerabilities from entering the codebase as development continues.

Step 4: Add DAST for runtime coverage

SAST finds source-level vulnerabilities. Offensive360’s DAST scanner tests your running ASP.NET application for authentication flaws, business logic issues, and runtime misconfigurations that only appear when the application is executing.


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

Offensive360 Security Research Team

Application Security Research

Updated June 1, 2026

Find vulnerabilities before attackers do

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