Skip to content

【CI】 evil case #3359

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 10 commits into
base: develop
Choose a base branch
from
329 changes: 329 additions & 0 deletions test/ce/server/test_evil_cases.py
Original file line number Diff line number Diff line change
Expand Up @@ -122,3 +122,332 @@ def test_stop_seq_exceed_length():
resp = send_request(URL, payload).json()
assert resp.get("detail").get("object") == "error", "stop 超出长度应触发异常"
assert "exceeds the limit stop_seqs_max_len" in resp.get("detail").get("message", ""), "未返回预期的报错信息"


def test_multilingual_input():
"""测试多语言混合输入是否能够被正确处理"""
data = {
"messages": [
{
"role": "user",
"content": "这是一个包含多种语言的输入:Hello, 世界!Bonjour, le monde! Hola, el mundo! こんにちは、世界!"
}
],
"stream": False,

}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()

# 验证响应是否包含有效的回复
assert "choices" in resp, "未收到有效的回复"
assert len(resp["choices"]) > 0, "回复为空"
assert "message" in resp["choices"][0], "回复中未包含消息内容"
assert "content" in resp["choices"][0]["message"], "回复中未包含内容字段"
# 验证模型是否能够正确处理多语言输入
response_content = resp["choices"][0]["message"]["content"]
assert response_content.strip() != "", "模型未生成任何内容"
print("多语言混合输入测试通过!")



