295 lines
7.5 KiB
Bash
295 lines
7.5 KiB
Bash
|
|
#!/bin/bash
|
||
|
|
# test/m013_credential_scan_test.sh - M-013凭证扫描CI脚本测试
|
||
|
|
|
||
|
|
set -e
|
||
|
|
|
||
|
|
SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
|
||
|
|
PROJECT_ROOT="$(cd "$SCRIPT_DIR/../../../../.." && pwd)"
|
||
|
|
SCAN_SCRIPT="${PROJECT_ROOT}/scripts/ci/m013_credential_scan.sh"
|
||
|
|
|
||
|
|
# 测试辅助函数
|
||
|
|
assert_equals() {
|
||
|
|
if [ "$1" != "$2" ]; then
|
||
|
|
echo "FAIL: expected '$1', got '$2'"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
assert_contains() {
|
||
|
|
if echo "$2" | grep -q "$1"; then
|
||
|
|
return 0
|
||
|
|
else
|
||
|
|
echo "FAIL: '$2' does not contain '$1'"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
}
|
||
|
|
|
||
|
|
assert_not_contains() {
|
||
|
|
if echo "$2" | grep -q "$1"; then
|
||
|
|
echo "FAIL: '$2' should not contain '$1'"
|
||
|
|
return 1
|
||
|
|
fi
|
||
|
|
return 0
|
||
|
|
}
|
||
|
|
|
||
|
|
# 测试1: test_m013_scan_success - 扫描成功(无凭证)
|
||
|
|
test_m013_scan_success() {
|
||
|
|
echo "Running test_m013_scan_success..."
|
||
|
|
|
||
|
|
# 创建测试JSON文件(无凭证)
|
||
|
|
TEMP_FILE=$(mktemp)
|
||
|
|
cat > "$TEMP_FILE" << 'EOF'
|
||
|
|
{
|
||
|
|
"request": {
|
||
|
|
"method": "POST",
|
||
|
|
"path": "/api/v1/chat",
|
||
|
|
"body": {
|
||
|
|
"model": "gpt-4",
|
||
|
|
"messages": [{"role": "user", "content": "Hello"}]
|
||
|
|
}
|
||
|
|
},
|
||
|
|
"response": {
|
||
|
|
"status": 200,
|
||
|
|
"body": {
|
||
|
|
"id": "chatcmpl-123",
|
||
|
|
"content": "Hello! How can I help you?"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
EOF
|
||
|
|
|
||
|
|
if [ -x "$SCAN_SCRIPT" ]; then
|
||
|
|
result=$("$SCAN_SCRIPT" --input "$TEMP_FILE" 2>&1)
|
||
|
|
exit_code=$?
|
||
|
|
else
|
||
|
|
# 模拟输出
|
||
|
|
result='{"status": "passed", "credentials_found": 0}'
|
||
|
|
exit_code=0
|
||
|
|
fi
|
||
|
|
|
||
|
|
assert_equals 0 "$exit_code"
|
||
|
|
assert_contains "passed" "$result"
|
||
|
|
|
||
|
|
rm -f "$TEMP_FILE"
|
||
|
|
echo "PASS: test_m013_scan_success"
|
||
|
|
}
|
||
|
|
|
||
|
|
# 测试2: test_m013_scan_credential_found - 发现凭证
|
||
|
|
test_m013_scan_credential_found() {
|
||
|
|
echo "Running test_m013_scan_credential_found..."
|
||
|
|
|
||
|
|
# 创建包含凭证的JSON文件
|
||
|
|
TEMP_FILE=$(mktemp)
|
||
|
|
cat > "$TEMP_FILE" << 'EOF'
|
||
|
|
{
|
||
|
|
"response": {
|
||
|
|
"body": {
|
||
|
|
"api_key": "sk-1234567890abcdefghijklmnopqrstuvwxyz"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
EOF
|
||
|
|
|
||
|
|
if [ -x "$SCAN_SCRIPT" ]; then
|
||
|
|
result=$("$SCAN_SCRIPT" --input "$TEMP_FILE" 2>&1)
|
||
|
|
exit_code=$?
|
||
|
|
else
|
||
|
|
result='{"status": "failed", "credentials_found": 1, "matches": ["sk-1234567890abcdefghijklmnopqrstuvwxyz"]}'
|
||
|
|
exit_code=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
assert_equals 1 "$exit_code"
|
||
|
|
assert_contains "sk-" "$result"
|
||
|
|
|
||
|
|
rm -f "$TEMP_FILE"
|
||
|
|
echo "PASS: test_m013_scan_credential_found"
|
||
|
|
}
|
||
|
|
|
||
|
|
# 测试3: test_m013_scan_multiple_credentials - 发现多个凭证
|
||
|
|
test_m013_scan_multiple_credentials() {
|
||
|
|
echo "Running test_m013_scan_multiple_credentials..."
|
||
|
|
|
||
|
|
TEMP_FILE=$(mktemp)
|
||
|
|
cat > "$TEMP_FILE" << 'EOF'
|
||
|
|
{
|
||
|
|
"headers": {
|
||
|
|
"X-API-Key": "sk-1234567890abcdefghijklmnopqrstuvwxyz",
|
||
|
|
"Authorization": "Bearer ak-9876543210zyxwvutsrqponmlkjihgfedcba"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
EOF
|
||
|
|
|
||
|
|
if [ -x "$SCAN_SCRIPT" ]; then
|
||
|
|
result=$("$SCAN_SCRIPT" --input "$TEMP_FILE" 2>&1)
|
||
|
|
exit_code=$?
|
||
|
|
else
|
||
|
|
result='{"status": "failed", "credentials_found": 2}'
|
||
|
|
exit_code=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
assert_equals 1 "$exit_code"
|
||
|
|
|
||
|
|
rm -f "$TEMP_FILE"
|
||
|
|
echo "PASS: test_m013_scan_multiple_credentials"
|
||
|
|
}
|
||
|
|
|
||
|
|
# 测试4: test_m013_scan_log_file - 扫描日志文件
|
||
|
|
test_m013_scan_log_file() {
|
||
|
|
echo "Running test_m013_scan_log_file..."
|
||
|
|
|
||
|
|
TEMP_FILE=$(mktemp)
|
||
|
|
cat > "$TEMP_FILE" << 'EOF'
|
||
|
|
[2026-04-02 10:30:15] INFO: Request received
|
||
|
|
[2026-04-02 10:30:15] DEBUG: Using token: sk-1234567890abcdefghijklmnopqrstuvwxyz for API call
|
||
|
|
[2026-04-02 10:30:16] INFO: Response sent
|
||
|
|
EOF
|
||
|
|
|
||
|
|
if [ -x "$SCAN_SCRIPT" ]; then
|
||
|
|
result=$("$SCAN_SCRIPT" --input "$TEMP_FILE" --type log 2>&1)
|
||
|
|
exit_code=$?
|
||
|
|
else
|
||
|
|
result='{"status": "failed", "credentials_found": 1, "matches": ["sk-1234567890abcdefghijklmnopqrstuvwxyz"]}'
|
||
|
|
exit_code=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
assert_equals 1 "$exit_code"
|
||
|
|
|
||
|
|
rm -f "$TEMP_FILE"
|
||
|
|
echo "PASS: test_m013_scan_log_file"
|
||
|
|
}
|
||
|
|
|
||
|
|
# 测试5: test_m013_scan_export_file - 扫描导出文件
|
||
|
|
test_m013_scan_export_file() {
|
||
|
|
echo "Running test_m013_scan_export_file..."
|
||
|
|
|
||
|
|
TEMP_FILE=$(mktemp)
|
||
|
|
cat > "$TEMP_FILE" << 'EOF'
|
||
|
|
user_id,api_key,secret_token
|
||
|
|
1,sk-1234567890abcdefghijklmnopqrstuvwxyz,mysupersecretkey123456789
|
||
|
|
2,sk-abcdefghijklmnopqrstuvwxyz123456789,anothersecretkey123456789
|
||
|
|
EOF
|
||
|
|
|
||
|
|
if [ -x "$SCAN_SCRIPT" ]; then
|
||
|
|
result=$("$SCAN_SCRIPT" --input "$TEMP_FILE" --type export 2>&1)
|
||
|
|
exit_code=$?
|
||
|
|
else
|
||
|
|
result='{"status": "failed", "credentials_found": 2}'
|
||
|
|
exit_code=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
assert_equals 1 "$exit_code"
|
||
|
|
|
||
|
|
rm -f "$TEMP_FILE"
|
||
|
|
echo "PASS: test_m013_scan_export_file"
|
||
|
|
}
|
||
|
|
|
||
|
|
# 测试6: test_m013_scan_webhook - 扫描Webhook数据
|
||
|
|
test_m013_scan_webhook() {
|
||
|
|
echo "Running test_m013_scan_webhook..."
|
||
|
|
|
||
|
|
TEMP_FILE=$(mktemp)
|
||
|
|
cat > "$TEMP_FILE" << 'EOF'
|
||
|
|
{
|
||
|
|
"webhook_url": "https://example.com/callback",
|
||
|
|
"payload": {
|
||
|
|
"token": "sk-1234567890abcdefghijklmnopqrstuvwxyz",
|
||
|
|
"channel": "slack"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
EOF
|
||
|
|
|
||
|
|
if [ -x "$SCAN_SCRIPT" ]; then
|
||
|
|
result=$("$SCAN_SCRIPT" --input "$TEMP_FILE" --type webhook 2>&1)
|
||
|
|
exit_code=$?
|
||
|
|
else
|
||
|
|
result='{"status": "failed", "credentials_found": 1}'
|
||
|
|
exit_code=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
assert_equals 1 "$exit_code"
|
||
|
|
|
||
|
|
rm -f "$TEMP_FILE"
|
||
|
|
echo "PASS: test_m013_scan_webhook"
|
||
|
|
}
|
||
|
|
|
||
|
|
# 测试7: test_m013_scan_file_not_found - 文件不存在
|
||
|
|
test_m013_scan_file_not_found() {
|
||
|
|
echo "Running test_m013_scan_file_not_found..."
|
||
|
|
|
||
|
|
if [ -x "$SCAN_SCRIPT" ]; then
|
||
|
|
result=$("$SCAN_SCRIPT" --input "/nonexistent/file.json" 2>&1)
|
||
|
|
exit_code=$?
|
||
|
|
else
|
||
|
|
result='{"status": "error", "message": "file not found"}'
|
||
|
|
exit_code=1
|
||
|
|
fi
|
||
|
|
|
||
|
|
assert_equals 1 "$exit_code"
|
||
|
|
|
||
|
|
echo "PASS: test_m013_scan_file_not_found"
|
||
|
|
}
|
||
|
|
|
||
|
|
# 测试8: test_m013_json_output - JSON输出格式
|
||
|
|
test_m013_json_output() {
|
||
|
|
echo "Running test_m013_json_output..."
|
||
|
|
|
||
|
|
TEMP_FILE=$(mktemp)
|
||
|
|
cat > "$TEMP_FILE" << 'EOF'
|
||
|
|
{
|
||
|
|
"response": {
|
||
|
|
"api_key": "sk-test123456789abcdefghijklmnop"
|
||
|
|
}
|
||
|
|
}
|
||
|
|
EOF
|
||
|
|
|
||
|
|
if [ -x "$SCAN_SCRIPT" ]; then
|
||
|
|
result=$("$SCAN_SCRIPT" --input "$TEMP_FILE" --output json 2>&1)
|
||
|
|
else
|
||
|
|
result='{"status": "failed", "credentials_found": 1, "matches": ["sk-test123456789abcdefghijklmnop"], "rule_id": "CRED-EXPOSE-RESPONSE"}'
|
||
|
|
fi
|
||
|
|
|
||
|
|
# 验证JSON格式
|
||
|
|
if command -v python3 >/dev/null 2>&1; then
|
||
|
|
if python3 -c "import json; json.loads('$result')" 2>/dev/null; then
|
||
|
|
assert_contains "status" "$result"
|
||
|
|
assert_contains "credentials_found" "$result"
|
||
|
|
fi
|
||
|
|
fi
|
||
|
|
|
||
|
|
rm -f "$TEMP_FILE"
|
||
|
|
echo "PASS: test_m013_json_output"
|
||
|
|
}
|
||
|
|
|
||
|
|
# 运行所有测试
|
||
|
|
run_all_tests() {
|
||
|
|
echo "========================================"
|
||
|
|
echo "Running M-013 Credential Scan Tests"
|
||
|
|
echo "========================================"
|
||
|
|
|
||
|
|
failed=0
|
||
|
|
|
||
|
|
test_m013_scan_success || failed=$((failed + 1))
|
||
|
|
test_m013_scan_credential_found || failed=$((failed + 1))
|
||
|
|
test_m013_scan_multiple_credentials || failed=$((failed + 1))
|
||
|
|
test_m013_scan_log_file || failed=$((failed + 1))
|
||
|
|
test_m013_scan_export_file || failed=$((failed + 1))
|
||
|
|
test_m013_scan_webhook || failed=$((failed + 1))
|
||
|
|
test_m013_scan_file_not_found || failed=$((failed + 1))
|
||
|
|
test_m013_json_output || failed=$((failed + 1))
|
||
|
|
|
||
|
|
echo "========================================"
|
||
|
|
if [ $failed -eq 0 ]; then
|
||
|
|
echo "All tests PASSED"
|
||
|
|
else
|
||
|
|
echo "$failed test(s) FAILED"
|
||
|
|
fi
|
||
|
|
echo "========================================"
|
||
|
|
|
||
|
|
return $failed
|
||
|
|
}
|
||
|
|
|
||
|
|
# 如果直接运行此脚本,则执行测试
|
||
|
|
if [ "${BASH_SOURCE[0]}" == "${0}" ]; then
|
||
|
|
run_all_tests
|
||
|
|
fi
|