La sécurité des applications est devenue un enjeu crucial dans le développement moderne. Pour les développeurs .NET, l'automatisation des tests de pénétration est essentielle pour détecter rapidement les vulnérabilités avant qu'elles n'atteignent la production. OWASP ZAP (Zed Attack Proxy) est un outil open source puissant qui s'intègre parfaitement dans un pipeline CI/CD .NET pour effectuer des scans de sécurité automatisés.
Concepts fondamentaux du pentest automatisé
OWASP ZAP fonctionne comme un proxy qui intercepte et analyse le trafic entre le client et l'application. Il peut être utilisé de deux façons principales :
- Mode proxy manuel pour tester interactivement
- Mode daemon automatisé via API pour l'intégration continue
Architecture d'intégration avec .NET
Pour automatiser les tests avec une application ASP.NET Core, nous utiliserons :
- ZAP API Client via NuGet
- TestServer d'ASP.NET Core pour héberger l'application
- xUnit pour orchestrer les tests
Implémentation en C#
Commençons par installer les packages nécessaires :
dotnet add package OWASPZAPDotNetAPI
dotnet add package Microsoft.AspNetCore.TestHost
dotnet add package xunit
Voici une classe helper pour configurer ZAP :
public class ZapScanner
{
private readonly ClientApi _api;
private readonly string _targetUrl;
public ZapScanner(string zapUrl, string apiKey, string targetUrl)
{
_api = new ClientApi(zapUrl, apiKey);
_targetUrl = targetUrl;
}
public async Task StartScanAsync()
{
// Démarrer une nouvelle session
await _api.Core.NewSessionAsync();
// Configurer le contexte de scan
var contextId = await _api.Context.NewContextAsync("TestContext");
await _api.Context.IncludeInContextAsync("TestContext", _targetUrl);
// Lancer le scan actif
var scanId = await _api.Ascan.ScanAsync(_targetUrl, "true", "false", null, null, null);
// Attendre la fin du scan
while (int.Parse(await _api.Ascan.StatusAsync(scanId)) < 100)
{
await Task.Delay(2000);
}
}
public async Task> GetAlertsAsync()
{
return await _api.Core.AlertsAsync(_targetUrl);
}
}
Intégration avec ASP.NET Core
Créons une classe de test qui démarre notre application et lance le scan :
public class SecurityTests : IClassFixture>
{
private readonly WebApplicationFactory _factory;
private readonly ZapScanner _scanner;
public SecurityTests(WebApplicationFactory factory)
{
_factory = factory;
// Configurer ZAP
_scanner = new ZapScanner(
"http://localhost:8080",
"api-key-here",
"http://localhost:5000");
}
[Fact]
public async Task Application_Should_Not_Have_HighRiskVulnerabilities()
{
// Arrange
using var server = _factory.CreateServer();
// Act
await _scanner.StartScanAsync();
var alerts = await _scanner.GetAlertsAsync();
// Assert
var highRiskAlerts = alerts.Where(a => a.Risk == "High").ToList();
Assert.Empty(highRiskAlerts);
}
}
Configuration du pipeline CI/CD
Voici un exemple de configuration Azure DevOps pour intégrer les tests ZAP :
trigger:
- main
pool:
vmImage: 'ubuntu-latest'
steps:
- task: DockerInstaller@0
inputs:
dockerVersion: '20.10.x'
- script: |
docker pull owasp/zap2docker-stable
docker run -d -p 8080:8080 -p 8090:8090 owasp/zap2docker-stable zap.sh -daemon -host 0.0.0.0 -port 8080
displayName: 'Start ZAP'
- task: DotNetCoreCLI@2
inputs:
command: 'test'
projects: '/Tests/.csproj'
arguments: '--configuration Release'
displayName: 'Run Security Tests'
Bonnes pratiques et recommandations
- Utilisez des règles personnalisées pour réduire les faux positifs
- Configurez des seuils d'acceptation appropriés selon le contexte
- Intégrez les rapports de scan dans votre processus de revue de code
- Maintenez une liste blanche d'URLs à exclure du scan
Gestion des erreurs et performance
public class ZapScannerOptions
{
public int ScanTimeoutMinutes { get; set; } = 30;
public int RetryAttempts { get; set; } = 3;
public int DelayBetweenRetries { get; set; } = 5000;
}
public async Task StartScanWithRetryAsync(ZapScannerOptions options)
{
var attempts = 0;
while (attempts < options.RetryAttempts)
{
try
{
using var cts = new CancellationTokenSource(
TimeSpan.FromMinutes(options.ScanTimeoutMinutes));
await StartScanAsync(cts.Token);
break;
}
catch (Exception ex)
{
attempts++;
if (attempts >= options.RetryAttempts)
throw new ZapScanException("Scan failed after maximum retries", ex);
await Task.Delay(options.DelayBetweenRetries);
}
}
}
Validation et tests
Implémentez des tests de validation pour vérifier la configuration de ZAP :
[Fact]
public async Task ZapScanner_ShouldBeConfiguredCorrectly()
{
// Arrange
var scanner = new ZapScanner("http://localhost:8080", "api-key", "http://target");
// Act
var status = await scanner.GetStatusAsync();
// Assert
Assert.True(status.IsRunning);
Assert.Equal("2.12.0", status.Version);
}
Conclusion
L'automatisation des tests de sécurité avec OWASP ZAP dans un environnement .NET permet de :
- Détecter rapidement les vulnérabilités de sécurité
- Intégrer les tests de sécurité dans le pipeline CI/CD
- Maintenir un niveau de sécurité constant
- Réduire les coûts liés aux audits de sécurité manuels
En suivant les bonnes pratiques et en utilisant les outils appropriés, vous pouvez créer un processus robuste de tests de sécurité automatisés pour vos applications .NET.