发布最新版本到 dev 分支用于验证

This commit is contained in:
sindricn
2025-09-24 14:59:19 +08:00
parent e0bb956a57
commit 64892fd428
22 changed files with 5901 additions and 562 deletions
+226
View File
@@ -0,0 +1,226 @@
#!/bin/bash
# 输入验证安全模块
# 防止命令注入和恶意输入
# 严格错误处理
set -euo pipefail
# 安全的域名验证
validate_domain_secure() {
local domain="$1"
local max_length=253
# 长度检查
if [[ ${#domain} -gt $max_length ]]; then
echo "域名长度超过限制 ($max_length 字符)" >&2
return 1
fi
# 基本字符检查 - 只允许字母、数字、点和连字符
if [[ ! "$domain" =~ ^[a-zA-Z0-9.-]+$ ]]; then
echo "域名包含非法字符" >&2
return 1
fi
# 标准域名格式验证
if [[ ! "$domain" =~ ^[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(\.[a-zA-Z0-9]([a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*$ ]]; then
echo "域名格式不正确" >&2
return 1
fi
# 防止特殊字符注入
if [[ "$domain" == *'$()'* ]] || [[ "$domain" == *'`'* ]] || [[ "$domain" == *';'* ]] || [[ "$domain" == *'&&'* ]] || [[ "$domain" == *'||'* ]]; then
echo "域名包含危险字符" >&2
return 1
fi
return 0
}
# 安全的邮箱验证
validate_email_secure() {
local email="$1"
local max_length=254
# 长度检查
if [[ ${#email} -gt $max_length ]]; then
echo "邮箱长度超过限制 ($max_length 字符)" >&2
return 1
fi
# 基本字符检查
if [[ ! "$email" =~ ^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$ ]]; then
echo "邮箱格式不正确" >&2
return 1
fi
# 防止命令注入
if [[ "$email" == *'$()'* ]] || [[ "$email" == *'`'* ]] || [[ "$email" == *';'* ]] || [[ "$email" == *'&&'* ]] || [[ "$email" == *'||'* ]]; then
echo "邮箱包含危险字符" >&2
return 1
fi
return 0
}
# 安全的端口验证
validate_port_secure() {
local port="$1"
# 检查是否为纯数字
if [[ ! "$port" =~ ^[0-9]+$ ]]; then
echo "端口必须为数字" >&2
return 1
fi
# 端口范围检查
if [[ $port -lt 1 ]] || [[ $port -gt 65535 ]]; then
echo "端口范围必须在 1-65535 之间" >&2
return 1
fi
return 0
}
# 安全的密码验证
validate_password_secure() {
local password="$1"
local min_length=8
local max_length=128
# 长度检查
if [[ ${#password} -lt $min_length ]]; then
echo "密码长度至少需要 $min_length 字符" >&2
return 1
fi
if [[ ${#password} -gt $max_length ]]; then
echo "密码长度不能超过 $max_length 字符" >&2
return 1
fi
# 防止命令注入字符
if [[ "$password" == *'$()'* ]] || [[ "$password" == *'`'* ]] || [[ "$password" == *';'* ]] || [[ "$password" == *'&&'* ]] || [[ "$password" == *'||'* ]]; then
echo "密码包含危险字符" >&2
return 1
fi
return 0
}
# 安全的数字输入验证
validate_number_secure() {
local number="$1"
local min_val="${2:-0}"
local max_val="${3:-999999}"
# 检查是否为纯数字
if [[ ! "$number" =~ ^[0-9]+$ ]]; then
echo "输入必须为数字" >&2
return 1
fi
# 范围检查
if [[ $number -lt $min_val ]] || [[ $number -gt $max_val ]]; then
echo "数字范围必须在 $min_val-$max_val 之间" >&2
return 1
fi
return 0
}
# 安全的文件路径验证
validate_filepath_secure() {
local filepath="$1"
# 防止路径遍历攻击
if [[ "$filepath" == *'..'* ]] || [[ "$filepath" == *'//'* ]]; then
echo "文件路径包含危险字符" >&2
return 1
fi
# 防止命令注入
if [[ "$filepath" == *'$()'* ]] || [[ "$filepath" == *'`'* ]] || [[ "$filepath" == *';'* ]] || [[ "$filepath" == *'&&'* ]] || [[ "$filepath" == *'||'* ]]; then
echo "文件路径包含危险字符" >&2
return 1
fi
# 检查路径长度
if [[ ${#filepath} -gt 4096 ]]; then
echo "文件路径过长" >&2
return 1
fi
return 0
}
# 安全的用户输入读取函数
read_input_secure() {
local prompt="$1"
local validator="$2"
local max_attempts=3
local attempt=1
local input
while [[ $attempt -le $max_attempts ]]; do
echo -n "$prompt: "
read -r input
# 空输入检查
if [[ -z "$input" ]]; then
echo "输入不能为空" >&2
((attempt++))
continue
fi
# 调用验证函数
if "$validator" "$input"; then
echo "$input"
return 0
fi
((attempt++))
if [[ $attempt -le $max_attempts ]]; then
echo "请重新输入 (剩余尝试次数: $((max_attempts - attempt + 1)))"
fi
done
echo "输入验证失败,已达到最大尝试次数" >&2
return 1
}
# 清理和转义用户输入
sanitize_input() {
local input="$1"
# 移除前后空白字符
input=$(echo "$input" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')
# 转义特殊字符
input=$(echo "$input" | sed 's/[`$();]/\\&/g')
echo "$input"
}
# 安全的命令执行函数
execute_command_secure() {
local cmd=("$@")
# 记录命令执行日志
echo "[$(date '+%Y-%m-%d %H:%M:%S')] 执行命令: ${cmd[*]}" >&2
# 使用数组形式执行命令,防止命令注入
"${cmd[@]}"
}
# 导出函数供其他脚本使用
export -f validate_domain_secure
export -f validate_email_secure
export -f validate_port_secure
export -f validate_password_secure
export -f validate_number_secure
export -f validate_filepath_secure
export -f read_input_secure
export -f sanitize_input
export -f execute_command_secure