Dans le monde du développement .NET moderne, la sécurité des applications est devenue une préoccupation majeure. Les SIEM (Security Information and Event Management) et la détection d'intrusion représentent des composants essentiels de toute stratégie de cybersécurité robuste. Cet article explore comment implémenter ces systèmes efficacement dans un environnement .NET, en utilisant les dernières fonctionnalités de C# 12 et .NET 8.
Fondamentaux du SIEM et de la détection d'intrusion en .NET
Un SIEM collecte, analyse et corrèle les événements de sécurité à travers l'infrastructure IT. Dans le contexte .NET, cela implique la surveillance des logs applicatifs, des événements système et des activités utilisateurs.
Architecture de base d'un système SIEM en .NET
public class SiemConfiguration
{
public string LogStoragePath { get; set; }
public TimeSpan RetentionPeriod { get; set; }
public int AlertThreshold { get; set; }
}
public interface ISiemCollector
{
Task CollectLogsAsync(DateTime startTime, DateTime endTime);
Task ProcessEventsAsync(IEnumerable events);
}
public class SecurityEvent
{
public DateTime Timestamp { get; set; }
public string Source { get; set; }
public EventSeverity Severity { get; set; }
public string Message { get; set; }
}
Implémentation de la détection d'intrusion
Voici un exemple d'implémentation d'un détecteur d'intrusion basique en C# :
public class IntrusionDetector
{
private readonly ILogger _logger;
private readonly Dictionary _failedLoginAttempts;
private readonly int _maxFailedAttempts;
public IntrusionDetector(ILogger logger, int maxFailedAttempts = 5)
{
_logger = logger;
_failedLoginAttempts = new Dictionary();
_maxFailedAttempts = maxFailedAttempts;
}
public async Task DetectIntrusion(string ipAddress, string userId)
{
var key = $"{ipAddress}_{userId}";
if (!_failedLoginAttempts.ContainsKey(key))
{
_failedLoginAttempts[key] = 1;
return false;
}
_failedLoginAttempts[key]++;
if (_failedLoginAttempts[key] >= _maxFailedAttempts)
{
await RaiseAlert(ipAddress, userId);
return true;
}
return false;
}
private async Task RaiseAlert(string ipAddress, string userId)
{
var alert = new SecurityAlert
{
Timestamp = DateTime.UtcNow,
Type = AlertType.BruteForceAttempt,
Source = ipAddress,
UserId = userId
};
_logger.LogWarning($"Intrusion détectée pour IP: {ipAddress}, User: {userId}");
await NotifySecurityTeam(alert);
}
}
Intégration avec ASP.NET Core
Pour intégrer le système de détection dans une application ASP.NET Core :
public class SecurityMiddleware
{
private readonly RequestDelegate _next;
private readonly IntrusionDetector _detector;
public SecurityMiddleware(RequestDelegate next, IntrusionDetector detector)
{
_next = next;
_detector = detector;
}
public async Task InvokeAsync(HttpContext context)
{
var ipAddress = context.Connection.RemoteIpAddress?.ToString();
var path = context.Request.Path.Value;
if (await _detector.DetectSuspiciousActivity(ipAddress, path))
{
context.Response.StatusCode = StatusCodes.Status403Forbidden;
return;
}
await _next(context);
}
}
Bonnes pratiques de logging sécurisé
- Utiliser des niveaux de log appropriés
- Éviter de logger des données sensibles
- Implémenter une rotation des logs
- Centraliser la collecte des logs
public class SecureLogger : ILogger
{
private readonly string _name;
private readonly LoggerConfiguration _config;
public SecureLogger(string name, LoggerConfiguration config)
{
_name = name;
_config = config;
}
public void Log(LogLevel logLevel, EventId eventId, TState state,
Exception exception, Func formatter)
{
if (!IsEnabled(logLevel)) return;
var message = formatter(state, exception);
var sanitizedMessage = SanitizeMessage(message);
// Logging sécurisé avec rotation et chiffrement
using var scope = new SecurityContext();
scope.LogSecurely(sanitizedMessage, logLevel);
}
}
Tests et validation
[Fact]
public async Task IntrusionDetector_Should_DetectBruteForceAttempt()
{
// Arrange
var logger = new Mock>();
var detector = new IntrusionDetector(logger.Object);
var ipAddress = "192.168.1.1";
var userId = "testUser";
// Act
for (int i = 0; i < 5; i++)
{
await detector.DetectIntrusion(ipAddress, userId);
}
// Assert
logger.Verify(x => x.LogWarning(It.IsAny()), Times.Once);
}
Considérations de performance
Pour optimiser les performances du système SIEM :
- Utiliser des buffers et du batching pour les logs
- Implémenter du caching pour les règles de détection
- Optimiser les requêtes de corrélation d'événements
public class OptimizedEventProcessor
{
private readonly Channel _eventChannel;
private readonly IMemoryCache _cache;
public OptimizedEventProcessor(IMemoryCache cache)
{
_eventChannel = Channel.CreateUnbounded();
_cache = cache;
}
public async Task ProcessEventsAsync(CancellationToken cancellationToken)
{
await foreach (var batch in _eventChannel.Reader.ReadAllAsync(cancellationToken)
.Buffer(100)
.WithCancellation(cancellationToken))
{
await ProcessEventBatchAsync(batch);
}
}
}
Conclusion
L'implémentation d'un système SIEM et de détection d'intrusion en .NET nécessite une approche méthodique et l'utilisation des bonnes pratiques de sécurité. Les exemples fournis constituent une base solide pour développer un système de sécurité robuste, adaptable aux besoins spécifiques de votre application.