refactor(security): 重构安全配置并优化测试环境
- 移除旧的测试套件和UAT测试文件 - 更新密码编码器配置使用BCrypt strength=12 - 添加用户角色关联表和相关服务 - 优化前端日期显示格式 - 清理无用资源和配置文件 - 增强测试数据管理和清理功能
This commit is contained in:
@@ -97,6 +97,143 @@ class TestSQLInjection(SecurityTestBase):
|
||||
|
||||
# 应该返回400(错误请求)或正常结果,但不应该暴露数据库错误
|
||||
assert response.status_code in [200, 400], f"SQL注入攻击未正确处理: {payload}"
|
||||
|
||||
|
||||
class TestXSS(SecurityTestBase):
|
||||
"""XSS攻击测试"""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup(self):
|
||||
self.setup_auth()
|
||||
yield
|
||||
self.cleanup()
|
||||
|
||||
def test_xss_in_user_creation(self):
|
||||
"""测试用户创建接口的XSS防护"""
|
||||
xss_payloads = [
|
||||
"<script>alert('XSS')</script>",
|
||||
"<img src=x onerror=alert('XSS')>",
|
||||
"<svg onload=alert('XSS')>",
|
||||
"javascript:alert('XSS')",
|
||||
"<body onload=alert('XSS')>",
|
||||
"<iframe src='javascript:alert(1)'>",
|
||||
"<object data='javascript:alert(1)'>"
|
||||
]
|
||||
|
||||
for payload in xss_payloads:
|
||||
user_data = {
|
||||
"username": f"test_{int(time.time() * 1000)}",
|
||||
"password": "Test123!@#",
|
||||
"email": "test@example.com",
|
||||
"nickname": payload
|
||||
}
|
||||
|
||||
response = self.client.post(
|
||||
f"{self.base_url}/api/users",
|
||||
json=user_data,
|
||||
headers=self.get_headers()
|
||||
)
|
||||
|
||||
if response.status_code == 201:
|
||||
user_id = response.json()["id"]
|
||||
get_response = self.client.get(
|
||||
f"{self.base_url}/api/users/{user_id}",
|
||||
headers=self.get_headers()
|
||||
)
|
||||
user_info = get_response.json()
|
||||
|
||||
# 验证XSS payload被转义
|
||||
assert "<script>" not in str(user_info), f"XSS payload {payload} 应该被转义"
|
||||
assert "alert(" not in str(user_info), f"XSS payload {payload} 应该被转义"
|
||||
assert "onerror=" not in str(user_info), f"XSS payload {payload} 应该被转义"
|
||||
assert "onload=" not in str(user_info), f"XSS payload {payload} 应该被转义"
|
||||
|
||||
def test_xss_in_role_creation(self):
|
||||
"""测试角色创建接口的XSS防护"""
|
||||
xss_payload = "<script>alert('XSS')</script>"
|
||||
|
||||
role_data = {
|
||||
"roleName": xss_payload,
|
||||
"roleKey": f"test_role_{int(time.time() * 1000)}",
|
||||
"roleSort": 1,
|
||||
"status": 1
|
||||
}
|
||||
|
||||
response = self.client.post(
|
||||
f"{self.base_url}/api/roles",
|
||||
json=role_data,
|
||||
headers=self.get_headers()
|
||||
)
|
||||
|
||||
if response.status_code == 201:
|
||||
role_id = response.json()["id"]
|
||||
get_response = self.client.get(
|
||||
f"{self.base_url}/api/roles/{role_id}",
|
||||
headers=self.get_headers()
|
||||
)
|
||||
role_info = get_response.json()
|
||||
|
||||
assert "<script>" not in str(role_info), "XSS payload应该被转义"
|
||||
|
||||
|
||||
class TestInputValidation(SecurityTestBase):
|
||||
"""输入验证测试"""
|
||||
|
||||
@pytest.fixture(autouse=True)
|
||||
def setup(self):
|
||||
self.setup_auth()
|
||||
yield
|
||||
self.cleanup()
|
||||
|
||||
def test_empty_required_fields(self):
|
||||
"""测试必填字段为空"""
|
||||
user_data = {
|
||||
"username": "",
|
||||
"password": "",
|
||||
"email": ""
|
||||
}
|
||||
|
||||
response = self.client.post(
|
||||
f"{self.base_url}/api/users",
|
||||
json=user_data,
|
||||
headers=self.get_headers()
|
||||
)
|
||||
|
||||
assert response.status_code in [400, 422], "空必填字段应该被拒绝"
|
||||
|
||||
def test_invalid_data_types(self):
|
||||
"""测试无效数据类型"""
|
||||
user_data = {
|
||||
"username": "testuser",
|
||||
"password": "Test123!@#",
|
||||
"email": "test@example.com",
|
||||
"status": "invalid_type"
|
||||
}
|
||||
|
||||
response = self.client.post(
|
||||
f"{self.base_url}/api/users",
|
||||
json=user_data,
|
||||
headers=self.get_headers()
|
||||
)
|
||||
|
||||
assert response.status_code in [400, 422], "无效数据类型应该被拒绝"
|
||||
|
||||
def test_oversized_fields(self):
|
||||
"""测试超长字段"""
|
||||
user_data = {
|
||||
"username": "a" * 1000,
|
||||
"password": "Test123!@#",
|
||||
"email": "test@example.com",
|
||||
"nickname": "a" * 5000
|
||||
}
|
||||
|
||||
response = self.client.post(
|
||||
f"{self.base_url}/api/users",
|
||||
json=user_data,
|
||||
headers=self.get_headers()
|
||||
)
|
||||
|
||||
assert response.status_code in [400, 422], "超长字段应该被拒绝"
|
||||
|
||||
# 如果返回200,验证结果不包含所有用户数据
|
||||
if response.status_code == 200:
|
||||
|
||||
Reference in New Issue
Block a user