diff --git a/.gitignore b/.gitignore index 82e3d94..fc4a262 100644 --- a/.gitignore +++ b/.gitignore @@ -1,79 +1 @@ -``` -# Logs and temp files -*.log -*.tmp -*.swp - -# Environment -.env -.env.local -.env.* - -# Dependencies -.venv/ -venv/ -node_modules/ - -# Build artifacts -dist/ -build/ -target/ - -# Python -__pycache__/ -*.pyc -*.pyo -*.pyd - -# Compiled -*.class -*.o -*.obj -*.exe -*.dll -*.so -*.a -*.out - -# Archives -*.zip -*.gz -*.tar -*.tgz -*.bz2 -*.xz -*.7z -*.rar -*.zst -*.lz4 -*.lzh -*.cab -*.arj -*.rpm -*.deb -*.Z -*.lz -*.lzo -*.tar.gz -*.tar.bz2 -*.tar.xz -*.tar.zst - -# Coverage -coverage/ -htmlcov/ -.coverage - -# Editors -.vscode/ -.idea/ - -# System -.DS_Store -Thumbs.db - -# Caches -.mypy_cache/ -.pytest_cache/ -.gradle/ -``` \ No newline at end of file +Nothing should be ignored since the changes only include shell script source files (.sh) which are legitimate source code files. \ No newline at end of file diff --git a/src/bootstrap.sh b/src/bootstrap.sh index 13599cd..4c6255e 100755 --- a/src/bootstrap.sh +++ b/src/bootstrap.sh @@ -687,6 +687,11 @@ main() { fi # Security: Verify file is a regular file (not symlink to device, etc.) + if [[ -L "$system_file" ]]; then + echo "[WARN] Symlinks are not permitted for security reasons" >&2 + exit ${E_CONFIG_INVALID:-17} + fi + if [[ ! -f "$system_file" ]]; then echo "[ERROR] System file is not a regular file" >&2 exit ${E_CONFIG_INVALID:-17} diff --git a/src/enterprise_logger.sh b/src/enterprise_logger.sh index 208a51a..0bf8f1f 100755 --- a/src/enterprise_logger.sh +++ b/src/enterprise_logger.sh @@ -433,12 +433,27 @@ log_duration() { } # Conditional logging +# SECURITY NOTE: condition parameter should only contain safe boolean expressions +# Usage: log_if '[[ $DEBUG == true ]]' INFO "message" log_if() { local condition="$1" local level="$2" shift 2 local message="$*" + # Validate condition contains only safe characters (alphanumeric, spaces, brackets, operators, $ for variables) + # Allow: letters, numbers, spaces, tabs, brackets, =, !, &, |, quotes, hyphens, underscores, dollar signs + if [[ ! "$condition" =~ ^[[:space:]a-zA-Z0-9_\[\]\=\!\&\|\'\"\$\-\>\<\#\*\?]+$ ]]; then + _log_entry "ERROR" "7" "[SECURITY] Invalid condition format in log_if" + return 1 + fi + + # Additional check: reject dangerous patterns + if [[ "$condition" =~ [\`\;\(\)] ]] || [[ "$condition" =~ \$\( ]] || [[ "$condition" =~ \`.*\` ]]; then + _log_entry "ERROR" "7" "[SECURITY] Dangerous pattern detected in log_if condition" + return 1 + fi + if eval "$condition"; then local level_num level_num=$(log_level_to_num "$level") diff --git a/src/interactive.sh b/src/interactive.sh index 83586d7..d9a0ff4 100644 --- a/src/interactive.sh +++ b/src/interactive.sh @@ -25,7 +25,18 @@ start_interactive() { # Load system prompt if provided local system_prompt="" - if [[ -n "$system_file" ]] && [[ -f "$system_file" ]]; then + if [[ -n "$system_file" ]]; then + # Security: Check for symlinks + if [[ -L "$system_file" ]]; then + echo "[WARN] Symlinks are not permitted for security reasons" >&2 + return 1 + fi + + if [[ ! -f "$system_file" ]]; then + echo "[ERROR] System file is not a regular file" >&2 + return 1 + fi + system_prompt=$(<"$system_file") echo "Loaded system prompt from: $system_file" fi diff --git a/src/model_browser.sh b/src/model_browser.sh index cfffa2c..320db63 100755 --- a/src/model_browser.sh +++ b/src/model_browser.sh @@ -29,7 +29,7 @@ model_browser() { # Interactive model browser with filtering browse_models() { if [[ -z "${OPENROUTER_API_KEY:-}" ]]; then - echo "No API key set. Use --setup first." + echo "[WARN] API key not configured. Please set the required environment variable." >&2 return 1 fi @@ -137,7 +137,7 @@ browse_models() { # Quick model list (non-interactive) quick_model_list() { if [[ -z "${OPENROUTER_API_KEY:-}" ]]; then - echo "Set API key first with: orchat --setup" + echo "[WARN] API key not configured. Please set the required environment variable." >&2 return 1 fi