ZainUlAbiddin.SecAuditor 1.0.0

The owner has unlisted this package. This could mean that the package is deprecated, has security vulnerabilities or shouldn't be used anymore.
dotnet tool install --global ZainUlAbiddin.SecAuditor --version 1.0.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local ZainUlAbiddin.SecAuditor --version 1.0.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=ZainUlAbiddin.SecAuditor&version=1.0.0
                    
nuke :add-package ZainUlAbiddin.SecAuditor --version 1.0.0
                    

SecAuditor

A Roslyn-based security auditor for ASP.NET Core APIs. It scans a real .sln/.csproj for common OWASP-relevant misconfigurations - missing [Authorize], JWT/CORS misconfig, hardcoded secrets, missing rate limiting, raw-SQL injection risk - and can optionally ask Claude to explain each finding in plain language with a concrete fix.

Rules are deterministic (real AST analysis via Roslyn, not string matching, not regex-over-everything); AI is only used to narrate findings the rule engine already found, never to invent them.

Why

Most static analyzers for .NET are generic (Snyk, SonarQube) - they don't speak ASP.NET Core's specific footguns (AllowAnyOrigin() + AllowCredentials(), FromSqlRaw vs FromSqlInterpolated, ValidateIssuer = false) and they don't explain why something matters or how to fix it in your code. SecAuditor is narrow on purpose: seven checks, each backed by a real vulnerable/safe pair in the test fixture, each with a specific, actionable fix - and each validated against a real production ASP.NET Core codebase, not just the fixture (see Verification).

What it can scan

Built for: ASP.NET Core Web API projects (net6.0+). The checks assume common ASP.NET Core idioms:

  • Controllers with [Authorize]/[AllowAnonymous]/[HttpPost] etc. (SEC001)
  • JWT auth via Microsoft.AspNetCore.Authentication.JwtBearer (SEC002)
  • CORS via AddCors/AllowAnyOrigin/AllowCredentials (SEC003)
  • appsettings*.json configuration files (SEC005)
  • Rate limiting via AddRateLimiter (SEC006)
  • EF Core (FromSqlRaw/ExecuteSqlRaw) or ADO.NET (SqlCommand/OleDbCommand/NpgsqlCommand) (SEC007)

Works on any C# project, ASP.NET Core or not: SEC004 (hardcoded secrets in source) doesn't depend on any ASP.NET Core API, so it's useful on console apps, class libraries, Windows services, anything.

Not the target, and will just report nothing (not false positives): WinForms/WPF desktop apps, non-web console apps, class libraries with no controllers/auth/CORS/SQL of their own - the ASP.NET-specific rules simply have nothing to check and stay silent. It's safe to point the tool at them; it just won't find much.

Untested, best-effort: classic .NET Framework (net48 etc.) projects. Project loading goes through MSBuildWorkspace, which can often open older-style .csproj files too, but this hasn't been verified against one.

Before scanning: run dotnet restore on the target project/solution first. MSBuildWorkspace evaluates the project file, so a project that's never been restored may load incompletely or spam workspace warnings to stderr (the scan still runs - Roslyn's syntax trees don't need a successful compilation, just valid project evaluation).

Point it at a .sln to scan every project in a solution at once, or at one .csproj to scan just that project.

Install

git clone https://github.com/<your-username>/DotNetSecAuditor.git
cd DotNetSecAuditor
dotnet pack src/SecAuditor -c Release
dotnet tool install --global --add-source ./nupkg ZainUlAbiddin.SecAuditor

Requires the .NET SDK (10.0+; built and tested on 10.0.401). Check with dotnet --version.

To update after pulling new changes:

dotnet tool uninstall --global ZainUlAbiddin.SecAuditor
dotnet pack src/SecAuditor -c Release
dotnet tool install --global --add-source ./nupkg ZainUlAbiddin.SecAuditor

Run without installing

No need to pack/install just to try it out:

dotnet run --project src/SecAuditor -- path/to/YourApi.csproj

Usage

secauditor path/to/YourApi.csproj
secauditor path/to/YourSolution.sln --json report.json --md report.md --html report.html
secauditor path/to/YourApi.csproj --ai        # requires ANTHROPIC_API_KEY
Flag Effect
--json <path> Write findings as structured JSON
--md <path> Write a Markdown report
--html <path> Write a styled, self-contained HTML report
--ai Ask Claude to explain each finding + suggest a fix. Silently skipped with a warning if ANTHROPIC_API_KEY isn't set - the tool never fails just because AI isn't configured.
--fail-on <Severity> Exit 1 if any finding is at or above this severity (Low/Medium/High/Critical, or none). For CI gates - without this flag, exit code is always 0 when the scan itself succeeds (findings are informational, not a build failure by default).

Use as a GitHub Action

Drop this into .github/workflows/security.yml in any ASP.NET Core repo to scan every pull request, upload the report as a build artifact, and post (and update, on re-push) a PR comment with the findings:

