Skip to content

Security diagnostics

React to whole-program security findings (SQL injection, XXE, weak crypto) from a rule through the typed Diagnostics collection and named aliases.

Some checks cannot be expressed with the local DSL predicates, because they need data-flow across the whole program: SQL injection, XML external-entity (XXE) processing, and other taint-based security findings. Rather than reinvent that analysis, CodeCharter delegates it to the maintained, MIT-licensed Microsoft.CodeAnalysis.NetAnalyzers security analyzers and surfaces each finding as a typed fact in the Diagnostics collection — the same typed surface every other rule uses.

The Diagnostics collection

Diagnostics is a top-level collection (like Types or Methods). Each element is a DiagnosticModel with these members:

Member Type Meaning
Rule string The analyzer rule id, e.g. CA2100 or CA5351.
Category string The analyzer category, e.g. Security.
Message string The human-readable diagnostic message.
OffendingText string The source text the diagnostic points at (may be null).
SourceFile string Absolute path to the file the diagnostic was reported in.
Line int 1-based source line.
Column int 1-based source column.

Filter by a named alias, not a CA… string

Do not compare d.Rule == "CA2100". Filter by a readable alias member. Aliases document intent and keep a rule working if the underlying id set changes:

Alias Underlying ids Flags
SqlInjection CA2100, CA3001 SQL built from untrusted / non-constant text
WeakHashing CA5350, CA5351 MD5 / SHA1 / DES and other broken algorithms
XmlExternalEntity CA3075 Unsafe XML external-entity (XXE) processing
DisabledCertificateValidation CA5359 Certificate validation turned off
DeprecatedSecurityProtocol CA5364 SSL3 / TLS 1.0 and other deprecated protocols
@name "SQL injection"
@severity error
@category "Security"

Diagnostics.Where(d => d.SqlInjection)

Referencing an alias that does not exist (a typo like d.SqlInjektion) is a clear authoring error, not a silently-false match.

Local checks stay in the typed members

Weak crypto is available both as an alias here (WeakHashing) and, for the parts that are a purely local decision, through the ordinary typed members. The boundary is simple: a check you can make by looking at a single expression belongs in the local members (m.Invocations, m.MemberAccesses, …); a check that needs the whole program — where does this string come from, does it reach a SQL sink — belongs in Diagnostics.

Two things to know

  • Opt-in. The analyzers only run when a rule reads the Diagnostics collection. A run whose rules never touch it pays nothing for analyzer execution.
  • Full-solution only. These findings populate during a real solution analysis with complete references. The in-memory spec harness (used by test) has a thin reference set, so taint-heavy analyzers cannot resolve there. A diagnostic that cannot run for lack of references is logged, not silently dropped.

Source and licence

The diagnostics come exclusively from Microsoft.CodeAnalysis.NetAnalyzers, which is MIT-licensed. The LGPL-3.0 SecurityCodeScan analyzers are deliberately not bundled. Analysis runs locally, in-process — no code leaves your machine, matching CodeCharter's overall privacy posture.

What's next