From 7fa6854079be4c293e30502270f17294ad5b24dc Mon Sep 17 00:00:00 2001 From: Maor Rozenfeld <49363375+maor-rozenfeld@users.noreply.github.com> Date: Tue, 12 Aug 2025 10:19:44 +0200 Subject: [PATCH 1/6] Add a validation workflow --- .github/workflows/shell-validation.yml | 172 +++++++++++++++++++++++++ 1 file changed, 172 insertions(+) create mode 100644 .github/workflows/shell-validation.yml diff --git a/.github/workflows/shell-validation.yml b/.github/workflows/shell-validation.yml new file mode 100644 index 0000000..42e1387 --- /dev/null +++ b/.github/workflows/shell-validation.yml @@ -0,0 +1,172 @@ +name: Shell Script Validation + +on: + push: + branches: [ main ] + pull_request: + +jobs: + validate-shell-scripts: + runs-on: ubuntu-latest + name: Validate Shell Scripts + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Install shellcheck + run: | + sudo apt-get update + sudo apt-get install -y shellcheck + + - name: Install shfmt + run: | + curl -L -o shfmt https://github.com/mvdan/sh/releases/latest/download/shfmt_v3.7.0_linux_amd64 + chmod +x shfmt + sudo mv shfmt /usr/local/bin/ + + - name: Find shell scripts + id: find-scripts + run: | + echo "Found shell scripts:" + find scripts/ -type f -executable -o -name "*.sh" | tee scripts-list.txt + # Also check files with shell shebangs + find scripts/ -type f -exec grep -l '^#!/bin/sh\|^#!/bin/bash\|^#!/usr/bin/env sh\|^#!/usr/bin/env bash' {} \; | tee -a scripts-list.txt + sort -u scripts-list.txt > unique-scripts.txt + mv unique-scripts.txt scripts-list.txt + cat scripts-list.txt + + - name: POSIX Compliance Check (shellcheck) + run: | + echo "Running shellcheck for POSIX compliance..." + exit_code=0 + while IFS= read -r script; do + if [ -f "$script" ]; then + echo "Checking $script..." + if ! shellcheck -s sh -e SC1091 -e SC2039 "$script"; then + echo "❌ $script failed POSIX compliance check" + exit_code=1 + else + echo "✅ $script passed POSIX compliance check" + fi + echo "---" + fi + done < scripts-list.txt + exit $exit_code + + - name: Shell Script Linting (shellcheck extended) + run: | + echo "Running extended shellcheck analysis..." + exit_code=0 + while IFS= read -r script; do + if [ -f "$script" ]; then + echo "Linting $script..." + if ! shellcheck -f gcc "$script"; then + echo "❌ $script failed extended linting" + exit_code=1 + else + echo "✅ $script passed extended linting" + fi + echo "---" + fi + done < scripts-list.txt + exit $exit_code + + - name: Format Check (shfmt) + run: | + echo "Checking shell script formatting..." + exit_code=0 + while IFS= read -r script; do + if [ -f "$script" ]; then + echo "Checking format of $script..." + if ! shfmt -d -s "$script"; then + echo "❌ $script is not properly formatted" + exit_code=1 + else + echo "✅ $script is properly formatted" + fi + echo "---" + fi + done < scripts-list.txt + exit $exit_code + + - name: Executable Permissions Check + run: | + echo "Checking executable permissions..." + exit_code=0 + while IFS= read -r script; do + if [ -f "$script" ]; then + if [ ! -x "$script" ]; then + echo "⚠️ $script is not executable" + exit_code=1 + else + echo "✅ $script has correct executable permissions" + fi + fi + done < scripts-list.txt + exit $exit_code + + - name: Shebang Validation + run: | + echo "Validating shebangs..." + exit_code=0 + while IFS= read -r script; do + if [ -f "$script" ]; then + first_line=$(head -n1 "$script") + case "$first_line" in + "#!/bin/sh"|"#!/usr/bin/env sh") + echo "✅ $script has valid POSIX shebang: $first_line" + ;; + "#!/bin/bash"|"#!/usr/bin/env bash") + echo "⚠️ $script uses bash shebang (not POSIX): $first_line" + ;; + "#!"*) + echo "❌ $script has non-standard shebang: $first_line" + exit_code=1 + ;; + *) + echo "❌ $script missing shebang" + exit_code=1 + ;; + esac + fi + done < scripts-list.txt + exit $exit_code + + - name: Security Scan (basic) + run: | + echo "Running basic security checks..." + exit_code=0 + while IFS= read -r script; do + if [ -f "$script" ]; then + echo "Security scanning $script..." + + # Check for potentially dangerous patterns + if grep -n "eval\|exec\|system\|curl.*|.*sh\|wget.*|.*sh" "$script" | grep -v "^#"; then + echo "⚠️ $script contains potentially dangerous patterns" + fi + + # Check for hardcoded credentials patterns + if grep -ni "password\|secret\|token\|key" "$script" | grep -v "^#" | grep "="; then + echo "⚠️ $script may contain hardcoded credentials" + fi + + # Check for unquoted variables + if grep -n '\$[A-Za-z_][A-Za-z0-9_]*[^A-Za-z0-9_"]' "$script" | grep -v "^#"; then + echo "⚠️ $script has potentially unquoted variables" + fi + + echo "✅ Basic security scan completed for $script" + echo "---" + fi + done < scripts-list.txt + exit $exit_code + + - name: Summary Report + if: always() + run: | + echo "=== Shell Script Validation Summary ===" + echo "Scripts validated:" + cat scripts-list.txt | wc -l + echo "" + echo "Validation completed. Check individual step results above for details." \ No newline at end of file From ee0c83bba058998eca16dedfff746fbce36f366d Mon Sep 17 00:00:00 2001 From: Maor Rozenfeld <49363375+maor-rozenfeld@users.noreply.github.com> Date: Tue, 12 Aug 2025 10:32:44 +0200 Subject: [PATCH 2/6] Fix shellcheck --- scripts/install | 2 ++ scripts/share-logs | 5 +++-- scripts/tls | 8 +++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/scripts/install b/scripts/install index fc5292c..1c7136c 100644 --- a/scripts/install +++ b/scripts/install @@ -80,6 +80,7 @@ headline() { check_for_user_confirmation() { if [ "$INTERACTIVE" = "true" ]; then echo "Press Enter to continue, or Ctrl+C to cancel..." + # shellcheck disable=SC2034 read -r answer logs.txt echo "Uploading logs to S3..." LOGS_FILE=$(date +%Y%m%d_%H%M%S).log -curl -fLX PUT --upload-file logs.txt https://openops-client-logs.s3.amazonaws.com/$LOGS_FILE +curl -fLX PUT --upload-file logs.txt "https://openops-client-logs.s3.amazonaws.com/$LOGS_FILE" echo "Done. File uploaded to https://openops-client-logs.s3.amazonaws.com/$LOGS_FILE" echo "Please share the following file name with OpenOps: $LOGS_FILE" diff --git a/scripts/tls b/scripts/tls index c42d3b1..4a18602 100644 --- a/scripts/tls +++ b/scripts/tls @@ -70,6 +70,7 @@ headline() { check_for_user_confirmation() { if [ "$INTERACTIVE" = "true" ]; then echo "Press Enter to continue, or Ctrl+C to cancel..." + # shellcheck disable=SC2034 read -r answer Date: Tue, 12 Aug 2025 11:56:14 +0200 Subject: [PATCH 3/6] Remove redundant var for generate_random_password --- scripts/install | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/install b/scripts/install index 1c7136c..c63422f 100644 --- a/scripts/install +++ b/scripts/install @@ -98,7 +98,7 @@ get_latest_release_version() { } generate_random_password() { - dd if=/dev/urandom bs=1 count=512 2>/dev/null | LC_ALL=C tr -dc '[:alnum:]' | cut -c -"${1:-16}" + dd if=/dev/urandom bs=1 count=512 2>/dev/null | LC_ALL=C tr -dc '[:alnum:]' | cut -c -16 } generate_random_hex() { From 0a36da1df8aa2d00153768fca76f7593cc5ea0ba Mon Sep 17 00:00:00 2001 From: Maor Rozenfeld <49363375+maor-rozenfeld@users.noreply.github.com> Date: Tue, 12 Aug 2025 11:59:48 +0200 Subject: [PATCH 4/6] Fix lint --- scripts/install | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/scripts/install b/scripts/install index c63422f..fab0db9 100644 --- a/scripts/install +++ b/scripts/install @@ -175,9 +175,10 @@ install_docker_debian() { echo "Installing Docker on Debian-like..." sudo apt-get update -y sudo apt-get install -y apt-transport-https ca-certificates curl gnupg lsb-release - # shellcheck disable=SC2046 + # shellcheck disable=SC2046,SC1091 curl -fsSL https://download.docker.com/linux/$(. /etc/os-release; echo "$ID")/gpg \ | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg + # shellcheck disable=SC1091 echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] \ https://download.docker.com/linux/$(. /etc/os-release; echo "$ID") \ $(lsb_release -cs) stable" \ From 998279f6ab260c143a96821a55618912d6d99093 Mon Sep 17 00:00:00 2001 From: Maor Rozenfeld <49363375+maor-rozenfeld@users.noreply.github.com> Date: Tue, 12 Aug 2025 12:00:53 +0200 Subject: [PATCH 5/6] Remove format check --- .github/workflows/shell-validation.yml | 18 ------------------ 1 file changed, 18 deletions(-) diff --git a/.github/workflows/shell-validation.yml b/.github/workflows/shell-validation.yml index 42e1387..3214ad0 100644 --- a/.github/workflows/shell-validation.yml +++ b/.github/workflows/shell-validation.yml @@ -72,24 +72,6 @@ jobs: done < scripts-list.txt exit $exit_code - - name: Format Check (shfmt) - run: | - echo "Checking shell script formatting..." - exit_code=0 - while IFS= read -r script; do - if [ -f "$script" ]; then - echo "Checking format of $script..." - if ! shfmt -d -s "$script"; then - echo "❌ $script is not properly formatted" - exit_code=1 - else - echo "✅ $script is properly formatted" - fi - echo "---" - fi - done < scripts-list.txt - exit $exit_code - - name: Executable Permissions Check run: | echo "Checking executable permissions..." From d845a3e59264be7d0352ed8fd5ebeb16ff49afc2 Mon Sep 17 00:00:00 2001 From: Maor Rozenfeld <49363375+maor-rozenfeld@users.noreply.github.com> Date: Tue, 12 Aug 2025 12:01:47 +0200 Subject: [PATCH 6/6] Make scripts executable --- scripts/help | 0 scripts/install | 0 scripts/share-logs | 0 scripts/tls | 0 4 files changed, 0 insertions(+), 0 deletions(-) mode change 100644 => 100755 scripts/help mode change 100644 => 100755 scripts/install mode change 100644 => 100755 scripts/share-logs mode change 100644 => 100755 scripts/tls diff --git a/scripts/help b/scripts/help old mode 100644 new mode 100755 diff --git a/scripts/install b/scripts/install old mode 100644 new mode 100755 diff --git a/scripts/share-logs b/scripts/share-logs old mode 100644 new mode 100755 diff --git a/scripts/tls b/scripts/tls old mode 100644 new mode 100755