NPM: validate canonical_https for www redirects; docs and env example
- Reject non-https, paths, and injection-prone chars in advanced_config 301 targets - E2E list: phoenix marketing note, the-order HAProxy remediation, 2026-03-27 passes - AGENTS.md: scoped Cloudflare token pointer; smom-dbis-138 dotenv load note - .env.master.example: DNS script flags and scoped token guidance Made-with: Cursor
This commit is contained in:
@@ -131,6 +131,30 @@ resolve_proxy_host_id() {
|
||||
.id' 2>/dev/null | head -n1
|
||||
}
|
||||
|
||||
# www → apex redirect: only https://hostname[:port] (no path/query); rejects characters that could break nginx advanced_config.
|
||||
validate_canonical_https_redirect() {
|
||||
local url="$1"
|
||||
local ctx="${2:-canonical_https}"
|
||||
if [[ "$url" != https://* ]]; then
|
||||
echo " ❌ $ctx: canonical_https must start with https:// (got: $url)"
|
||||
return 1
|
||||
fi
|
||||
if [[ "$url" == *$'\n'* || "$url" == *$'\r'* || "$url" == *' '* || "$url" == *';'* || "$url" == *'$'* || "$url" == *'`'* ]]; then
|
||||
echo " ❌ $ctx: canonical_https contains forbidden characters (no spaces, semicolons, dollar, backticks)"
|
||||
return 1
|
||||
fi
|
||||
local rest="${url#https://}"
|
||||
if [[ "$rest" == */* ]]; then
|
||||
echo " ❌ $ctx: canonical_https must not include a path (got: $url)"
|
||||
return 1
|
||||
fi
|
||||
if ! [[ "$rest" =~ ^[a-zA-Z0-9._-]+(:[0-9]{1,5})?$ ]]; then
|
||||
echo " ❌ $ctx: canonical_https must be https://hostname or https://hostname:port (got: $url)"
|
||||
return 1
|
||||
fi
|
||||
return 0
|
||||
}
|
||||
|
||||
# Function to add proxy host (POST) when domain does not exist
|
||||
# Optional 6th arg: canonical HTTPS apex for www-style hosts (sets advanced_config 301 → apex$request_uri)
|
||||
add_proxy_host() {
|
||||
@@ -141,6 +165,9 @@ add_proxy_host() {
|
||||
local block_exploits=${5:-false}
|
||||
local canonical_https="${6:-}"
|
||||
local adv_line=""
|
||||
if [ -n "$canonical_https" ] && ! validate_canonical_https_redirect "$canonical_https" "add_proxy_host($domain)"; then
|
||||
return 1
|
||||
fi
|
||||
if [ -n "$canonical_https" ]; then
|
||||
adv_line="return 301 ${canonical_https}\$request_uri;"
|
||||
fi
|
||||
@@ -174,7 +201,11 @@ add_proxy_host() {
|
||||
local id
|
||||
id=$(echo "$resp" | jq -r '.id // empty' 2>/dev/null)
|
||||
if [ -n "$id" ] && [ "$id" != "null" ]; then
|
||||
echo " ✅ Added: $domain -> http://${forward_host}:${forward_port} (WebSocket: $websocket)"
|
||||
if [ -n "$canonical_https" ]; then
|
||||
echo " ✅ Added: $domain -> http://${forward_host}:${forward_port} (WebSocket: $websocket) + 301 → ${canonical_https}\$request_uri"
|
||||
else
|
||||
echo " ✅ Added: $domain -> http://${forward_host}:${forward_port} (WebSocket: $websocket)"
|
||||
fi
|
||||
return 0
|
||||
else
|
||||
local err
|
||||
@@ -202,7 +233,10 @@ update_proxy_host() {
|
||||
local websocket=$3
|
||||
local block_exploits=${4:-true}
|
||||
local canonical_https="${5:-}"
|
||||
|
||||
if [ -n "$canonical_https" ] && ! validate_canonical_https_redirect "$canonical_https" "update_proxy_host($domain)"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Parse target URL
|
||||
local scheme=$(echo "$target" | sed -E 's|^([^:]+):.*|\1|')
|
||||
local hostname=$(echo "$target" | sed -E 's|^[^/]+//([^:]+):.*|\1|')
|
||||
@@ -367,7 +401,8 @@ update_proxy_host "www.the-order.sankofa.nexus" "http://${THE_ORDER_UPSTREAM_IP}
|
||||
# Sankofa Studio (FusionAI) — VMID 7805; UI at /studio/ on same origin (port 8000). Prefer IP_SANKOFA_STUDIO from ip-addresses.conf / .env
|
||||
IP_SANKOFA_STUDIO="${IP_SANKOFA_STUDIO:-192.168.11.72}"
|
||||
SANKOFA_STUDIO_PORT="${SANKOFA_STUDIO_PORT:-8000}"
|
||||
update_proxy_host "studio.sankofa.nexus" "http://${IP_SANKOFA_STUDIO}:${SANKOFA_STUDIO_PORT}" false && updated_count=$((updated_count + 1)) || { add_proxy_host "studio.sankofa.nexus" "${IP_SANKOFA_STUDIO}" "${SANKOFA_STUDIO_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
# block_exploits false — studio UI/API may POST; align with portal policy (avoid spurious 405 from NPM WAF)
|
||||
update_proxy_host "studio.sankofa.nexus" "http://${IP_SANKOFA_STUDIO}:${SANKOFA_STUDIO_PORT}" false false && updated_count=$((updated_count + 1)) || { add_proxy_host "studio.sankofa.nexus" "${IP_SANKOFA_STUDIO}" "${SANKOFA_STUDIO_PORT}" false false && updated_count=$((updated_count + 1)); } || failed_count=$((failed_count + 1))
|
||||
|
||||
echo ""
|
||||
echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"
|
||||
|
||||
Reference in New Issue
Block a user