创建新工程
This commit is contained in:
226
tests/test_security_manager.gd
Normal file
226
tests/test_security_manager.gd
Normal file
@@ -0,0 +1,226 @@
|
||||
extends GutTest
|
||||
## 安全管理器测试
|
||||
## 测试安全验证、输入过滤和防护措施
|
||||
|
||||
var security_manager: SecurityManager
|
||||
|
||||
func before_each():
|
||||
"""每个测试前的设置"""
|
||||
security_manager = SecurityManager.new()
|
||||
|
||||
func after_each():
|
||||
"""每个测试后的清理"""
|
||||
if security_manager:
|
||||
security_manager.queue_free()
|
||||
|
||||
## 测试输入验证 - 有效输入
|
||||
func test_validate_input_valid():
|
||||
"""测试有效输入的验证"""
|
||||
# 测试有效用户名
|
||||
var result = SecurityManager.validate_input("TestUser123", "username")
|
||||
assert_true(result.valid, "Valid username should pass validation")
|
||||
assert_eq(result.sanitized, "TestUser123", "Valid username should not be modified")
|
||||
|
||||
# 测试有效角色名
|
||||
result = SecurityManager.validate_input("MyCharacter", "character_name")
|
||||
assert_true(result.valid, "Valid character name should pass validation")
|
||||
assert_eq(result.sanitized, "MyCharacter", "Valid character name should not be modified")
|
||||
|
||||
# 测试有效消息
|
||||
result = SecurityManager.validate_input("Hello, world!", "message")
|
||||
assert_true(result.valid, "Valid message should pass validation")
|
||||
assert_eq(result.sanitized, "Hello, world!", "Valid message should not be modified")
|
||||
|
||||
## 测试输入验证 - 无效输入
|
||||
func test_validate_input_invalid():
|
||||
"""测试无效输入的验证"""
|
||||
# 测试空输入
|
||||
var result = SecurityManager.validate_input("", "username")
|
||||
assert_false(result.valid, "Empty username should fail validation")
|
||||
assert_true(result.error.length() > 0, "Should provide error message")
|
||||
|
||||
# 测试过长输入
|
||||
var long_string = "a".repeat(100)
|
||||
result = SecurityManager.validate_input(long_string, "character_name")
|
||||
assert_false(result.valid, "Overly long character name should fail validation")
|
||||
|
||||
# 测试过短角色名
|
||||
result = SecurityManager.validate_input("a", "character_name")
|
||||
assert_false(result.valid, "Too short character name should fail validation")
|
||||
|
||||
## 测试恶意内容检测
|
||||
func test_malicious_content_detection():
|
||||
"""测试恶意内容检测"""
|
||||
# 测试脚本注入
|
||||
var malicious_inputs = [
|
||||
"<script>alert('xss')</script>",
|
||||
"javascript:alert('xss')",
|
||||
"onload=alert('xss')",
|
||||
"eval(malicious_code)",
|
||||
"document.cookie"
|
||||
]
|
||||
|
||||
for malicious_input in malicious_inputs:
|
||||
var result = SecurityManager.validate_input(malicious_input, "message")
|
||||
assert_false(result.valid, "Malicious input should be rejected: " + malicious_input)
|
||||
assert_true(result.error.contains("不安全内容"), "Should indicate unsafe content")
|
||||
|
||||
## 测试SQL注入检测
|
||||
func test_sql_injection_detection():
|
||||
"""测试SQL注入检测"""
|
||||
var injection_inputs = [
|
||||
"'; DROP TABLE users; --",
|
||||
"' OR '1'='1",
|
||||
"UNION SELECT * FROM passwords",
|
||||
"INSERT INTO users VALUES"
|
||||
]
|
||||
|
||||
for injection_input in injection_inputs:
|
||||
var result = SecurityManager.validate_input(injection_input, "message")
|
||||
assert_false(result.valid, "SQL injection should be rejected: " + injection_input)
|
||||
|
||||
## 测试过度重复字符检测
|
||||
func test_excessive_repetition_detection():
|
||||
"""测试过度重复字符检测"""
|
||||
# 创建70%重复字符的字符串
|
||||
var repetitive_string = "a".repeat(70) + "b".repeat(30)
|
||||
var result = SecurityManager.validate_input(repetitive_string, "message")
|
||||
assert_false(result.valid, "Excessive repetition should be rejected")
|
||||
assert_true(result.error.contains("重复字符"), "Should indicate repetition issue")
|
||||
|
||||
## 测试输入清理
|
||||
func test_input_sanitization():
|
||||
"""测试输入清理功能"""
|
||||
# 测试HTML标签移除
|
||||
var html_input = "Hello <b>world</b>!"
|
||||
var sanitized = SecurityManager.sanitize_input(html_input)
|
||||
assert_false(sanitized.contains("<b>"), "HTML tags should be removed")
|
||||
assert_false(sanitized.contains("</b>"), "HTML tags should be removed")
|
||||
assert_true(sanitized.contains("Hello"), "Text content should be preserved")
|
||||
assert_true(sanitized.contains("world"), "Text content should be preserved")
|
||||
|
||||
# 测试多余空格处理
|
||||
var spaced_input = "Hello world !"
|
||||
sanitized = SecurityManager.sanitize_input(spaced_input)
|
||||
assert_false(sanitized.contains(" "), "Multiple spaces should be reduced")
|
||||
assert_true(sanitized.contains("Hello world"), "Should contain single spaces")
|
||||
|
||||
## 测试消息格式验证
|
||||
func test_message_format_validation():
|
||||
"""测试网络消息格式验证"""
|
||||
# 测试有效消息
|
||||
var valid_message = {
|
||||
"type": "auth_request",
|
||||
"data": {"username": "test"},
|
||||
"timestamp": Time.get_unix_time_from_system()
|
||||
}
|
||||
assert_true(SecurityManager.validate_message_format(valid_message), "Valid message should pass")
|
||||
|
||||
# 测试缺少字段的消息
|
||||
var invalid_message = {
|
||||
"type": "auth_request"
|
||||
# 缺少 data 和 timestamp
|
||||
}
|
||||
assert_false(SecurityManager.validate_message_format(invalid_message), "Invalid message should fail")
|
||||
|
||||
# 测试无效消息类型
|
||||
var invalid_type_message = {
|
||||
"type": "malicious_type",
|
||||
"data": {},
|
||||
"timestamp": Time.get_unix_time_from_system()
|
||||
}
|
||||
assert_false(SecurityManager.validate_message_format(invalid_type_message), "Invalid message type should fail")
|
||||
|
||||
# 测试时间戳过旧
|
||||
var old_message = {
|
||||
"type": "auth_request",
|
||||
"data": {},
|
||||
"timestamp": Time.get_unix_time_from_system() - 400 # 超过5分钟
|
||||
}
|
||||
assert_false(SecurityManager.validate_message_format(old_message), "Old timestamp should fail")
|
||||
|
||||
## 测试会话管理
|
||||
func test_session_management():
|
||||
"""测试会话管理功能"""
|
||||
# 创建会话
|
||||
var session_token = security_manager.create_session("client123", "testuser")
|
||||
assert_true(session_token.length() > 0, "Should generate session token")
|
||||
|
||||
# 验证会话
|
||||
assert_true(security_manager.validate_session(session_token), "New session should be valid")
|
||||
|
||||
# 使会话无效
|
||||
security_manager.invalidate_session(session_token)
|
||||
assert_false(security_manager.validate_session(session_token), "Invalidated session should be invalid")
|
||||
|
||||
## 测试失败尝试记录
|
||||
func test_failed_attempt_recording():
|
||||
"""测试失败尝试记录和锁定机制"""
|
||||
var client_id = "test_client"
|
||||
|
||||
# 记录多次失败尝试
|
||||
for i in range(4): # 4次失败,还未达到锁定阈值
|
||||
var should_lock = security_manager.record_failed_attempt(client_id)
|
||||
assert_false(should_lock, "Should not lock before reaching max attempts")
|
||||
|
||||
# 第5次失败应该触发锁定
|
||||
var should_lock = security_manager.record_failed_attempt(client_id)
|
||||
assert_true(should_lock, "Should lock after max failed attempts")
|
||||
|
||||
# 检查锁定状态
|
||||
assert_true(security_manager.is_locked(client_id), "Client should be locked")
|
||||
|
||||
# 清除失败尝试
|
||||
security_manager.clear_failed_attempts(client_id)
|
||||
assert_false(security_manager.is_locked(client_id), "Client should be unlocked after clearing attempts")
|
||||
|
||||
## 测试安全统计
|
||||
func test_security_statistics():
|
||||
"""测试安全统计功能"""
|
||||
# 创建一些会话和失败尝试
|
||||
security_manager.create_session("client1", "user1")
|
||||
security_manager.create_session("client2", "user2")
|
||||
security_manager.record_failed_attempt("client3")
|
||||
|
||||
var stats = security_manager.get_security_stats()
|
||||
assert_true(stats.has("active_sessions"), "Stats should include active sessions")
|
||||
assert_true(stats.has("failed_attempts"), "Stats should include failed attempts")
|
||||
assert_true(stats.has("locked_clients"), "Stats should include locked clients")
|
||||
|
||||
assert_eq(stats.active_sessions, 2, "Should have 2 active sessions")
|
||||
assert_eq(stats.failed_attempts, 1, "Should have 1 failed attempt record")
|
||||
|
||||
## 测试会话超时
|
||||
func test_session_timeout():
|
||||
"""测试会话超时机制"""
|
||||
# 创建会话
|
||||
var session_token = security_manager.create_session("client123", "testuser")
|
||||
|
||||
# 修改会话超时时间为很短的时间进行测试
|
||||
security_manager.session_timeout = 0.1 # 0.1秒
|
||||
|
||||
# 等待超时
|
||||
await get_tree().create_timer(0.2).timeout
|
||||
|
||||
# 验证会话应该已过期
|
||||
assert_false(security_manager.validate_session(session_token), "Session should expire after timeout")
|
||||
|
||||
## 测试边界情况
|
||||
func test_edge_cases():
|
||||
"""测试边界情况"""
|
||||
# 测试null输入
|
||||
var result = SecurityManager.validate_input(null, "username")
|
||||
assert_false(result.valid, "Null input should be rejected")
|
||||
|
||||
# 测试空白字符输入
|
||||
result = SecurityManager.validate_input(" ", "character_name")
|
||||
assert_false(result.valid, "Whitespace-only input should be rejected")
|
||||
|
||||
# 测试边界长度
|
||||
var min_length_name = "ab" # 最小长度
|
||||
result = SecurityManager.validate_input(min_length_name, "character_name")
|
||||
assert_true(result.valid, "Minimum length name should be valid")
|
||||
|
||||
var max_length_name = "a".repeat(20) # 最大长度
|
||||
result = SecurityManager.validate_input(max_length_name, "character_name")
|
||||
assert_true(result.valid, "Maximum length name should be valid")
|
||||
Reference in New Issue
Block a user