diff --git a/daytona/lib/common.sh b/daytona/lib/common.sh index 03919208..63729c99 100644 --- a/daytona/lib/common.sh +++ b/daytona/lib/common.sh @@ -164,15 +164,18 @@ run_server() { upload_file() { local local_path="${1}" local remote_path="${2}" - # Upload via base64 encoding through exec (no native CLI file upload) + + # SECURITY: Validate remote_path to prevent command injection via single-quote breakout + if [[ "$remote_path" == *"'"* || "$remote_path" == *'$'* || "$remote_path" == *'`'* || "$remote_path" == *$'\n'* ]]; then + log_error "Invalid remote path (contains unsafe characters): $remote_path" + return 1 + fi + + # base64 output is safe (alphanumeric + /+=) so no injection risk local content content=$(base64 -w0 "${local_path}" 2>/dev/null || base64 "${local_path}") - # SECURITY: Properly escape paths and content - local escaped_path - escaped_path=$(printf '%q' "${remote_path}") - local escaped_content - escaped_content=$(printf '%q' "${content}") - daytona exec "${DAYTONA_SANDBOX_ID}" -- bash -c "printf '%s' ${escaped_content} | base64 -d > ${escaped_path}" + + daytona exec "${DAYTONA_SANDBOX_ID}" -- bash -c "printf '%s' '${content}' | base64 -d > '${remote_path}'" } # Daytona has true SSH support — much better than exec-only providers diff --git a/e2b/lib/common.sh b/e2b/lib/common.sh index 4d05ccbd..a884135c 100644 --- a/e2b/lib/common.sh +++ b/e2b/lib/common.sh @@ -115,15 +115,18 @@ run_server() { upload_file() { local local_path="${1}" local remote_path="${2}" - # Upload via base64 encoding through exec + + # SECURITY: Validate remote_path to prevent command injection via single-quote breakout + if [[ "$remote_path" == *"'"* || "$remote_path" == *'$'* || "$remote_path" == *'`'* || "$remote_path" == *$'\n'* ]]; then + log_error "Invalid remote path (contains unsafe characters): $remote_path" + return 1 + fi + + # base64 output is safe (alphanumeric + /+=) so no injection risk local content content=$(base64 -w0 "${local_path}" 2>/dev/null || base64 "${local_path}") - # SECURITY: Properly escape the remote path - local escaped_path - escaped_path=$(printf '%q' "${remote_path}") - local escaped_content - escaped_content=$(printf '%q' "${content}") - e2b sandbox exec "${E2B_SANDBOX_ID}" -- bash -c "echo ${escaped_content} | base64 -d > ${escaped_path}" + + e2b sandbox exec "${E2B_SANDBOX_ID}" -- bash -c "printf '%s' '${content}' | base64 -d > '${remote_path}'" } interactive_session() { diff --git a/fly/lib/common.sh b/fly/lib/common.sh index 76ed4909..011bd644 100644 --- a/fly/lib/common.sh +++ b/fly/lib/common.sh @@ -311,13 +311,18 @@ run_server() { upload_file() { local local_path="$1" local remote_path="$2" - local content=$(base64 -w0 "$local_path" 2>/dev/null || base64 "$local_path") - # SECURITY: Properly escape paths and content to prevent injection - local escaped_path - escaped_path=$(printf '%q' "$remote_path") - local escaped_content - escaped_content=$(printf '%q' "$content") - run_server "echo $escaped_content | base64 -d > $escaped_path" + + # SECURITY: Validate remote_path to prevent command injection via single-quote breakout + if [[ "$remote_path" == *"'"* || "$remote_path" == *'$'* || "$remote_path" == *'`'* || "$remote_path" == *$'\n'* ]]; then + log_error "Invalid remote path (contains unsafe characters): $remote_path" + return 1 + fi + + # base64 output is safe (alphanumeric + /+=) so no injection risk + local content + content=$(base64 -w0 "$local_path" 2>/dev/null || base64 "$local_path") + + run_server "printf '%s' '${content}' | base64 -d > '${remote_path}'" } # Start an interactive SSH session on the Fly.io machine diff --git a/koyeb/lib/common.sh b/koyeb/lib/common.sh index 7dabd634..766e0feb 100644 --- a/koyeb/lib/common.sh +++ b/koyeb/lib/common.sh @@ -222,16 +222,18 @@ upload_file() { return 1 fi + # SECURITY: Validate remote_path to prevent command injection via single-quote breakout + if [[ "$remote_path" == *"'"* || "$remote_path" == *'$'* || "$remote_path" == *'`'* || "$remote_path" == *$'\n'* ]]; then + log_error "Invalid remote path (contains unsafe characters): $remote_path" + return 1 + fi + # SECURITY: base64 -w0 produces single-line output (no newline injection) + # base64 output is safe (alphanumeric + /+=) so no injection risk local content content=$(base64 -w0 "$local_path" 2>/dev/null || base64 "$local_path") - # SECURITY: Properly escape remote_path to prevent injection - local escaped_path - escaped_path=$(printf '%q' "$remote_path") - - # base64 output is safe (alphanumeric + /+=) so no injection risk - run_server "printf '%s' '$content' | base64 -d > $escaped_path" + run_server "printf '%s' '${content}' | base64 -d > '${remote_path}'" } # Wait for cloud-init or basic system readiness diff --git a/northflank/lib/common.sh b/northflank/lib/common.sh index b21a8e03..ce8ad4d5 100644 --- a/northflank/lib/common.sh +++ b/northflank/lib/common.sh @@ -166,16 +166,18 @@ run_server() { upload_file() { local local_path="${1}" local remote_path="${2}" + + # SECURITY: Validate remote_path to prevent command injection via single-quote breakout + if [[ "$remote_path" == *"'"* || "$remote_path" == *'$'* || "$remote_path" == *'`'* || "$remote_path" == *$'\n'* ]]; then + log_error "Invalid remote path (contains unsafe characters): $remote_path" + return 1 + fi + + # base64 output is safe (alphanumeric + /+=) so no injection risk local content content=$(base64 -w0 "${local_path}" 2>/dev/null || base64 "${local_path}") - # SECURITY: Properly escape paths and content to prevent injection - local escaped_path - escaped_path=$(printf '%q' "${remote_path}") - local escaped_content - escaped_content=$(printf '%q' "${content}") - - run_server "echo ${escaped_content} | base64 -d > ${escaped_path}" + run_server "printf '%s' '${content}' | base64 -d > '${remote_path}'" } # Start an interactive shell session on the Northflank service