From 89c85f671ad0778b745766ea626d8bc123a4b2de Mon Sep 17 00:00:00 2001 From: Vijit Singh Date: Sun, 7 Jun 2026 02:22:02 -0500 Subject: [PATCH] feat: validate P2POOL_NODE_HOSTNAME before building (closes #8) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The host is interpolated straight into the XMRig pool URL, so validate it in parse_config: it must be set and match a hostname/FQDN/IPv4/IPv6 charset ([A-Za-z0-9._:-]). This rejects an empty/missing value, the unfilled template placeholder (<...>), and shell/URL metacharacters — failing fast with a clear message before any source patch or build. The DONATION half of #8 landed earlier in #26; this completes the issue. Co-Authored-By: Claude Opus 4.8 --- rigforge.sh | 11 ++++++++++- tests/run.sh | 14 ++++++++++++++ 2 files changed, 24 insertions(+), 1 deletion(-) diff --git a/rigforge.sh b/rigforge.sh index cb20ddf..864ae37 100755 --- a/rigforge.sh +++ b/rigforge.sh @@ -142,7 +142,16 @@ parse_config() { if [ "$WORKER_CONFIG_FILE" == "null" ] || [ -z "$WORKER_CONFIG_FILE" ]; then error "WORKER_CONFIG_FILE is not defined in $CONFIG_JSON." fi - P2POOL_NODE_HOSTNAME=$(jq -r .P2POOL_NODE_HOSTNAME "$CONFIG_JSON") + P2POOL_NODE_HOSTNAME=$(jq -r '.P2POOL_NODE_HOSTNAME // empty' "$CONFIG_JSON") + # The host goes straight into the XMRig pool URL, so validate it before building: it must be set + # and look like a hostname/FQDN or an IPv4/IPv6 literal. This also rejects the unfilled template + # placeholder (<...>) and any shell/URL metacharacters. + if [ -z "$P2POOL_NODE_HOSTNAME" ]; then + error "P2POOL_NODE_HOSTNAME is required in $CONFIG_JSON (your pool/stack host or IP)." + fi + if ! [[ "$P2POOL_NODE_HOSTNAME" =~ ^[A-Za-z0-9._:-]+$ ]]; then + error "P2POOL_NODE_HOSTNAME is not a valid host/IP: '$P2POOL_NODE_HOSTNAME'. Use a hostname, FQDN, or IP address." + fi ACCESS_TOKEN=$(jq -r '.ACCESS_TOKEN // empty' "$CONFIG_JSON") if [ -z "$ACCESS_TOKEN" ]; then ACCESS_TOKEN=$(hostname) diff --git a/tests/run.sh b/tests/run.sh index 47132b4..76c2877 100644 --- a/tests/run.sh +++ b/tests/run.sh @@ -149,6 +149,20 @@ assert_eq "FQDN passed through" "$(parse_and_print "$c" "$ROOT" P2 c="$(mkconf ip "{ \"P2POOL_NODE_HOSTNAME\": \"10.0.0.5\", $CFG_TPL }")" assert_eq "IPv4 host passed through" "$(parse_and_print "$c" "$ROOT" P2POOL_NODE_ADDRESS)" "10.0.0.5" +echo "== unit: hostname validation (#8) ==" +for h in box box.lan 10.0.0.5 fe80::1 rig-01; do + c="$(mkconf hnok "{ \"P2POOL_NODE_HOSTNAME\": \"$h\", $CFG_TPL }")" + parse_rc "$c" "$ROOT"; assert_rc "host '$h' accepted" "$?" "0" +done +c="$(mkconf hnempty "{ \"P2POOL_NODE_HOSTNAME\": \"\", $CFG_TPL }")" +parse_rc "$c" "$ROOT"; assert_rc "empty host rejected" "$?" "1" +c="$(mkconf hnmiss "{ $CFG_TPL }")" +parse_rc "$c" "$ROOT"; assert_rc "missing host rejected" "$?" "1" +for h in 'bad host' 'evil;rm' 'a/b' ''; do + c="$(mkconf hnbad "{ \"P2POOL_NODE_HOSTNAME\": \"$h\", $CFG_TPL }")" + parse_rc "$c" "$ROOT"; assert_rc "host '$h' rejected" "$?" "1" +done + echo "== unit: parse_config — workspace + token + template resolution ==" c="$(mkconf dyn "{ \"HOME_DIR\": \"DYNAMIC_HOME\", \"P2POOL_NODE_HOSTNAME\": \"h\", $CFG_TPL }")" assert_eq "DYNAMIC_HOME -> script data dir" "$(parse_and_print "$c" "$ROOT" WORKER_ROOT)" "$ROOT/data/worker"