def test_too_long_input():
"""测试超长输入是否被正确处理"""
data = {
"messages": [
{
"role": "user",
"content": "a," * 200000 # 超过最大输入长度
}
],
"stream": False
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp["detail"].get("object") == "error", "超长输入未被识别为错误"
assert "Input text is too long" in resp["detail"].get("message", ""), "未检测到最大长度限制错误"


def test_empty_input():
"""测试空输入是否被正确处理"""
data = {
"messages": [
{
"role": "user",
"content": "" # 空输入
}
],
"stream": False
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert "error" not in resp.get("object"), "空输入被识别为错误"
assert len(resp["choices"][0]["message"]["content"]) > 0, "内容为空时,回复为空"


def test_prompt_only_spaces():
"""messages content 为纯空格字符串,服务正常返回"""
data = {
"messages": [
{
"role": "user",
"content": " ", # 纯空格
}
],
"stream": False,
"max_tokens": 10,
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("object") == "chat.completion", "应返回 chat.completion 对象"
response_content = resp["choices"][0]["message"]["content"]
assert len(response_content) > 0, "messages content为空,未正常生成回复"


def test_illegal_characters():
"""测试非法字符输入是否被正确处理"""
data = {
"messages": [
{
"role": "user",
"content": "非洲的首都是?:\x00\x01\x02" # 非法字符
}
],
"stream": False
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert len(resp["choices"][0]["message"]["content"]) > 0, "非法字符输入影响模型回复"


def test_sql_injection():
"""测试 SQL 注入攻击是否被正确处理"""
data = {
"messages": [
{
"role": "user",
"content": "SELECT * FROM users WHERE username = 'admin' OR '1'='1';" # SQL 注入攻击
}
],
"stream": False,
"max_tokens": 50,
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert "message" in resp["choices"][0], "回复中未包含消息内容"
assert "content" in resp["choices"][0]["message"], "回复中未包含内容字段"
response_content = resp["choices"][0]["message"]["content"]
assert len(response_content) > 0, "SQL 注入攻击影响模型回复"


def test_xss_attack():
"""测试 XSS 攻击是否被正确处理"""
data = {
"messages": [
{
"role": "user",
"content": "<script>alert('XSS');</script>" # XSS 攻击
}
],
"stream": False,
"max_tokens": 50,
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert "message" in resp["choices"][0], "回复中未包含消息内容"
assert "content" in resp["choices"][0]["message"], "回复中未包含内容字段"
response_content = resp["choices"][0]["message"]["content"]
assert len(response_content) > 0, "XSS 攻击未被正确处理"


def test_stop_empty_string():
"""测试 stop 参数为空字符串时的行为"""
data = {
"stream": False,
"messages": [
{
"role": "user",
"content": "非洲的首都是?"
}
],
"max_tokens": 10,
"stop": "" # 空字符串
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("object") == "chat.completion", "应返回 chat.completion 对象"
assert len(resp.get("choices", [])[0].get("message", {}).get("content", "")) > 0, "应生成有效文本"


def test_stop_multiple_strings():
"""测试 stop 参数为多个字符串时的行为"""
data = {
"stream": False,
"messages": [
{
"role": "user",
"content": "非洲的首都是?"
}
],
"max_tokens": 50,
"stop": ["。", "!", "?"] # 多个停止条件
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("object") == "chat.completion", "应返回 chat.completion 对象"
generated_text = resp.get("choices")[0].get("message", {}).get("content", "")
assert any(stop in generated_text for stop in data["stop"]), "生成文本应包含 stop 序列之一"


def test_stop_with_special_characters():
"""测试 stop 参数为包含特殊字符的字符串时的行为"""
data = {
"stream": False,
"messages": [
{
"role": "user",
"content": "非洲的首都是?"
}
],
"max_tokens": 50,
"stop": "!@#$%^&*()" # 包含特殊字符
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("object") == "chat.completion", "应返回 chat.completion 对象"
generated_text = resp.get("choices")[0].get("message", {}).get("content", "")
assert any(char in generated_text for char in data["stop"]), "生成文本应包含 stop 序列中的特殊字符之一"


def test_stop_with_newlines():
"""测试 stop 参数为包含换行符的字符串时的行为"""
data = {
"stream": False,
"messages": [
{
"role": "user",
"content": "非洲的首都是?"
}
],
"max_tokens": 50,
"stop": "\n\n" # 包含换行符
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("object") == "chat.completion", "应返回 chat.completion 对象"
generated_text = resp.get("choices")[0].get("message", {}).get("content", "")
assert data["stop"] in generated_text, "生成文本应包含 stop 序列"


def test_model_empty():
"""model 参数为空,不影响服务"""
data = {
"messages": [
{
"role": "user",
"content": "非洲的首都是?",
}
],
"stream": False,
"max_tokens": 10,
"model": "" # 空模型
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("object") == "chat.completion", "应返回 chat.completion 对象"
response_content = resp["choices"][0]["message"]["content"]
assert len(response_content) > 0, "模型名为空,未正常生成回复"


def test_model_invalid():
"""model 参数为不存在的模型,不影响服务"""
data = {
"messages": [
{
"role": "user",
"content": "非洲的首都是?",
}
],
"stream": False,
"max_tokens": 10,
"model": "non-existent-model" # 不存在的模型
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("object") == "chat.completion", "不存在的 model 应触发校验异常"
assert "non-existent-model" in resp.get("model"), "未返回预期的 model 信息"
assert len(resp.get("choices")[0].get("message").get("content")) > 0, "模型名为不存在的 model,未正常生成回复"


def test_model_with_special_characters():
"""model 参数为非法格式(例如包含特殊字符),不影响服务"""
data = {
"messages": [
{
"role": "user",
"content": "非洲的首都是?",
}
],
"stream": False,
"max_tokens": 10,
"model": "!@#" # 包含特殊字符
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("object") == "chat.completion", "不存在的 model 应触发校验异常"
assert "!@#" in resp.get("model"), "未返回预期的 model 信息"
assert len(resp.get("choices")[0].get("message").get("content")) > 0, "模型名为model 参数为非法格式,未正常生成回复"


def test_max_tokens_negative():
"""max_tokens 为负数,服务应报错"""
data = {
"messages": [
{
"role": "user",
"content": "非洲的首都是?",
}
],
"stream": False,
"max_tokens": -10, # 负数
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get("detail").get("object") == "error", "max_tokens < 0 未触发校验异常"
assert 'max_tokens can be defined [1,' in resp.get("detail").get("message"), "未返回预期的 max_tokens 错误信息"


def test_max_tokens_min():
"""测试 max_tokens 达到异常值0 时的行为"""
data = {
"messages": [
{
"role": "user",
"content": "非洲的首都是?",
}
],
"stream": False,
"max_tokens": 0, # 最小值
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get('detail').get("object") == "error", "max_tokens未0时API未拦截住"
assert "reasoning_max_tokens must be between max_tokens and 1" in resp.get('detail').get("message", ""), "未返回预期的 max_tokens 达到异常值0 的 错误信息"


def test_max_tokens_non_integer():
"""max_tokens 为非整数,服务应报错"""
data = {
"messages": [
{
"role": "user",
"content": "非洲的首都是?",
}
],
"stream": False,
"max_tokens": 10.5, # 非整数
}
payload = build_request_payload(TEMPLATE, data)
resp = send_request(URL, payload).json()
assert resp.get('detail')[0].get("msg") == "Input should be a valid integer, got a number with a fractional part", "未返回预期的 max_tokens 为非整数的错误信息"

Loading