name: Security scan
on: [pull_request]

jobs:
  secauditor:
    runs-on: ubuntu-latest
    permissions:
      pull-requests: write
    steps:
      - uses: actions/checkout@v4
      - uses: zainbinattaullah/DotNetSecAuditor@master
        with:
          path: src/YourApi/YourApi.csproj
          fail-on: Critical        # or High / Medium / Low / none
          # ai: 'true'             # needs env.ANTHROPIC_API_KEY set on this job from a secret

The action builds SecAuditor from source on each run (it isn't published to NuGet.org), so no separate install step is needed - actions/checkout on your repo plus the action reference above is enough. See action.yml for all inputs/outputs, and .github/workflows/ci.yml in this repo for a working example (it dogfoods the action against its own test fixture).

Rules

ID Check Severity
SEC001 Mutating controller action (POST/PUT/DELETE/PATCH) with no [Authorize] and no explicit [AllowAnonymous] High
SEC002 TokenValidationParameters disabling ValidateIssuer/ValidateAudience/ValidateLifetime/ValidateIssuerSigningKey, or a JWT signing key built from a string literal Critical
SEC003 CORS AllowAnyOrigin() - Critical if combined with AllowCredentials() (also an ASP.NET Core runtime error), Medium alone Critical / Medium
SEC004 Hardcoded secret (password/API key/connection string) assigned to a string literal in C# Critical
SEC005 Hardcoded secret in appsettings*.json - matches both "ApiKey": "..."-shaped keys and Password=... embedded in a connection string value Critical
SEC006 Project-wide: looks like a web API but no AddRateLimiter() anywhere Medium
SEC007 FromSqlRaw/ExecuteSqlRaw/SqlCommand built from an interpolated or concatenated string instead of parameters Critical

Every rule skips values that look like placeholders (CHANGE_ME_*, TODO, empty strings), URLs, or natural-language sentences, so config templates and UI copy don't drown real findings - see Rules/SecretValueHeuristics.cs.

Architecture

src/SecAuditor/
  Analysis/     ProjectLoader (MSBuildWorkspace), AuditEngine (runs all rule kinds)
  Rules/        ISecurityRule (per-file), IProjectRule (whole-project), IFileContentRule (non-C# files)
  Ai/           IFindingExplainer + Claude-backed implementation
  Reports/      JSON / Markdown / HTML writers
tests/SampleVulnerableApp/
  A real ASP.NET Core Web API with one deliberately planted bug per rule, plus a
  correctly-guarded counter-example for each - the project's own regression test.

Three rule interfaces because checks operate at three different granularities:

  • ISecurityRule judges one C# file at a time (most rules)
  • IProjectRule needs to see every file before it can decide (e.g. "is there a rate limiter anywhere in this project?")
  • IFileContentRule runs on files that are never part of the C# compilation at all (appsettings*.json)

Adding a rule means implementing one of these three interfaces and registering it in Program.cs - nothing else changes.

Verification

Two layers of proof, not just "it compiles":

  1. tests/SampleVulnerableApp plants exactly one bug per rule and one correctly-fixed counter-example per rule (an [Authorize]-guarded action, a parameterized SQL query, an [AllowAnonymous] action, etc.). Running secauditor against it reports exactly 9 findings with zero false positives on the guarded code:

    dotnet run --project src/SecAuditor -- tests/SampleVulnerableApp/SampleVulnerableApp.csproj
    
  2. Run against a real, unmodified production codebase. The fixture alone can only prove a rule fires on a bug planted to trigger it - it can't prove the rule stays quiet on real, messy code it was never designed around. Running an early version against a real ASP.NET Core API surfaced two genuine false positive shapes the fixture never had (a URL named PasswordResetUrl, a UI message named GenericForgotPasswordMessage - both matched on "name contains 'password'"), which is exactly what Rules/SecretValueHeuristics.cs exists to fix. That real run also turned up a genuinely hardcoded Gmail app password and a predictable default reset password - the kind of finding a fixture can't manufacture on its own.

Contributing / adding a rule

  1. Pick the right interface (ISecurityRule for a per-file check, IProjectRule for a whole-project check, IFileContentRule for a non-C# file).
  2. Implement it in Rules/, register it in Program.cs.
  3. Add one vulnerable fixture and one correctly-fixed counter-example to tests/SampleVulnerableApp and confirm the finding count in the README's verification command still matches.

Roadmap

  • Live endpoint scanning (send test requests, check headers/rate limits at runtime)
  • Full OWASP API Security Top 10 coverage
  • Web dashboard with historical trend tracking

License

MIT

Product Compatible and additional computed target framework versions.
.NET net10.0 is compatible.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last Updated

First public release: 7 rules (missing [Authorize], JWT/CORS misconfig, hardcoded secrets in code and config, missing rate limiting, raw-SQL injection risk), JSON/Markdown/HTML reports, optional AI-generated explanations, --fail-on CI gate, and a reusable GitHub Action.