C#
Vulkro reads C# and .NET projects with a dedicated pack of configuration and syntactic rules. There is no C# parser in the main analysis pipeline and no taint engine for C#: the rules match risky call shapes and configuration values, and a small same-method check decides whether a value came from the request. NuGet dependencies declared in .csproj and resolved in packages.lock.json are checked against the local CVE bundle.
C# is covered by vulkro (Core). Because these files are read, C# is not listed as an unread language in the scan coverage report.
vulkro scan .
What is analysed
| Area | Coverage |
|---|---|
| Files read | *.cs, *.cshtml, *.razor, *.aspx / *.ascx / *.master, web*.config (including Web.Release.config transforms), appsettings*.json, *.csproj |
| Skipped | Generated code (*.designer.cs, *.g.cs), test projects (a .csproj referencing a test SDK, *.Tests directories, *Tests.cs) and bin/, obj/, packages/ |
| Request sources | Request.Query / Form / Headers / Cookies / Body / RouteValues style reads, [FromQuery]-style parameters, string parameters of a public controller action or minimal-API lambda, and variables assigned from any of those in the same method |
| Taint | None. "Request-derived" is decided within one method only |
| Endpoints and auth | ASP.NET Core routes: attribute-routed controllers (class [Route] templates, verb attributes, [controller] / [action] tokens, conventional MVC actions) and minimal APIs under MapGroup prefixes, each with an auth verdict from [Authorize] / [AllowAnonymous], RequireAuthorization() and a fallback policy. A finding inside an action names its route |
| Dependencies | .csproj <PackageReference> items, resolved by a sibling packages.lock.json, matched as NuGet against the local CVE bundle. See Dependencies and CVEs |
Detectors
| Rule | What it finds | CWE |
|---|---|---|
DOTNET-DESER-001 | BinaryFormatter, SoapFormatter, NetDataContractSerializer, LosFormatter or ObjectStateFormatter deserializing; Critical when the input comes from the request in the same method. A DataSet / DataTable ReadXml of request data is reported here too | 502 |
DOTNET-DESER-002 | Json.NET TypeNameHandling other than None, JavaScriptSerializer with SimpleTypeResolver, and XmlSerializer / DataContractSerializer built from a request-chosen type | 502 |
DOTNET-VIEWSTATE-001 | enableViewStateMac="false", aspnet:AllowInsecureViewState, viewStateEncryptionMode="Never" | 642, 311 |
DOTNET-CONFIG-001 | customErrors mode="Off", compilation debug="true" (skipped when a release transform fixes it), request validation off, "DetailedErrors": true outside development, an unconditional UseDeveloperExceptionPage(), and any-origin CORS combined with credentials | 209, 11, 79, 942 |
DOTNET-AUTH-001 | [AllowAnonymous] on a mutating action beside [Authorize] siblings, a Host header compared with localhost in an access decision, Request.IsLocal deciding access, and a Referer-based authentication exemption | 862, 290, 293 |
DOTNET-CMDI-001 | A request-derived value reaching Process.Start | 78 |
DOTNET-SQLI-001 | A request-derived value in an ADO.NET or EF raw SQL call through concatenation or interpolation | 89 |
DOTNET-PATH-001 | A request-derived value in a file API without GetFileName or GetFullPath plus StartsWith containment | 22 |
DOTNET-SSRF-001 | An outbound HTTP call whose whole URL comes from the request | 918 |
DOTNET-XXE-001 | XmlUrlResolver assigned, DtdProcessing.Parse with a resolver, and insecure XmlTextReader / XmlDocument defaults when the project targets .NET Framework older than 4.5.2 | 611 |
A committed <machineKey> is reported as SIGNKEY-STATIC-001 (framework signing key set to a known value), not under a DOTNET rule. Secrets, IaC, container and CI checks run on a .NET repository as on any other.
Example
public IActionResult Find([FromQuery] string id)
{
var cmd = new SqlCommand("SELECT * FROM Users WHERE Id = " + id, conn);
return Ok(cmd.ExecuteScalar());
}
vulkro scan . reports this as DOTNET-SQLI-001 (CWE-89) on the SqlCommand line. Confidence is High when the request read sits on the sink statement itself and Medium when it arrives through a local variable.
Limits
- No taint and no cross-method flow. A request value passed to a helper method, stored in a field, or returned from another method is not followed. Findings carry no data-flow trace and are not reported as proven.
- Syntactic matching. Source is matched after comments and string contents are blanked; types are not resolved, so a call is recognised by its name and shape.
- No endpoint map and no access model. The OWASP API Top 10 checks that need an endpoint inventory (missing auth per route, IDOR, function-level authorization) do not run for C#.
- Markup is read narrowly. Razor files (
.cshtml,.razor) get the same code rules as.cs; Web Forms pages (.aspx,.ascx,.master) are read only for a page directive that turns off ViewState MAC. Template escaping context is not modelled. - VB.NET is not read.
See Supported languages for how C# compares with the other languages.