Skip to content

Commit 47970b2

Browse files
Merge pull request #160 from contentstack/staging
DX | 06-04-2026 | Release
2 parents 8fc2b31 + a7c2042 commit 47970b2

File tree

8 files changed

+40
-24
lines changed

8 files changed

+40
-24
lines changed

.github/workflows/sca-scan.yml

Lines changed: 15 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,33 @@ name: Source Composition Analysis Scan
22
on:
33
pull_request:
44
types: [opened, synchronize, reopened]
5+
56
jobs:
67
security-sca:
78
runs-on: ubuntu-latest
89
steps:
910
- name: Checkout repository
1011
uses: actions/checkout@master
12+
1113
- name: Setup .NET Core @ Latest
1214
uses: actions/setup-dotnet@v1
1315
with:
1416
dotnet-version: "7.0.x"
17+
1518
- name: Run Dotnet Restore
16-
run: |
17-
dotnet restore
19+
run: dotnet restore
20+
21+
- name: Setup Snyk
22+
uses: snyk/actions/setup@master # just installs Snyk CLI, no deprecated dotnet action
23+
1824
- name: Run Snyk to check for vulnerabilities
19-
uses: snyk/actions/dotnet@master
25+
run: |
26+
snyk test \
27+
--file=Contentstack.Core/obj/project.assets.json \
28+
--fail-on=all \
29+
--json-file-output=snyk.json # ← writes snyk.json to disk
2030
env:
2131
SNYK_TOKEN: ${{ secrets.SNYK_TOKEN }}
22-
with:
23-
args: --file=Contentstack.Core/obj/project.assets.json --fail-on=all
24-
json: true
25-
continue-on-error: true
32+
continue-on-error: true # ← let pipeline continue even if vulns found
33+
2634
- uses: contentstack/sca-policy@main

.gitignore

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,5 @@ packages/
6666
*.userosscache
6767
*.sln.docstates
6868

69+
# Python
70+
Scripts/venv/

Contentstack.Core.Tests/Contentstack.Core.Tests.csproj

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
1+
<Project Sdk="Microsoft.NET.Sdk" ToolsVersion="15.0">
22

33
<PropertyGroup>
44
<TargetFramework>net7.0</TargetFramework>
@@ -27,6 +27,8 @@
2727
<DotNetCliToolReference Include="dotnet-reportgenerator-cli" Version="4.2.10" />
2828
<PackageReference Include="AutoFixture" Version="4.18.1" />
2929
<PackageReference Include="AutoFixture.AutoMoq" Version="4.18.1" />
30+
<PackageReference Include="System.Net.Http" Version="4.3.4" />
31+
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
3032
<PackageReference Include="Moq" Version="4.20.72" />
3133
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
3234
</ItemGroup>

