238 lines
5.9 KiB
C#
Executable File
238 lines
5.9 KiB
C#
Executable File
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
|
using MarketAlly.AIPlugin.Security;
|
|
using System;
|
|
using System.IO;
|
|
using System.Collections.Generic;
|
|
|
|
namespace MarketAlly.AIPlugin.Tests.Security
|
|
{
|
|
[TestClass]
|
|
public class SecurityValidatorTests
|
|
{
|
|
private SecurityConfiguration _testConfig;
|
|
private string _testDirectory;
|
|
|
|
[TestInitialize]
|
|
public void Setup()
|
|
{
|
|
_testDirectory = Path.Combine(Path.GetTempPath(), "AIPlugin_Tests", Guid.NewGuid().ToString());
|
|
Directory.CreateDirectory(_testDirectory);
|
|
|
|
_testConfig = new SecurityConfiguration
|
|
{
|
|
AllowedDirectories = new List<string> { _testDirectory },
|
|
AllowedFileExtensions = new List<string> { ".txt", ".json", ".log" },
|
|
MaxFileSizeBytes = 1024 * 1024, // 1MB
|
|
AllowedUrlSchemes = new List<string> { "https" }
|
|
};
|
|
}
|
|
|
|
[TestCleanup]
|
|
public void Cleanup()
|
|
{
|
|
if (Directory.Exists(_testDirectory))
|
|
{
|
|
Directory.Delete(_testDirectory, true);
|
|
}
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ValidateAndNormalizePath_ValidPath_ReturnsNormalizedPath()
|
|
{
|
|
// Arrange
|
|
var validPath = Path.Combine(_testDirectory, "test.txt");
|
|
|
|
// Act
|
|
var result = SecurityValidator.ValidateAndNormalizePath(validPath, _testConfig);
|
|
|
|
// Assert
|
|
Assert.AreEqual(Path.GetFullPath(validPath), result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ValidateAndNormalizePath_ValidSubdirectoryPath_ReturnsNormalizedPath()
|
|
{
|
|
// Arrange
|
|
var validPath = Path.Combine(_testDirectory, "subdir", "test.txt");
|
|
|
|
// Act
|
|
var result = SecurityValidator.ValidateAndNormalizePath(validPath, _testConfig);
|
|
|
|
// Assert
|
|
Assert.AreEqual(Path.GetFullPath(validPath), result);
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(UnauthorizedAccessException))]
|
|
public void ValidateAndNormalizePath_PathTraversal_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var maliciousPath = Path.Combine(_testDirectory, "..", "..", "etc", "passwd");
|
|
|
|
// Act
|
|
SecurityValidator.ValidateAndNormalizePath(maliciousPath, _testConfig);
|
|
|
|
// Assert - Exception expected
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(UnauthorizedAccessException))]
|
|
public void ValidateAndNormalizePath_OutsideAllowedDirectory_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var outsidePath = Path.Combine(Path.GetTempPath(), "outside.txt");
|
|
|
|
// Act
|
|
SecurityValidator.ValidateAndNormalizePath(outsidePath, _testConfig);
|
|
|
|
// Assert - Exception expected
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(UnauthorizedAccessException))]
|
|
public void ValidateAndNormalizePath_DisallowedExtension_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var disallowedPath = Path.Combine(_testDirectory, "test.exe");
|
|
|
|
// Act
|
|
SecurityValidator.ValidateAndNormalizePath(disallowedPath, _testConfig);
|
|
|
|
// Assert - Exception expected
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(ArgumentException))]
|
|
public void ValidateAndNormalizePath_UnsafeCharacters_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var unsafePath = Path.Combine(_testDirectory, "test<>.txt");
|
|
|
|
// Act
|
|
SecurityValidator.ValidateAndNormalizePath(unsafePath, _testConfig);
|
|
|
|
// Assert - Exception expected
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ValidateContentSize_ValidSize_DoesNotThrow()
|
|
{
|
|
// Arrange
|
|
var content = "This is a test content";
|
|
|
|
// Act & Assert
|
|
SecurityValidator.ValidateContentSize(content, _testConfig);
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(UnauthorizedAccessException))]
|
|
public void ValidateContentSize_TooLarge_ThrowsException()
|
|
{
|
|
long size = _testConfig.MaxFileSizeBytes + 1;
|
|
if (size > int.MaxValue)
|
|
throw new InvalidOperationException("Requested string size exceeds maximum allowed length.");
|
|
|
|
var largeContent = new string('A', (int)size);
|
|
|
|
|
|
// Act
|
|
SecurityValidator.ValidateContentSize(largeContent, _testConfig);
|
|
|
|
// Assert - Exception expected
|
|
}
|
|
|
|
[TestMethod]
|
|
public void ValidateUrl_ValidHttpsUrl_ReturnsUri()
|
|
{
|
|
// Arrange
|
|
var validUrl = "https://example.com/api/test";
|
|
|
|
// Act
|
|
var result = SecurityValidator.ValidateUrl(validUrl, _testConfig);
|
|
|
|
// Assert
|
|
Assert.AreEqual("https", result.Scheme);
|
|
Assert.AreEqual("example.com", result.Host);
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(UnauthorizedAccessException))]
|
|
public void ValidateUrl_HttpScheme_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var httpUrl = "http://example.com/api/test";
|
|
|
|
// Act
|
|
SecurityValidator.ValidateUrl(httpUrl, _testConfig);
|
|
|
|
// Assert - Exception expected
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(UnauthorizedAccessException))]
|
|
public void ValidateUrl_LocalhostUrl_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var localhostUrl = "https://localhost:8080/api/test";
|
|
|
|
// Act
|
|
SecurityValidator.ValidateUrl(localhostUrl, _testConfig);
|
|
|
|
// Assert - Exception expected
|
|
}
|
|
|
|
[TestMethod]
|
|
[ExpectedException(typeof(UnauthorizedAccessException))]
|
|
public void ValidateUrl_PrivateIpUrl_ThrowsException()
|
|
{
|
|
// Arrange
|
|
var privateIpUrl = "https://192.168.1.1/api/test";
|
|
|
|
// Act
|
|
SecurityValidator.ValidateUrl(privateIpUrl, _testConfig);
|
|
|
|
// Assert - Exception expected
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SanitizeInput_ValidInput_ReturnsInput()
|
|
{
|
|
// Arrange
|
|
var validInput = "This is a normal string";
|
|
|
|
// Act
|
|
var result = SecurityValidator.SanitizeInput(validInput);
|
|
|
|
// Assert
|
|
Assert.AreEqual(validInput, result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void SanitizeInput_ControlCharacters_RemovesControlCharacters()
|
|
{
|
|
// Arrange
|
|
var inputWithControlChars = "Test\x00\x01string\x1F";
|
|
|
|
// Act
|
|
var result = SecurityValidator.SanitizeInput(inputWithControlChars);
|
|
|
|
// Assert
|
|
Assert.AreEqual("Teststring", result);
|
|
}
|
|
|
|
[TestMethod]
|
|
public void CreateSecureBackupPath_ValidPath_ReturnsSecurePath()
|
|
{
|
|
// Arrange
|
|
var originalPath = Path.Combine(_testDirectory, "test.txt");
|
|
|
|
// Act
|
|
var backupPath = SecurityValidator.CreateSecureBackupPath(originalPath);
|
|
|
|
// Assert
|
|
Assert.IsTrue(backupPath.StartsWith(_testDirectory));
|
|
Assert.IsTrue(backupPath.Contains("test_"));
|
|
Assert.IsTrue(backupPath.EndsWith(".bak.txt"));
|
|
}
|
|
}
|
|
} |