fix(security): enforce audited account, network and resource boundaries
Implement B01-B06 with regression coverage and retained validation evidence. Preserve the production ingress preflight; F04 runtime verification remains open.
This commit is contained in:
@@ -23,6 +23,57 @@ if [ -n "$port" ]; then
|
||||
case "$port" in ""|*[!0-9]*) echo "APP_PUBLIC_BASE_URL contains an invalid port." >&2; exit 1 ;; esac
|
||||
fi
|
||||
|
||||
sed "s/__APP_EXTERNAL_HOST__/$external_host/g" \
|
||||
/etc/nginx/jobtracker.conf.template \
|
||||
> /etc/nginx/conf.d/default.conf
|
||||
scheme="${origin%%:*}"
|
||||
http_config="$(mktemp)"
|
||||
checks="$(mktemp)"
|
||||
trap 'rm -f "$http_config" "$checks"' EXIT
|
||||
|
||||
case "${INGRESS_MODE:-proxy}" in
|
||||
proxy)
|
||||
[ "$scheme" = https ] || { echo "Proxy ingress requires the canonical HTTPS origin." >&2; exit 1; }
|
||||
[ -n "${INGRESS_PROXY_CIDRS:-}" ] || { echo "INGRESS_PROXY_CIDRS must identify the observed Traefik socket peers." >&2; exit 1; }
|
||||
printf 'geo $realip_remote_addr $ingress_peer_trusted {\n default 0;\n' > "$http_config"
|
||||
for cidr in $INGRESS_PROXY_CIDRS; do
|
||||
case "$cidr" in
|
||||
*[!0-9A-Fa-f:./]*|*/0|*/*/*) echo "Invalid ingress proxy CIDR." >&2; exit 1 ;;
|
||||
*/*) ;;
|
||||
*) echo "Ingress proxy peers must use explicit CIDR notation." >&2; exit 1 ;;
|
||||
esac
|
||||
prefix="${cidr##*/}"
|
||||
case "$prefix" in ''|*[!0-9]*) echo "Invalid ingress prefix." >&2; exit 1 ;; esac
|
||||
# Only RFC1918/ULA ranges may group peers; all other addresses must be individual.
|
||||
# This also rejects IPv6 prefixes covering every IPv4-mapped address.
|
||||
case "$cidr" in
|
||||
[fF][cCdD]*:*) minimum=64; maximum=128 ;;
|
||||
*:*) minimum=128; maximum=128 ;;
|
||||
10.*|192.168.*|172.1[6-9].*|172.2[0-9].*|172.3[01].*) minimum=24; maximum=32 ;;
|
||||
*) minimum=32; maximum=32 ;;
|
||||
esac
|
||||
[ "$prefix" -ge "$minimum" ] && [ "$prefix" -le "$maximum" ] || { echo "Ingress proxy CIDR is too broad or invalid." >&2; exit 1; }
|
||||
printf ' %s 1;\n' "$cidr" >> "$http_config"
|
||||
done
|
||||
printf '}\nreal_ip_header X-Forwarded-For;\nreal_ip_recursive off;\n' >> "$http_config"
|
||||
for cidr in $INGRESS_PROXY_CIDRS; do printf 'set_real_ip_from %s;\n' "$cidr" >> "$http_config"; done
|
||||
cat > "$checks" <<'CHECKS'
|
||||
if ($ingress_peer_trusted = 0) { return 403; }
|
||||
if ($http_x_forwarded_proto != "https") { return 400; }
|
||||
if ($http_x_forwarded_for = "") { return 400; }
|
||||
if ($http_x_forwarded_for ~ ",") { return 400; }
|
||||
# A malformed address is not forwarded verbatim: realip leaves the socket IP intact.
|
||||
CHECKS
|
||||
;;
|
||||
direct)
|
||||
[ "$scheme" = http ] || { echo "Direct ingress is only supported for HTTP development." >&2; exit 1; }
|
||||
;;
|
||||
*) echo "INGRESS_MODE must be proxy or direct." >&2; exit 1 ;;
|
||||
esac
|
||||
|
||||
sed -e "s/__APP_EXTERNAL_HOST__/$external_host/g" \
|
||||
-e "s/__APP_EXTERNAL_AUTHORITY__/$authority/g" \
|
||||
-e "s/__APP_EXTERNAL_SCHEME__/$scheme/g" \
|
||||
-e "/__APP_INGRESS_HTTP__/r $http_config" -e '/__APP_INGRESS_HTTP__/d' \
|
||||
-e "/__APP_INGRESS_CHECK__/r $checks" -e '/__APP_INGRESS_CHECK__/d' \
|
||||
/etc/nginx/jobtracker.conf.template > /etc/nginx/conf.d/default.conf
|
||||
|
||||
# Validate addresses and the generated configuration before the entrypoint starts serving.
|
||||
nginx -t
|
||||
|
||||
Reference in New Issue
Block a user