Files
git.stella-ops.org/tests/security/StellaOps.Security.Tests/Infrastructure/SecurityTestBase.cs
master b55d9fa68d
Some checks failed
Docs CI / lint-and-preview (push) Has been cancelled
AOC Guard CI / aoc-guard (push) Has been cancelled
AOC Guard CI / aoc-verify (push) Has been cancelled
Add comprehensive security tests for OWASP A03 (Injection) and A10 (SSRF)
- Implemented InjectionTests.cs to cover various injection vulnerabilities including SQL, NoSQL, Command, LDAP, and XPath injections.
- Created SsrfTests.cs to test for Server-Side Request Forgery (SSRF) vulnerabilities, including internal URL access, cloud metadata access, and URL allowlist bypass attempts.
- Introduced MaliciousPayloads.cs to store a collection of malicious payloads for testing various security vulnerabilities.
- Added SecurityAssertions.cs for common security-specific assertion helpers.
- Established SecurityTestBase.cs as a base class for security tests, providing common infrastructure and mocking utilities.
- Configured the test project StellaOps.Security.Tests.csproj with necessary dependencies for testing.
2025-12-16 13:11:57 +02:00

129 lines
4.0 KiB
C#

// =============================================================================
// SecurityTestBase.cs
// Base class for all security tests providing common infrastructure
// =============================================================================
using FluentAssertions;
using Microsoft.Extensions.Logging;
using Moq;
namespace StellaOps.Security.Tests.Infrastructure;
/// <summary>
/// Base class for OWASP-category security tests.
/// Provides common test infrastructure, mocking utilities, and security assertions.
/// </summary>
[Trait("Category", "Security")]
public abstract class SecurityTestBase : IDisposable
{
protected readonly Mock<ILogger> LoggerMock;
protected readonly CancellationToken TestCancellation;
private readonly CancellationTokenSource _cts;
protected SecurityTestBase()
{
LoggerMock = new Mock<ILogger>();
_cts = new CancellationTokenSource(TimeSpan.FromSeconds(30));
TestCancellation = _cts.Token;
}
/// <summary>
/// Assert that an action throws a security-related exception.
/// </summary>
protected static void AssertSecurityException<TException>(Action action, string? expectedMessage = null)
where TException : Exception
{
var exception = Assert.Throws<TException>(action);
if (expectedMessage != null)
{
exception.Message.Should().Contain(expectedMessage);
}
}
/// <summary>
/// Assert that an async action throws a security-related exception.
/// </summary>
protected static async Task AssertSecurityExceptionAsync<TException>(Func<Task> action, string? expectedMessage = null)
where TException : Exception
{
var exception = await Assert.ThrowsAsync<TException>(action);
if (expectedMessage != null)
{
exception.Message.Should().Contain(expectedMessage);
}
}
/// <summary>
/// Assert that the logger was called with a security warning.
/// </summary>
protected void AssertSecurityWarningLogged(string expectedMessage)
{
LoggerMock.Verify(
x => x.Log(
LogLevel.Warning,
It.IsAny<EventId>(),
It.Is<It.IsAnyType>((v, t) => v.ToString()!.Contains(expectedMessage)),
It.IsAny<Exception?>(),
It.IsAny<Func<It.IsAnyType, Exception?, string>>()),
Times.AtLeastOnce);
}
/// <summary>
/// Assert that no sensitive data is present in the response.
/// </summary>
protected static void AssertNoSensitiveDataLeakage(string content)
{
var sensitivePatterns = new[]
{
"password",
"secret",
"api_key",
"apikey",
"private_key",
"token",
"bearer",
"authorization"
};
foreach (var pattern in sensitivePatterns)
{
// Case-insensitive check for sensitive patterns in unexpected places
content.ToLowerInvariant().Should().NotContain(pattern,
$"Response should not contain sensitive data pattern: {pattern}");
}
}
/// <summary>
/// Generate a random tenant ID for isolation.
/// </summary>
protected static Guid GenerateTestTenantId() => Guid.NewGuid();
/// <summary>
/// Generate a random user ID for isolation.
/// </summary>
protected static Guid GenerateTestUserId() => Guid.NewGuid();
public virtual void Dispose()
{
_cts.Cancel();
_cts.Dispose();
GC.SuppressFinalize(this);
}
}
/// <summary>
/// Trait for categorizing tests by OWASP category.
/// </summary>
[AttributeUsage(AttributeTargets.Class | AttributeTargets.Method)]
public class OwaspCategoryAttribute : Attribute
{
public string Category { get; }
public string Description { get; }
public OwaspCategoryAttribute(string category, string description)
{
Category = category;
Description = description;
}
}