Skip to content

fix: suppress S4790 on the MD5 and SHA-1 hash providers - #16

Merged
matt-edmondson merged 1 commit into
mainfrom
fix/sonar-s4790-hash-providers
Aug 24, 2026
Merged

fix: suppress S4790 on the MD5 and SHA-1 hash providers#16
matt-edmondson merged 1 commit into
mainfrom
fix/sonar-s4790-hash-providers

Conversation

@matt-edmondson

Copy link
Copy Markdown
Contributor

Takes main's SonarCloud security rating on new code from D back to A. That rating is currently the only thing failing the quality gate on main other than duplication.

Why the gate is red

Eight S4790 findings, "use a stronger hashing algorithm", four in each of the MD5 and SHA-1 providers:

Essentials.HashProviders.MD5/MD5HashProvider.cs:40,42,71,74
Essentials.HashProviders.SHA1/SHA1HashProvider.cs:40,42,71,74

They're false positives by construction. A package named ktsu.Essentials.HashProviders.MD5 has to call MD5, and the algorithm is fixed by the type's contract rather than picked per call. There is no fix that keeps the package doing what it says on the tin.

Worth noting they have nothing to do with the recent async stream work: SonarCloud dates all eight to 2026-08-13, and they only began failing the gate once main's new code window moved past the 2.2.0 release.

The change

One class-level suppression per file, sitting directly beneath the CA5351 and CA5350 suppressions that are already there for exactly this reason, and written in the same shape:

[SuppressMessage("Security", "CA5351:Do Not Use Broken Cryptographic Algorithms", Justification = "This provider exists specifically to implement MD5, which callers select deliberately for compatibility")]
[SuppressMessage("Security", "S4790:Using weak hashing algorithms is security-sensitive", Justification = "This provider exists specifically to implement MD5, which callers select deliberately for compatibility. The algorithm is fixed by the type's contract and cannot be substituted for a stronger one")]

Class level is the smallest scope that actually covers this, because all four sites per file are the algorithm the type exists to expose, split across two overloads and their #if NET6_0_OR_GREATER branches. Suppressing per line would mean eight attributes saying the same sentence.

Preferred over triaging the findings in the SonarCloud UI because the reasoning stays in version control next to the code it excuses, and it survives any future project re-import.

Verification

Both projects build clean, 0 warnings and 0 errors under warnings-as-errors.

Local verification stops there, and I want to be straight about it: SonarAnalyzer only runs through the CI scanner, so a plain dotnet build never exercises S4790 and can't confirm the suppression binds. Roslyn matches SuppressMessageAttribute on the check ID, so this should hold, but the real proof is this PR's own SonarCloud run. If the rating doesn't move, the suppression is wrong and I'll adjust it rather than leave it sitting there looking like it worked.

SonarCloud rates new code on main D for security, on the strength of eight
S4790 "use a stronger hashing algorithm" findings across these two providers.
They are false positives by construction: a package named
ktsu.Essentials.HashProviders.MD5 has to call MD5, and the algorithm is fixed
by the type's contract rather than chosen per call.

Suppress at class level, alongside the CA5351 and CA5350 suppressions already
there for the same reason, and with justifications in the same shape. Class
level is the smallest scope that covers it, since all four sites per file are
the algorithm the type exists to expose.

These findings predate the async stream work; they were raised 2026-08-13 and
only started failing the gate once main's new code window moved.
@sonarqubecloud

Copy link
Copy Markdown

@matt-edmondson
matt-edmondson merged commit b233d2e into main Aug 24, 2026
10 checks passed
@matt-edmondson
matt-edmondson deleted the fix/sonar-s4790-hash-providers branch August 24, 2026 00:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant