Software Composition Analysis (SCA)
Raises an issue per consumed NuGet package version with known security advisories listed on GitHub: https://github.com/advisories?query=+ecosystem%3Anuget The issue is reported on the first type (alphabetically) using a third-party assembly from the affected package.
Flagged Code
Flagged Code
<!-- MyApp.csproj: Newtonsoft.Json 12.0.1 has the advisory GHSA-5crp-9r3c-p9vr --> <ItemGroup> <PackageReference Include="Newtonsoft.Json" Version="12.0.1" /> </ItemGroup>Fixed Code
<!-- 13.0.1 is the patched version that resolves all known advisories of this package --> <ItemGroup> <PackageReference Include="Newtonsoft.Json" Version="13.0.1" /> </ItemGroup>
How to fix
Update the affected package to at least the patched version recommended, which resolves all known advisories for the package. It is not always the latest version (e.g. an issue in 4.0.2 might be fixed in 4.1.0 while 7.0.8 exists).
CQLinq source
This rule is written in CQLinq, C# LINQ over the NDepend code model. It ships with every new NDepend project: you can read it, adapt it, or use it as a starting point for your own custom rules.
// <Name>Software Composition Analysis (SCA)</Name>
// <Id>ND3120:SoftwareCompositionAnalysis</Id>
warnif count > 0
// Use this hashset to avoid to have several SAC issues on a type
let hashset = new HashSet<IType>()
// Gather third-party assemblies with one or several GitHub Security Advisories
let thirdPartyAsmWithAdvisories = from asm in ThirdParty.Assemblies
// Assemblies from Microsoft.NetCore.App.Runtime pkg reference version
// are always X.0.0.0 (like 8.0.0.0 or 9.0.0.0)
// Thus this rule cannot detect if patched version is referenced.
where !asm.Name.StartsWithAny("System.","Microsoft.") &&
// If the asm is not resolved at analysis time, the file-version
// remains unknow and this can lead to false positive
!asm.IsThirdPartyInferredFromRef
let advisories = asm.GetSecurityAdvisories()
where advisories.Count > 0
select new {
asm,
advisories,
PackageName = (string)advisories.First().PackageName
}
// Merge third-party assemblies within the same NuGet Package
from x in thirdPartyAsmWithAdvisories.ToLookup(a1 => a1.PackageName)
// Gather data useful to describe the advisories and how to fix
let HighestSeverity = x.SelectMany(r => r.advisories).Max(ad => ad.Severity)
let AdvisoryWithHighestSeverity = x.SelectMany(r => r.advisories).First(ad => ad.Severity == HighestSeverity)
let ThirdPartyAssembliesImpacted = x.Select(x1 => x1.asm).ToArray()
// Application AND test assemblies: a vulnerable package referenced only by tests is still a vulnerability
let AppAssembliesUser = ApplicationAndTestCode.Assemblies.UsingAny(ThirdPartyAssembliesImpacted)
// Discard when consummers are only .NET Fx v4.x, this provoke some false positive with .NET Core version range matching
where AppAssembliesUser.Any(a1 => !a1.TargetFrameworkName.StartsWith("net4"))
// The issue appears on the first type using one culprit third-party assembly
let typeUsers = ApplicationAndTestCode.Types.UsingAny(ThirdPartyAssembliesImpacted)
.Where(t => !t.IsGeneratedByCompiler || t.Name.StartsWith("Program+")).ToArray()
let FirstAppTypeUser = (typeUsers.Length == 0 ? ApplicationAndTestCode.Types : typeUsers ) // Make sure at least one type else we get an exception!
.Aggregate((minElement, nextElement) =>
string.Compare(nextElement.Name, minElement.Name, StringComparison.Ordinal) < 0 && !hashset.Contains(nextElement)
? nextElement
: minElement)
let fillHashset = hashset.Add(FirstAppTypeUser)
select new {
FirstAppTypeUser,
PackageName = x.Key,
ThirdPartyAssembliesImpacted,
AppAssembliesUser,
PackageVersion = x.First().asm.Version,
PatchAllAdvisoriesVersion = x.First().advisories.Max(ad => ad.PatchedVersion),
HighestSeverity,
AdvisoryWithHighestSeverity = AdvisoryWithHighestSeverity.Url,
AdvisorySummary = AdvisoryWithHighestSeverity.Summary,
NbAdvisory = x.First().advisories.Count,
AdvisoriesUrl = x.First().advisories.Select(ad=> ad.Url).Except(AdvisoryWithHighestSeverity.Url).Aggregate(" ; "),
Debt = 20.ToMinutes().ToDebt()
}
//<Expl>
// The application uses the NuGet Package **{1} version {4}** which is affected by {9} Github security advisor{9?y:ies}.
//
// **Recommended Action:** Update the package to version *{5}* or higher that has no known security advisory.
//
// Advisory with highest severity *{6}* is {7} : **{8}**. {9?:Other advisory url: }{10}
//
// The *{0}* is the first type (alphabetically) in the application that uses this package.
//</Expl>
//<Desc>
// Raises an issue per consumed NuGet package version with known security
// advisories listed on GitHub:
// https://github.com/advisories?query=+ecosystem%3Anuget
// The issue is reported on the first type (alphabetically) using a
// third-party assembly from the affected package.
//
// **Flagged Code**
// ```xml
// <!-- MyApp.csproj: Newtonsoft.Json 12.0.1 has the advisory GHSA-5crp-9r3c-p9vr -->
// <ItemGroup>
// <PackageReference Include="Newtonsoft.Json" Version="12.0.1" />
// </ItemGroup>
// ```
//
// **Fixed Code**
// ```xml
// <!-- 13.0.1 is the patched version that resolves all known advisories of this package -->
// <ItemGroup>
// <PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
// </ItemGroup>
// ```
//</Desc>
//<HowToFix>
// Update the affected package to at least the patched version recommended,
// which resolves all known advisories for the package. It is not always the
// latest version (e.g. an issue in 4.0.2 might be fixed in 4.1.0 while 7.0.8
// exists).
//</HowToFix>
Open in the interactive Rules Explorer · All default rules
Security: all 39 items
- Software Composition Analysis (SCA) ND3120
- Transitive Software Composition Analysis (SCA) ND3121
- Don't hard-code secrets in constants ND3114
- Review credentials built from hard-coded values ND3115
- Don't use insecure deserializers ND3110
- Don't use weak hash algorithms (MD5, SHA1) ND3109
- Don't use DES/3DES/RC2 weak cipher algorithms ND3102
- Don't use weak password-based key derivation ND3123
- Don't use the ECB encryption mode ND3132
- Don't disable certificate validation ND3103
- Don't hard-code TLS/SSL protocol versions ND3122
- Review commands vulnerable to SQL injection ND3107
- Review data adapters vulnerable to SQL injection ND3108
- Review raw SQL built from composed strings ND3128
- Review LDAP filters composed from strings ND3137
- Don't enable external XML entity resolution (XXE) ND3111
- Review processes started with a composed arguments string ND3124
- Review web endpoints building file paths from their parameters ND3129
- Review custom archive extraction (Zip Slip) ND3135
- Review assemblies and types loaded from runtime-provided names ND3125
- Review web endpoints without [Authorize] nor [AllowAnonymous] ND3118
- Review state-changing endpoints opened to anonymous callers ND3130
- Review state-changing MVC actions without anti-forgery validation ND3119
- Review HTML-encoding bypasses ND3133
- Review explicitly disabled request validation ND3134
- Review redirects to a URL that is not validated as local ND3126
- Review request-influenced outbound HTTP calls (SSRF) ND3136
- Review insecure ASP.NET Core CORS policies and unguarded developer exception page ND3116
- Review cookies created without HttpOnly and Secure flags ND3117
- Review regular expressions without a match timeout (ReDoS) ND3112
- Review secrets compared with non-constant-time equality ND3113
- Review secrets passed to logging methods ND3127
- Review security operations that log nothing ND3131
- Don't use System.Random for security purposes ND3101
- Don't use CoSetProxyBlanket and CoInitializeSecurity ND3100
- Review publicly visible event handlers ND3104
- Pointers should not be publicly visible ND3105
- Seal methods that satisfy non-public interfaces ND3106
- Restrict sensitive APIs to reviewed components ND3138