# Shell Script Security Checklist

This checklist should be used for all new shell scripts and when modifying existing ones.

## Pre-Development Security Checklist

### Script Header Requirements

- [ ] Includes comprehensive header with author, version, and security notes
- [ ] Documents all parameters and their validation requirements
- [ ] Specifies required permissions and security considerations
- [ ] Includes usage examples with security implications

### Initial Security Setup

- [ ] Uses `set -euo pipefail` for strict error handling
- [ ] Defines readonly constants for sensitive paths and configurations
- [ ] Implements cleanup function with proper trap handling
- [ ] Validates all required dependencies and tools

## Input Validation and Sanitization

### Command Line Arguments

- [ ] Validates all positional parameters
- [ ] Checks parameter count and types
- [ ] Sanitizes file paths to prevent directory traversal
- [ ] Validates numeric inputs for bounds and format
- [ ] Rejects dangerous characters in string inputs

### Environment Variables

- [ ] Validates all used environment variables
- [ ] Provides secure defaults for missing variables
- [ ] Sanitizes environment-derived paths and commands
- [ ] Documents required environment setup

### File and Directory Operations

- [ ] Verifies file existence before operations
- [ ] Checks file permissions and ownership
- [ ] Validates file paths for traversal attempts
- [ ] Uses absolute paths where possible
- [ ] Implements proper temporary file handling

## Variable Usage and Quoting

### Variable Declaration

- [ ] Uses `readonly` for constants
- [ ] Uses `local` for function variables
- [ ] Initializes all variables before use
- [ ] Uses descriptive variable names

### Variable Expansion

- [ ] **CRITICAL:** All variables quoted in command contexts: `"$VARIABLE"`
- [ ] Array expansions properly quoted: `"${ARRAY[@]}"`
- [ ] Parameter expansions use braces: `"${VAR:-default}"`
- [ ] Command substitutions properly quoted: `RESULT="$(command)"`

### Dangerous Patterns to Avoid

- [ ] **NEVER:** Unquoted variables in commands: `command $VAR`
- [ ] **NEVER:** Unquoted variables in file operations: `rm $FILE`
- [ ] **NEVER:** Unquoted variables in loops: `for item in $LIST`
- [ ] **NEVER:** Unquoted variables in conditions: `if [ $VAR = "value" ]`

## Command Execution Security

### External Commands

- [ ] Validates command existence before execution
- [ ] Uses full paths for critical system commands
- [ ] Escapes or validates all command arguments
- [ ] Handles command failures appropriately

### Dangerous Command Patterns

- [ ] **AVOID:** `eval` statements (if used, sanitize inputs extensively)
- [ ] **AVOID:** `source` or `.` with user-controlled paths
- [ ] **AVOID:** `curl | bash` or `wget | sh` patterns
- [ ] **AVOID:** Uncontrolled `find -exec` operations

### Privilege Escalation

- [ ] Minimizes `sudo` usage to specific commands
- [ ] Uses service-specific users instead of root where possible
- [ ] Validates commands before privilege escalation
- [ ] Logs privilege escalation activities

## Network and Remote Operations

### Download Security

- [ ] **REQUIRED:** Download to temporary location first
- [ ] **RECOMMENDED:** Verify checksums or signatures
- [ ] **REQUIRED:** Validate content before execution
- [ ] Use HTTPS instead of HTTP where possible
- [ ] Implement timeout and retry logic

### API and Service Interactions

- [ ] Validates API responses before processing
- [ ] Uses authentication tokens securely
- [ ] Implements proper error handling for network failures
- [ ] Logs security-relevant activities

## Database and File System Security

### Database Operations

- [ ] Uses parameterized queries or proper escaping
- [ ] Validates database paths and names
- [ ] Implements backup and recovery procedures
- [ ] Handles database locks and corruption gracefully

### File System Security

- [ ] Sets appropriate file permissions (644 for files, 755 for directories)
- [ ] Validates ownership before operations
- [ ] Implements secure temporary file creation
- [ ] Cleans up temporary files in all exit scenarios

## Service and Container Management

### Service Operations

- [ ] Validates service state before operations
- [ ] Implements proper start/stop sequences
- [ ] Handles service failures gracefully
- [ ] Logs service management activities

### Container Security

