Files
KNEL-AIMiddleware/docs/audit/2026-02-20/02-shell-script-security.md
Charles N Wyble 787fe1f702 docs(audit): add comprehensive security audit report
External security audit of KNEL-AIMiddleware before release:

- FINAL-REPORT.md: Executive summary, risk assessment, remediation roadmap
- 01-dockerfile-security.md: 38/40 containers run as root (HIGH)
- 02-shell-script-security.md: 83 missing set -e/u directives (HIGH)
- 03-docker-compose-security.md: 3 privileged services documented (MEDIUM)
- 04-secrets-audit.md: PASS - no hardcoded secrets found
- 05-vulnerability-scan.md: 14+ CVEs, 1 CRITICAL OpenSSL (golang:1.23-alpine)

Assessment: CONDITIONAL PASS for release

💘 Generated with Crush

Assisted-by: GLM-5 via Crush <crush@charm.land>
2026-02-20 11:59:09 -05:00

5.2 KiB

Shell Script Security Audit

Date: 2026-02-20 Auditor: External Security Review Scope: All shell scripts in project root and scripts/ directory

Executive Summary

Metric Value
Total Scripts Analyzed 45+
Scripts Missing set -e 38
Scripts Missing set -u 45 (all)
Scripts with Unquoted Variables 4

Detailed Findings

1. Missing Error Handling (HIGH)

Severity: HIGH Affected: 38 of 45 scripts (84%) CWE: CWE-252 (Unchecked Return Value)

Description

Most shell scripts lack set -e which causes scripts to continue executing even when commands fail. This can lead to:

  • Silent failures going undetected
  • Partial/incomplete operations
  • Security bypasses if validation commands fail

Pattern Found

#!/bin/bash
# Script continues even if commands fail
docker build ...  # If this fails, script continues
echo "Build complete"  # Misleading success message

Correct Pattern

#!/bin/bash
set -euo pipefail
# Script exits immediately on any error

Affected Script Categories

  • Wrapper scripts (mcp-*-wrapper.sh): 34 scripts
  • LSP wrapper scripts (lsp-*-wrapper.sh): Multiple
  • Build scripts (scripts/BuildAll.sh): 1 script

Recommendation

Add to all scripts:

#!/bin/bash
set -euo pipefail

2. Missing Undefined Variable Protection (HIGH)

Severity: HIGH Affected: 45 of 45 scripts (100%) CWE: CWE-456 (Missing Initialization of a Variable)

Description

No scripts use set -u which prevents the use of undefined variables. This can cause:

  • Commands to execute with empty values
  • Unexpected behavior with missing environment variables
  • Potential security issues if variables like paths are empty

Example Risk

#!/bin/bash
# If API_KEY is not set, this becomes: curl -H "Authorization: Bearer "
curl -H "Authorization: Bearer $API_KEY" https://api.example.com

Recommendation

#!/bin/bash
set -u  # Exit on undefined variable

# Or provide defaults:
API_KEY="${API_KEY:-}"  # Empty default
API_KEY="${API_KEY:-default_value}"  # Non-empty default

3. Unquoted Variables (MEDIUM)

Severity: MEDIUM Affected: 4 scripts CWE: CWE-77 (Command Injection)

Description

Some scripts use unquoted variables which can lead to:

  • Word splitting on spaces
  • Glob expansion
  • Potential command injection

Affected Files

Found in various wrapper scripts where environment variables are passed through.

Pattern to Avoid

# Dangerous - unquoted
docker run $CONTAINER_NAME

# Safe - quoted
docker run "$CONTAINER_NAME"

Recommendation

Always quote variable expansions:

docker run "${CONTAINER_NAME}"

4. No Input Validation (MEDIUM)

Severity: MEDIUM Affected: All wrapper scripts CWE: CWE-20 (Improper Input Validation)

Description

Wrapper scripts pass environment variables directly to Docker commands without validation.

Example

#!/bin/bash
docker run --rm -i \
  -e PROXMOX_HOST="${PROXMOX_HOST}" \
  -e PROXMOX_USER="${PROXMOX_USER}" \
  kneldevstack-aimiddleware-proxmox-mcp

No validation that:

  • Variables are set
  • Values are in expected format
  • Values don't contain injection characters

Recommendation

Add validation for critical variables:

#!/bin/bash
set -euo pipefail

: "${REQUIRED_VAR:?REQUIRED_VAR must be set}"

# Optional validation
if [[ ! "$URL" =~ ^https?:// ]]; then
  echo "Invalid URL format" >&2
  exit 1
fi

Script Categories

MCP Wrapper Scripts (34 files)

  • Pattern: mcp-*-wrapper.sh
  • Purpose: Launch MCP server containers with environment configuration
  • Risk: Medium - primarily pass-through scripts

LSP Wrapper Scripts (5+ files)

  • Pattern: lsp-*-wrapper.sh
  • Purpose: Launch LSP server containers
  • Risk: Low - typically no sensitive data

Build/Utility Scripts (scripts/)

  • BuildAll.sh - Build automation
  • validate-all.sh - Validation testing
  • Risk: Low - development utilities

Positive Findings

  1. No command substitution injection - Variables passed as arguments, not evaluated
  2. Consistent naming convention - Easy to identify script purpose
  3. Simple pass-through design - Limited attack surface
  4. No hardcoded secrets - All credentials from environment

Remediation Priority

Priority Finding Effort Impact
1 Add set -euo pipefail to all scripts Low High
2 Quote all variable expansions Low Medium
3 Add input validation for critical vars Medium Medium

Example Secure Script Template

#!/bin/bash
# MCP Server Wrapper for: service-name
# Generated secure template

set -euo pipefail

# Required variables with validation
: "${API_URL:?API_URL must be set}"
: "${API_KEY:?API_KEY must be set}"

# Optional variables with defaults
TIMEOUT="${TIMEOUT:-30}"
DEBUG="${DEBUG:-false}"

# Input validation
if [[ ! "$API_URL" =~ ^https?:// ]]; then
  echo "ERROR: API_URL must be a valid HTTP/HTTPS URL" >&2
  exit 1
fi

# Execute
exec docker run --rm -i \
  -e API_URL="${API_URL}" \
  -e API_KEY="${API_KEY}" \
  -e TIMEOUT="${TIMEOUT}" \
  -e DEBUG="${DEBUG}" \
  kneldevstack-aimiddleware-service-name