#!/usr/bin/env bash # 浏览器来源为可选项:缺失或留空时保持宽松策略,显式配置时校验。 # 不 source .env,避免执行环境文件中的内容。 security_origin_script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # shellcheck source=scripts/init-public-api-base-url.sh . "${security_origin_script_dir}/init-public-api-base-url.sh" security_origin_valid() { local value rest value="$(public_url_normalize "$1")" public_url_validate "$value" || return 1 rest="${value#*://}" [[ "$rest" != */* ]] } init_security_origin() { local file="${1:-.env}" local api_url origin current item scheme rest authority [ -f "$file" ] || { echo "❌ 环境配置文件不存在: $file" >&2 return 1 } current="$(public_url_read_env_value "$file" "CONFIG_SECURITY_ORIGIN")" if [ -z "$current" ]; then echo " ✓ 未配置浏览器来源,后端将默认允许所有来源" return 0 fi # 旧版样例值不是用户选择的白名单;非本机部署升级时清空,恢复缺省策略。 if [ "$current" = 'http://127.0.0.1,http://localhost' ]; then api_url="$(public_url_read_env_value "$file" "CONFIG_PUBLIC_API_BASE_URL")" if public_url_validate "$api_url"; then scheme="${api_url%%://*}" rest="${api_url#*://}" authority="${rest%%/*}" origin="${scheme}://${authority}" if [ "$origin" != 'http://127.0.0.1' ] && [ "$origin" != 'http://localhost' ]; then public_url_write_env_value "$file" "CONFIG_SECURITY_ORIGIN" "" echo " ✓ 已清理历史浏览器来源样例值,后端将默认允许所有来源" return 0 fi fi fi local -a origins case "$current" in ,*|*,|*,,*) echo "❌ CONFIG_SECURITY_ORIGIN 包含空的来源地址" >&2 return 1 ;; esac IFS=',' read -r -a origins <<< "$current" [ "${#origins[@]}" -gt 0 ] || return 1 for item in "${origins[@]}"; do item="$(printf '%s' "$item" | sed 's/^[[:space:]]*//;s/[[:space:]]*$//')" if ! security_origin_valid "$item"; then echo "❌ CONFIG_SECURITY_ORIGIN 包含无效或非浏览器来源,请填写 http(s) Origin,不能使用通配符或路径" >&2 return 1 fi done } if [ "${BASH_SOURCE[0]}" = "$0" ]; then init_security_origin "${1:-.env}" fi