Skip to content

Commit fcc5f22

Browse files
authored
ci: update OWASP ZAP workflow and improve SQL Server readiness checks (#9) (#10)
1 parent 5fb540b commit fcc5f22

2 files changed

Lines changed: 41 additions & 29 deletions

File tree

.github/workflows/owasp-zap.yml

Lines changed: 33 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -31,19 +31,19 @@ jobs:
3131
--health-interval 15s
3232
--health-timeout 10s
3333
--health-retries 10
34-
--health-start-period 40s
34+
--health-start-period 60s
3535
3636
steps:
3737
- name: Checkout repository
38-
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
38+
uses: actions/checkout@v4
3939

4040
- name: Setup .NET
41-
uses: actions/setup-dotnet@c2fa09f4bde5ebb9d1777cf28262a3eb3db3ced7 # v5.2.0
41+
uses: actions/setup-dotnet@v4
4242
with:
4343
dotnet-version: 8.0.x
4444

4545
- name: Cache NuGet packages
46-
uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
46+
uses: actions/cache@v4
4747
with:
4848
path: ~/.nuget/packages
4949
key: ${{ runner.os }}-nuget-${{ hashFiles('**/*.csproj') }}
@@ -54,16 +54,23 @@ jobs:
5454
dotnet restore CompanyManagementSystem.sln
5555
dotnet publish ERP.PL/ERP.PL.csproj --configuration Release --no-restore --output ./publish
5656
57-
- name: Wait for SQL Server to be ready
57+
- name: Wait for SQL Server to be truly ready
5858
run: |
59-
echo "Waiting for SQL Server to accept connections..."
60-
for i in $(seq 1 30); do
61-
if nc -z localhost 1433 2>/dev/null; then
62-
echo "SQL Server is accepting connections!"
59+
echo "Waiting for SQL Server to accept SQL queries..."
60+
for i in $(seq 1 40); do
61+
if /opt/mssql-tools18/bin/sqlcmd -S localhost,1433 -U sa -P 'TestP@ssw0rd123!' -C -Q 'SELECT 1' -b > /dev/null 2>&1; then
62+
echo "SQL Server is ready! (attempt $i)"
6363
break
64+
elif /opt/mssql-tools/bin/sqlcmd -S localhost,1433 -U sa -P 'TestP@ssw0rd123!' -Q 'SELECT 1' -b > /dev/null 2>&1; then
65+
echo "SQL Server is ready via mssql-tools! (attempt $i)"
66+
break
67+
fi
68+
if [ $i -eq 40 ]; then
69+
echo "::error::SQL Server did not become ready in time."
70+
exit 1
6471
fi
65-
echo "Attempt $i: SQL Server not ready yet..."
66-
sleep 3
72+
echo "Attempt $i/40: SQL Server not ready yet, waiting 5s..."
73+
sleep 5
6774
done
6875
6976
- name: Start application
@@ -73,7 +80,8 @@ jobs:
7380
ConnectionStrings__DefaultConnection: "Server=localhost,1433;Database=ERPDB_ZAP;User Id=sa;Password=TestP@ssw0rd123!;TrustServerCertificate=True;"
7481
Database__ApplyMigrationsOnStartup: "true"
7582
Seed__Mode: "None"
76-
Logging__LogLevel__Default: "Warning"
83+
Logging__LogLevel__Default: "Information"
84+
Logging__LogLevel__Microsoft_EntityFrameworkCore: "Warning"
7785
run: |
7886
cd publish
7987
dotnet ERP.PL.dll > ../app.log 2>&1 &
@@ -85,34 +93,37 @@ jobs:
8593
echo "Waiting for application to become healthy..."
8694
READY=false
8795
for i in $(seq 1 60); do
88-
if curl -sf -o /dev/null -m 5 http://localhost:5000/health 2>/dev/null; then
89-
echo "Application is healthy and ready! (attempt $i)"
96+
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -m 5 http://localhost:5000/health 2>/dev/null || echo "000")
97+
if [ "$HTTP_CODE" = "200" ]; then
98+
echo "Application is healthy and ready! (attempt $i, HTTP $HTTP_CODE)"
9099
READY=true
91100
break
92101
fi
93102
94-
# Check if process is still running
95103
if ! kill -0 $APP_PID 2>/dev/null; then
96104
echo "::error::Application process exited unexpectedly!"
97-
echo "=== Application Logs ==="
105+
echo "=== Full Application Logs ==="
98106
cat app.log || true
99107
exit 1
100108
fi
101109
102-
echo "Attempt $i/60: Waiting for health check..."
110+
echo "Attempt $i/60: health check returned HTTP $HTTP_CODE, waiting 5s..."
103111
sleep 5
104112
done
105113
106114
if [ "$READY" != "true" ]; then
107115
echo "::error::Application did not become healthy within 5 minutes"
108-
echo "=== Application Logs ==="
109-
tail -100 app.log || true
116+
echo "=== Full Application Logs ==="
117+
tail -150 app.log || true
110118
kill $APP_PID 2>/dev/null || true
111119
exit 1
112120
fi
113121
122+
echo "Verifying port 5000 is listening..."
123+
ss -tlnp | grep :5000 || netstat -tlnp | grep :5000 || true
124+
114125
- name: Run OWASP ZAP Baseline Scan
115-
uses: zaproxy/action-baseline@de8ad967d3548d44ef623df22cf95c3b0baf8b25 # v0.15.0
126+
uses: zaproxy/action-baseline@v0.14.0
116127
with:
117128
target: "http://localhost:5000"
118129
rules_file_name: ".zap/rules.tsv"
@@ -132,15 +143,15 @@ jobs:
132143
133144
- name: Upload application logs
134145
if: always()
135-
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
146+
uses: actions/upload-artifact@v4
136147
with:
137148
name: app-logs
138149
path: app.log
139150
if-no-files-found: ignore
140151

141152
- name: Upload ZAP Report
142153
if: always()
143-
uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
154+
uses: actions/upload-artifact@v4
144155
with:
145156
name: zap-security-report
146157
path: |

ERP.PL/Program.cs

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -149,9 +149,11 @@ public static async Task Main(string[] args)
149149
builder.Services.AddAntiforgery(options =>
150150
{
151151
options.HeaderName = "X-CSRF-TOKEN";
152-
// Use HTTPS only in production; allow HTTP in development
152+
// Use HTTPS only in production; allow HTTP in development/testing
153153
options.Cookie.HttpOnly = true;
154-
options.Cookie.SecurePolicy = CookieSecurePolicy.Always;
154+
options.Cookie.SecurePolicy = builder.Environment.IsProduction()
155+
? CookieSecurePolicy.Always
156+
: CookieSecurePolicy.SameAsRequest;
155157
options.Cookie.SameSite = SameSiteMode.Strict;
156158
});
157159

@@ -265,7 +267,9 @@ public static async Task Main(string[] args)
265267
builder.Services.ConfigureApplicationCookie(options =>
266268
{
267269
options.Cookie.HttpOnly = true; // Prevent XSS access to cookie
268-
options.Cookie.SecurePolicy = CookieSecurePolicy.Always; // HTTPS only
270+
options.Cookie.SecurePolicy = builder.Environment.IsProduction()
271+
? CookieSecurePolicy.Always
272+
: CookieSecurePolicy.SameAsRequest;
269273
options.Cookie.SameSite = SameSiteMode.Strict; // Prevent CSRF
270274
options.ExpireTimeSpan = TimeSpan.FromMinutes(30); // Session timeout
271275
options.SlidingExpiration = true; // Extend on activity
@@ -430,10 +434,7 @@ public static async Task Main(string[] args)
430434
pattern: "{controller=Home}/{action=Index}/{id?}");
431435
#endregion
432436

433-
if (!app.Environment.IsEnvironment("Testing"))
434-
{
435-
await ApplyDatabaseMigrationsAndSeedAsync(app);
436-
}
437+
await ApplyDatabaseMigrationsAndSeedAsync(app);
437438

438439
app.Run();
439440
}

0 commit comments

Comments
 (0)