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

231 lines
5.2 KiB
Markdown

# 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
```bash
#!/bin/bash
# Script continues even if commands fail
docker build ... # If this fails, script continues
echo "Build complete" # Misleading success message
```
#### Correct Pattern
```bash
#!/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:
```bash
#!/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
```bash
#!/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
```bash
#!/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
```bash
# Dangerous - unquoted
docker run $CONTAINER_NAME
# Safe - quoted
docker run "$CONTAINER_NAME"
```
#### Recommendation
Always quote variable expansions:
```bash
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
```bash
#!/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:
```bash
#!/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
```bash
#!/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
```