Skip to content

Commit e7d569b

Browse files
author
Ajay kumar
committed
[Blog] [Ajay]: Add blog on vlenrability detection
1 parent 327eb29 commit e7d569b

File tree

7 files changed

+272
-29
lines changed

7 files changed

+272
-29
lines changed

TestArena/Blog/Common/NavigationUtils/SiteMap.cs

Lines changed: 35 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -6,47 +6,53 @@ public static class SiteMap
66
{
77
public static List<PageInfo> Pages { get; } =
88
[
9-
new("Intro to PACT for .NET Core: API contract testing",
10-
"/blog/contract-testing-pact-net-intro",
11-
new DateTime(2024, 12, 14),
12-
"images/blog/pact/intro/header_landscape.png",
9+
new("Intro to PACT for .NET Core: API contract testing",
10+
"/blog/contract-testing-pact-net-intro",
11+
new DateTime(2024, 12, 14),
12+
"images/blog/pact/intro/header_landscape.png",
1313
["PACT", "API"]),
1414

15-
new("Intro to PACT for .NET Core: Events based systems",
16-
"/blog/contract-testing-in-pact-with-events",
17-
new DateTime(2024, 12, 28),
18-
"images/blog/pact/events-demo/contract-testing-events.webp",
15+
new("Intro to PACT for .NET Core: Events based systems",
16+
"/blog/contract-testing-in-pact-with-events",
17+
new DateTime(2024, 12, 28),
18+
"images/blog/pact/events-demo/contract-testing-events.webp",
1919
["PACT", "Events"]),
2020

21-
new("Intro to PACT for .NET Core: Integration with PactFlow",
22-
"/blog/integration-with-pactflow",
23-
new DateTime(2025, 1, 11),
24-
"images/blog/pact/pact-broker/blog_header.png",
21+
new("Intro to PACT for .NET Core: Integration with PactFlow",
22+
"/blog/integration-with-pactflow",
23+
new DateTime(2025, 1, 11),
24+
"images/blog/pact/pact-broker/blog_header.png",
2525
["PACT", "PactFlow"]),
2626

27-
new("Integration testing for dotnet core APIs: Introduction",
28-
"/blog/integration-testing-in-dotnet-intro",
29-
new DateTime(2025, 1, 25),
30-
"images/blog/integration-testing/intro/banner.png",
27+
new("Integration testing for dotnet core APIs: Introduction",
28+
"/blog/integration-testing-in-dotnet-intro",
29+
new DateTime(2025, 1, 25),
30+
"images/blog/integration-testing/intro/banner.png",
3131
["Integration Testing", "DotNet"]),
3232

33-
new("Integration testing for dotnet core APIs: Handling database",
34-
"/blog/integration-testing-in-dotnet-with-database",
35-
new DateTime(2025, 2, 8),
36-
"images/blog/integration-testing/handling-database/banner.png",
33+
new("Integration testing for dotnet core APIs: Handling database",
34+
"/blog/integration-testing-in-dotnet-with-database",
35+
new DateTime(2025, 2, 8),
36+
"images/blog/integration-testing/handling-database/banner.png",
3737
["Integration Testing", "Database"]),
3838

39-
new("Integration testing for dotnet core APIs: Handling APIs behind authentication",
40-
"/blog/integration-testing-in-dotnet-with-auth",
41-
new DateTime(2025, 2, 22),
42-
"images/blog/integration-testing/handling-auth/banner.png",
39+
new("Integration testing for dotnet core APIs: Handling APIs behind authentication",
40+
"/blog/integration-testing-in-dotnet-with-auth",
41+
new DateTime(2025, 2, 22),
42+
"images/blog/integration-testing/handling-auth/banner.png",
4343
["Integration Testing", "Authentication"]),
4444

45-
new("Integration testing for dotnet core APIs: Handling 3rd party service calls using wiremock",
46-
"/blog/integration-testing-in-dotnet-with-external-services",
47-
new DateTime(2025, 3, 8),
48-
"images/blog/integration-testing/handling-external-services/banner.png",
49-
["Integration Testing", "WireMock"])
45+
new("Integration testing for dotnet core APIs: Handling 3rd party service calls using wiremock",
46+
"/blog/integration-testing-in-dotnet-with-external-services",
47+
new DateTime(2025, 3, 8),
48+
"images/blog/integration-testing/handling-external-services/banner.png",
49+
["Integration Testing", "WireMock"]),
50+
51+
new("Enforcing package auditing in .NET",
52+
"/blog/package-vulnerability-detection-in-dotnet",
53+
new DateTime(2025, 3, 22),
54+
"images/blog/vulnerability/auditing/banner.png",
55+
["Security", "Vulnerability", ".NET"]),
5056
];
5157
}
5258

Lines changed: 237 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,237 @@
1+
@page "/blog/package-vulnerability-detection-in-dotnet"
2+
@using TestArena.Blog.Common
3+
@using TestArena.Blog.Common.NavigationUtils
4+
5+
@code{
6+
PageInfo currentPage = SiteMap.Pages.FirstOrDefault(x => x.RelativePath == "/blog/package-vulnerability-detection-in-dotnet")!;
7+
}
8+
9+
<BlogContainer>
10+
<Header
11+
Title="@currentPage.Header"
12+
Description="@currentPage.Header"
13+
Image="@currentPage.ArticleImage"
14+
PublishedOn="@currentPage.PublishedOn"
15+
Authors="Ajay kumar"/>
16+
17+
<Section Heading="Summary">
18+
<p>As developers, we often trust third-party NuGet packages to accelerate development—but with that trust comes risk. Many of these packages may carry <b>known security vulnerabilities</b>, and if left unchecked, they can become a backdoor into your application. This is where <b>vulnerability detection in .NET</b> projects becomes critical.</p>
19+
20+
<p>Starting with .NET SDK 5.0.200, Microsoft introduced a built-in auditing command:</p>
21+
<CodeSnippet Number="1" Language="Bash" Description="Command to check for vulnerable packages">
22+
dotnet list package --vulnerable
23+
</CodeSnippet>
24+
25+
<p>This command scans both direct and transitive NuGet dependencies for known security issues using Microsoft’s advisory database. It flags packages with vulnerabilities, categorizing them by severity (Low to Critical), and provides advisory URLs to investigate further.</p>
26+
27+
<p>But detection is only step one.</p>
28+
29+
<p>Vulnerability checks should be automated into your build or deployment workflows. Failing a build when vulnerabilities are found prevents insecure code from reaching production. Simple shell or PowerShell scripts can be used to enforce this in local or CI pipelines without relying on GitHub or external tools.</p>
30+
31+
<p>Equally important is the role of the .csproj file—this file acts as the source of truth for all your package references. A single vulnerable package listed here, directly or indirectly, can compromise your entire application.</p>
32+
</Section>
33+
34+
<Section Heading="NugetAudit to the rescue!">
35+
<p>
36+
NuGet 6.8 introduced the <code>NuGetAudit</code> MSBuild property, which enhances vulnerability detection during build time. When set to <code>true</code>, NuGetAudit performs an audit of your project's NuGet dependencies and generates warnings for any detected vulnerabilities. This allows you to identify and address security issues before your application is deployed.
37+
</p>
38+
39+
<p>
40+
We are using a sample repo here which which uses below packages
41+
<ul>
42+
<li><code>Refit</code> version <b><i>7.2.1</i></b> which has <b>Critical</b> vulnerability</li>
43+
<li><code>Newtonsoft.Json</code> version <b><i>12.0.3</i></b> which has <b>High</b> vulnerability</li>
44+
</ul>
45+
</p>
46+
<p>To enable <code>NuGetAudit</code>, we can add the following to our <code>.csproj</code> file:</p>
47+
<CodeSnippet Number="2" Language="xml" Description="Example .csproj file with NuGetAudit enabled">
48+
&lt;Project Sdk="Microsoft.NET.Sdk"&gt;
49+
&lt;PropertyGroup&gt;
50+
&lt;TargetFramework&gt;net8.0&lt;/TargetFramework&gt;
51+
&lt;ImplicitUsings&gt;enable&lt;/ImplicitUsings&gt;
52+
&lt;Nullable&gt;enable&lt;/Nullable&gt;
53+
&lt;NugetAudit&gt;true&lt;/NugetAudit&gt;
54+
&lt;/PropertyGroup&gt;
55+
56+
&lt;ItemGroup&gt;
57+
&lt;PackageReference Include="Newtonsoft.Json" Version="12.0.3" /&gt;
58+
&lt;PackageReference Include="Refit" Version="7.2.1" /&gt;
59+
&lt;/ItemGroup&gt;
60+
&lt;/Project&gt;
61+
</CodeSnippet>
62+
63+
<p>
64+
When <code>NuGetAudit</code> is enabled, the build process will generate warnings for any NuGet packages with known vulnerabilities. These warnings will include information about the vulnerability, such as the severity and the affected package version.
65+
</p>
66+
67+
<p>
68+
You can configure the level of detail in the NuGet audit warnings by using the <code>NuGetAuditLevel</code> property. This property accepts the following values:
69+
</p>
70+
<ul>
71+
<li><code>None</code>: No audit warnings are displayed.</li>
72+
<li><code>Low</code>: Only warnings for vulnerabilities with a severity of Low or higher are displayed. This is <b>default</b> value.</li>
73+
<li><code>Moderate</code>: Only warnings for vulnerabilities with a severity of Moderate or higher are displayed.</li>
74+
<li><code>High</code>: Only warnings for vulnerabilities with a severity of High or Critical are displayed.</li>
75+
<li><code>Critical</code>: Only warnings for vulnerabilities with a severity of Critical are displayed.</li>
76+
</ul>
77+
</Section>
78+
79+
<Section Heading="Lets explore some more scenarios">
80+
<Section Heading="Disabling the audit mode" Level="5">
81+
<p>When We disbale the auditing by setting <code>NuGetAudit</code> To <b>false</b> and try to <code>build / restore</code> </p>
82+
83+
<CodeSnippet Number="2" Language="xml" Description="Example .csproj file with NuGetAudit disabled">
84+
&lt;Project Sdk="Microsoft.NET.Sdk"&gt;
85+
&lt;PropertyGroup&gt;
86+
&lt;TargetFramework&gt;net8.0&lt;/TargetFramework&gt;
87+
&lt;ImplicitUsings&gt;enable&lt;/ImplicitUsings&gt;
88+
&lt;Nullable&gt;enable&lt;/Nullable&gt;
89+
&lt;NugetAudit&gt;false&lt;/NugetAudit&gt;
90+
&lt;/PropertyGroup&gt;
91+
92+
&lt;ItemGroup&gt;
93+
&lt;PackageReference Include="Newtonsoft.Json" Version="12.0.3" /&gt;
94+
&lt;PackageReference Include="Refit" Version="7.2.1" /&gt;
95+
&lt;/ItemGroup&gt;
96+
&lt;/Project&gt;
97+
</CodeSnippet>
98+
99+
<BlogImage ImagePath="/images/blog/vulnerability/auditing/Build Passed with audit disabled.png" Description="Build passed" Number="1"/>
100+
</Section>
101+
102+
<Section Heading="Eabling the audit mode" Level="5">
103+
<p>Lets enable the auditing by setting <code>NuGetAudit</code> To <b>true</b> and try to <code>build / restore</code> </p>
104+
105+
<CodeSnippet Number="3" Language="xml" Description="Example .csproj file with NuGetAudit enabled">
106+
&lt;Project Sdk="Microsoft.NET.Sdk"&gt;
107+
&lt;PropertyGroup&gt;
108+
&lt;TargetFramework&gt;net8.0&lt;/TargetFramework&gt;
109+
&lt;ImplicitUsings&gt;enable&lt;/ImplicitUsings&gt;
110+
&lt;Nullable&gt;enable&lt;/Nullable&gt;
111+
&lt;NugetAudit&gt;true&lt;/NugetAudit&gt;
112+
&lt;/PropertyGroup&gt;
113+
114+
&lt;ItemGroup&gt;
115+
&lt;PackageReference Include="Newtonsoft.Json" Version="12.0.3" /&gt;
116+
&lt;PackageReference Include="Refit" Version="7.2.1" /&gt;
117+
&lt;/ItemGroup&gt;
118+
&lt;/Project&gt;
119+
</CodeSnippet>
120+
121+
<BlogImage ImagePath="/images/blog/vulnerability/auditing/Build failed with audit enabled.png" Description="Build passed with warnings" Number="2"/>
122+
123+
<p>As we can see the build is warning about both the critical and high severity level packages.</p>
124+
<p>Depending on security guidelines we may want to only flag certain severity level</p>
125+
</Section>
126+
127+
<Section Heading="Setting the severity level" Level="5">
128+
<p>Depending on security guidelines for out project we may want to only flag certain severity level and above. For this article lets assume, we only want to warn about critial vulnerabilities and leave the rest.</p>
129+
130+
<p>Lets set the severity level for our audit by setting <code>NuGetAudit</code> To <b>true</b> and try to <code>build / restore</code> </p>
131+
132+
<CodeSnippet Number="4" Language="xml" Description="Example .csproj file with NugetAuditLevel defined">
133+
&lt;Project Sdk="Microsoft.NET.Sdk"&gt;
134+
&lt;PropertyGroup&gt;
135+
&lt;TargetFramework&gt;net8.0&lt;/TargetFramework&gt;
136+
&lt;ImplicitUsings&gt;enable&lt;/ImplicitUsings&gt;
137+
&lt;Nullable&gt;enable&lt;/Nullable&gt;
138+
&lt;NugetAudit&gt;true&lt;/NugetAudit&gt;
139+
&lt;NugetAuditLevel&gt;critical&lt;/NugetAuditLevel&gt;
140+
&lt;/PropertyGroup&gt;
141+
142+
&lt;ItemGroup&gt;
143+
&lt;PackageReference Include="Newtonsoft.Json" Version="12.0.3" /&gt;
144+
&lt;PackageReference Include="Refit" Version="7.2.1" /&gt;
145+
&lt;/ItemGroup&gt;
146+
&lt;/Project&gt;
147+
</CodeSnippet>
148+
149+
<BlogImage
150+
ImagePath="/images/blog/vulnerability/auditing/Build passed with audit enabled and severity level defined.png"
151+
Description="Build passed with critical severity level warnings"
152+
Number="3"/>
153+
154+
<p>As we can see the build is warning about only the critical severity level package(s).</p>
155+
156+
</Section>
157+
158+
<Section Heading="Enforcing build failure for vulnerabilities" Level="5">
159+
<p>Now, warning are good but they can be ignored/missed allowing vulnerabilities to creep into the production code. To prevent this, there is another msbuild property <code>WarningsAsErrors</code> that can help by treating specified warnings codes as errors resulting in build failure. Refer the below table to such warning codes</p>
160+
<table class="table table-bordered">
161+
<thead class="thead-dark">
162+
<tr>
163+
<th>Warning Code</th>
164+
<th>Reason</th>
165+
</tr>
166+
</thead>
167+
<tbody>
168+
<tr>
169+
<td>NU1900</td>
170+
<td>Error communicating with package source, while getting vulnerability information.</td>
171+
</tr>
172+
<tr>
173+
<td>NU1901</td>
174+
<td>Package with low severity detected</td>
175+
</tr>
176+
<tr>
177+
<td>NU1902</td>
178+
<td>Package with moderate severity detected</td>
179+
</tr>
180+
<tr>
181+
<td>NU1903</td>
182+
<td>Package with high severity detected</td>
183+
</tr>
184+
<tr>
185+
<td>NU1904</td>
186+
<td>Package with critical severity detected</td>
187+
</tr>
188+
<tr>
189+
<td>NU1905</td>
190+
<td>An audit source does not provide a vulnerability database</td>
191+
</tr>
192+
</tbody>
193+
</table>
194+
195+
<p>Lets set critical warning as error for our audit by setting <code>WarningsAsErrors</code> To <b>true</b> and try to <code>build / restore</code> </p>
196+
197+
<CodeSnippet Number="5" Language="xml" Description="Example .csproj file with WarningsAsErrors defined">
198+
&lt;Project Sdk="Microsoft.NET.Sdk"&gt;
199+
&lt;PropertyGroup&gt;
200+
&lt;TargetFramework&gt;net8.0&lt;/TargetFramework&gt;
201+
&lt;ImplicitUsings&gt;enable&lt;/ImplicitUsings&gt;
202+
&lt;Nullable&gt;enable&lt;/Nullable&gt;
203+
&lt;NugetAudit&gt;true&lt;/NugetAudit&gt;
204+
&lt;NugetAuditLevel&gt;critical&lt;/NugetAuditLevel&gt;
205+
&lt;WarningsAsErrors&gt;NU1904;&lt;/WarningsAsErrors&gt;
206+
&lt;/PropertyGroup&gt;
207+
208+
&lt;ItemGroup&gt;
209+
&lt;PackageReference Include="Newtonsoft.Json" Version="12.0.3" /&gt;
210+
&lt;PackageReference Include="Refit" Version="7.2.1" /&gt;
211+
&lt;/ItemGroup&gt;
212+
&lt;/Project&gt;
213+
</CodeSnippet>
214+
215+
<BlogImage
216+
ImagePath="/images/blog/vulnerability/auditing/Build failure with critical vulnerability.png"
217+
Description="Build failure with critical vulnerability"
218+
Number="4"/>
219+
220+
<p>As we can see the build is warning about only the critical severity level package(s).</p>
221+
222+
</Section>
223+
</Section>
224+
225+
<Section Heading="Conclusion">
226+
<p>In conclusion, vulnerability detection in .NET projects is a critical aspect of modern software development. By leveraging the built-in auditing command and the NuGetAudit MSBuild property, developers can proactively identify and address security vulnerabilities in their applications. This not only helps to protect sensitive data but also ensures compliance with security standards and best practices.</p>
227+
228+
<p>By integrating these tools into your development workflow, you can significantly reduce the risk of security breaches and enhance the overall security posture of your .NET applications.</p>
229+
<p>Integrating these tools into your CI/CD build pipelines ensures that vulnerabilities are detected and addressed early, preventing insecure code from being deployed to production systems.</p>
230+
</Section>
231+
232+
<hr/>
233+
<p>Thats about it for this article. Hope you liked it.</p>
234+
235+
<EndNotes/>
236+
237+
</BlogContainer>
83.3 KB
Loading
263 KB
Loading
434 KB
Loading
181 KB
Loading
552 KB
Loading

0 commit comments

Comments
 (0)