- [ ] Validates container names and IDs
- [ ] Uses specific image tags instead of 'latest'
- [ ] Implements proper volume and network security
- [ ] Validates container health before operations

## Error Handling and Logging

### Error Handling Requirements

- [ ] Implements comprehensive error handling for all operations
- [ ] Uses appropriate exit codes (0 for success, 1-255 for various errors)
- [ ] Provides meaningful error messages
- [ ] Implements cleanup on error conditions

### Logging Security

- [ ] Logs security-relevant events
- [ ] Avoids logging sensitive information (passwords, tokens)
- [ ] Implements log rotation and retention policies
- [ ] Uses appropriate log levels (INFO, WARN, ERROR)

## Testing and Validation

### Security Testing

- [ ] **REQUIRED:** Run `bash -n script.sh` for syntax validation
- [ ] **RECOMMENDED:** Use ShellCheck for security analysis
- [ ] Test with various input combinations including edge cases
- [ ] Test error conditions and recovery procedures

### Manual Security Review

- [ ] Review all variable usage for proper quoting
- [ ] Verify all file operations use absolute paths
- [ ] Check for potential race conditions
- [ ] Review privilege requirements and usage

## Documentation Requirements

### Security Documentation

- [ ] Document all security assumptions
- [ ] List required permissions and privileges
- [ ] Document potential security risks
- [ ] Provide secure usage examples

### Operational Security

- [ ] Document deployment security requirements
- [ ] Specify required environment security
- [ ] Document integration security considerations
- [ ] Provide incident response procedures

## Code Review Checklist

### Pre-Commit Review

- [ ] All variables properly quoted
- [ ] No unvalidated user inputs
- [ ] Appropriate error handling implemented
- [ ] Security documentation updated

### Peer Review Requirements

- [ ] Security-critical changes reviewed by security-aware developer
- [ ] Privilege usage justified and documented
- [ ] External integrations reviewed for security implications
- [ ] Testing coverage includes security scenarios

## Deployment Security

### Production Deployment

- [ ] Environment variables secured and validated
- [ ] File permissions set appropriately
- [ ] Service accounts configured with minimal privileges
- [ ] Logging and monitoring configured

### Security Monitoring

- [ ] Failed authentication attempts logged
- [ ] Privilege escalation attempts logged
- [ ] Unusual file access patterns monitored
- [ ] Network connectivity anomalies tracked

## Maintenance and Updates

### Regular Security Maintenance

- [ ] Review and update security dependencies
- [ ] Update security documentation
- [ ] Review and rotate secrets and tokens
- [ ] Update security testing procedures

### Security Incident Response

- [ ] Document security incident procedures
- [ ] Implement security rollback procedures
- [ ] Define security escalation paths
- [ ] Regular security drills and testing

---

## Common Security Anti-Patterns

### ❌ DO NOT DO THIS

```bash
# Unquoted variable in command
docker pull $IMAGE

# Unquoted variable in condition
if [ $STATUS = "active" ]; then

# Unquoted variable in loop
for file in $FILES; do

# Direct remote execution
curl -s https://example.com/script.sh | bash

# Excessive permissions
chmod 777 /path/to/file

# Unvalidated user input
rm -rf $USER_PROVIDED_PATH
```

### ✅ DO THIS INSTEAD

```bash
# Quoted variable in command
docker pull "$IMAGE"

# Quoted variable in condition
if [[ "$STATUS" = "active" ]]; then

# Quoted variable in loop (or use array)
while IFS= read -r file; do
    # process file
done <<< "$FILES"

# Secure remote execution
TEMP_SCRIPT=$(mktemp)
if curl -s https://example.com/script.sh -o "$TEMP_SCRIPT"; then
    # Optionally verify checksum
    bash "$TEMP_SCRIPT"
    rm -f "$TEMP_SCRIPT"
fi

# Appropriate permissions
chmod 644 /path/to/file  # or 755 for executables

# Validated user input
if [[ "$USER_PROVIDED_PATH" =~ ^[a-zA-Z0-9/_.-]+$ ]] && [[ -e "$USER_PROVIDED_PATH" ]]; then
    rm -rf "$USER_PROVIDED_PATH"
else
    echo "Invalid path provided"
    exit 1
fi
```

---

**Remember:** Security is not a feature to be added later—it must be built in from the beginning. Use this checklist for every script, every time.
