diff --git a/sh/e2e/lib/clouds/aws.sh b/sh/e2e/lib/clouds/aws.sh index 335453c81..ebe882b56 100644 --- a/sh/e2e/lib/clouds/aws.sh +++ b/sh/e2e/lib/clouds/aws.sh @@ -145,9 +145,16 @@ _aws_exec() { fi fi + # Base64-encode the command to prevent shell injection when passed as an + # SSH argument. The encoded string contains only [A-Za-z0-9+/=] characters, + # making it safe to embed in single quotes. Stdin is preserved for callers + # that pipe data into cloud_exec. + local encoded_cmd + encoded_cmd=$(printf '%s' "${cmd}" | base64 | tr -d '\n') + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ -o ConnectTimeout=10 -o LogLevel=ERROR -o BatchMode=yes \ - "ubuntu@${_AWS_INSTANCE_IP}" "${cmd}" + "ubuntu@${_AWS_INSTANCE_IP}" "printf '%s' '${encoded_cmd}' | base64 -d | bash" } # --------------------------------------------------------------------------- diff --git a/sh/e2e/lib/clouds/digitalocean.sh b/sh/e2e/lib/clouds/digitalocean.sh index fcb09b68e..9131bfec9 100644 --- a/sh/e2e/lib/clouds/digitalocean.sh +++ b/sh/e2e/lib/clouds/digitalocean.sh @@ -155,9 +155,16 @@ _digitalocean_exec() { return 1 fi + # Base64-encode the command to prevent shell injection when passed as an + # SSH argument. The encoded string contains only [A-Za-z0-9+/=] characters, + # making it safe to embed in single quotes. Stdin is preserved for callers + # that pipe data into cloud_exec. + local encoded_cmd + encoded_cmd=$(printf '%s' "${cmd}" | base64 | tr -d '\n') + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ -o ConnectTimeout=10 -o LogLevel=ERROR -o BatchMode=yes \ - "root@${ip}" "${cmd}" + "root@${ip}" "printf '%s' '${encoded_cmd}' | base64 -d | bash" } # --------------------------------------------------------------------------- diff --git a/sh/e2e/lib/clouds/gcp.sh b/sh/e2e/lib/clouds/gcp.sh index 4294dcc4c..5871c264e 100644 --- a/sh/e2e/lib/clouds/gcp.sh +++ b/sh/e2e/lib/clouds/gcp.sh @@ -158,9 +158,16 @@ _gcp_exec() { fi fi + # Base64-encode the command to prevent shell injection when passed as an + # SSH argument. The encoded string contains only [A-Za-z0-9+/=] characters, + # making it safe to embed in single quotes. Stdin is preserved for callers + # that pipe data into cloud_exec. + local encoded_cmd + encoded_cmd=$(printf '%s' "${cmd}" | base64 | tr -d '\n') + ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null \ -o ConnectTimeout=10 -o LogLevel=ERROR -o BatchMode=yes \ - "${ssh_user}@${_GCP_INSTANCE_IP}" "${cmd}" + "${ssh_user}@${_GCP_INSTANCE_IP}" "printf '%s' '${encoded_cmd}' | base64 -d | bash" } # --------------------------------------------------------------------------- diff --git a/sh/e2e/lib/clouds/hetzner.sh b/sh/e2e/lib/clouds/hetzner.sh index 80eb0a895..0ab5dc880 100644 --- a/sh/e2e/lib/clouds/hetzner.sh +++ b/sh/e2e/lib/clouds/hetzner.sh @@ -135,12 +135,19 @@ _hetzner_exec() { return 1 fi + # Base64-encode the command to prevent shell injection when passed as an + # SSH argument. The encoded string contains only [A-Za-z0-9+/=] characters, + # making it safe to embed in single quotes. Stdin is preserved for callers + # that pipe data into cloud_exec. + local encoded_cmd + encoded_cmd=$(printf '%s' "${cmd}" | base64 | tr -d '\n') + ssh -o StrictHostKeyChecking=no \ -o UserKnownHostsFile=/dev/null \ -o LogLevel=ERROR \ -o BatchMode=yes \ -o ConnectTimeout=10 \ - "root@${ip}" "${cmd}" + "root@${ip}" "printf '%s' '${encoded_cmd}' | base64 -d | bash" } # ---------------------------------------------------------------------------