Contentstack.Core.Tests/Helpers/TestDataHelper.cs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -187,16 +187,16 @@ static TestDataHelper()
187187
/// <summary>
188188
/// Gets a required configuration value and throws if not found
189189
/// </summary>
190-
/// <param name="key">Configuration key</param>
190+
/// <param name="configKey">Configuration key name</param>
191191
/// <returns>Configuration value</returns>
192192
/// <exception cref="InvalidOperationException">Thrown when configuration is missing</exception>
193-
private static string GetRequiredConfig(string key)
193+
private static string GetRequiredConfig(string configKey)
194194
{
195-
var value = ConfigurationManager.AppSettings[key];
195+
var value = ConfigurationManager.AppSettings[configKey];
196196
if (string.IsNullOrEmpty(value))
197197
{
198198
throw new InvalidOperationException(
199-
$"Required configuration '{key}' is missing from app.config. " +
199+
$"Required configuration '{configKey}' is missing from app.config. " +
200200
$"Please ensure all required keys are present in the <appSettings> section.");
201201
}
202202
return value;
@@ -205,12 +205,12 @@ private static string GetRequiredConfig(string key)
205205
/// <summary>
206206
/// Gets an optional configuration value with a default
207207
/// </summary>
208-
/// <param name="key">Configuration key</param>
208+
/// <param name="configKey">Configuration key name</param>
209209
/// <param name="defaultValue">Default value if not found</param>
210210
/// <returns>Configuration value or default</returns>
211-
private static string GetOptionalConfig(string key, string defaultValue = null)
211+
private static string GetOptionalConfig(string configKey, string defaultValue = null)
212212
{
213-
return ConfigurationManager.AppSettings[key] ?? defaultValue;
213+
return ConfigurationManager.AppSettings[configKey] ?? defaultValue;
214214
}
215215

216216
/// <summary>

Contentstack.Core.Unit.Tests/Contentstack.Core.Unit.Tests.csproj

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@
1818
</PackageReference>
1919
<PackageReference Include="AutoFixture" Version="4.18.1" />
2020
<PackageReference Include="AutoFixture.AutoMoq" Version="4.18.1" />
21+
<PackageReference Include="System.Net.Http" Version="4.3.4" />
22+
<PackageReference Include="System.Text.RegularExpressions" Version="4.3.1" />
2123
<PackageReference Include="Moq" Version="4.20.72" />
2224
<PackageReference Include="System.Configuration.ConfigurationManager" Version="9.0.0" />
2325
<PackageReference Include="Microsoft.Extensions.Options" Version="9.0.0" />

Scripts/generate_enhanced_html_report.py

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
- Expected vs Actual values
66
- HTTP Request details (including cURL)
77
- Response details
8-
No external dependencies - uses only Python standard library
8+
Uses defusedxml for secure XML parsing (XXE/DDoS-safe).
99
"""
1010

11-
import xml.etree.ElementTree as ET
11+
import defusedxml.ElementTree as ET
1212
import os
1313
import sys
1414
import re
@@ -158,9 +158,9 @@ def parse_trx(self):
158158
test_output = stdout_elem.text
159159
structured_output = self.parse_structured_output(test_output)
160160

161-
# Get test category
161+
# Get test category (find by id without dynamic XPath to avoid CWE-643)
162162
test_def_id = test_result.get('testId', '')
163-
test_def = root.find(f".//UnitTest[@id='{test_def_id}']", ns)
163+
test_def = next((el for el in root.findall('.//UnitTest', ns) if el.get('id') == test_def_id), None)
164164
category = 'General'
165165
if test_def is not None:
166166
test_method = test_def.find('.//TestMethod', ns)

Scripts/generate_html_report.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#!/usr/bin/env python3
22
"""
33
HTML Test Report Generator for .NET Test Results
4-
Converts .trx files to beautiful HTML reports
5-
No external dependencies - uses only Python standard library
4+
Converts .trx files to beautiful HTML reports.
5+
Uses defusedxml for secure XML parsing (XXE/DDoS-safe).
66
"""
77

8-
import xml.etree.ElementTree as ET
8+
import defusedxml.ElementTree as ET
99
import os
1010
import sys
1111
from datetime import datetime
@@ -78,9 +78,9 @@ def parse_trx(self):
7878
if stacktrace_elem is not None:
7979
error_stacktrace = stacktrace_elem.text
8080

81-
# Get test category
81+
# Get test category (find by id without dynamic XPath to avoid CWE-643)
8282
test_def_id = test_result.get('testId', '')
83-
test_def = root.find(f".//UnitTest[@id='{test_def_id}']", ns)
83+
test_def = next((el for el in root.findall('.//UnitTest', ns) if el.get('id') == test_def_id), None)
8484
category = 'General'
8585
if test_def is not None:
8686
test_method = test_def.find('.//TestMethod', ns)

Scripts/requirements.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# Secure XML parsing (fixes Snyk CWE-611 Insecure Xml Parser / XXE)
2+
defusedxml>=0.7.1

0 commit comments

Comments
 (0)