fix: path traversal in install.sh, error logging in hooks

- Validate language names in install.sh to prevent path traversal via
  malicious args like ../../etc (only allow [a-zA-Z0-9_-])
- Replace silent catch in check-console-log.js with stderr logging so
  hook failures are visible to the user for debugging
- Escape backticks in session-end.js user messages to prevent markdown
  structure corruption in session files
This commit is contained in:
Affaan Mustafa
2026-02-12 14:14:21 -08:00
parent f3a4b33d41
commit 6e5b45ed28
3 changed files with 14 additions and 4 deletions

View File

@@ -69,6 +69,11 @@ if [[ "$TARGET" == "claude" ]]; then
# Install each requested language # Install each requested language
for lang in "$@"; do for lang in "$@"; do
# Validate language name to prevent path traversal
if [[ ! "$lang" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "Error: invalid language name '$lang'. Only alphanumeric, dash, and underscore allowed." >&2
continue
fi
lang_dir="$RULES_DIR/$lang" lang_dir="$RULES_DIR/$lang"
if [[ ! -d "$lang_dir" ]]; then if [[ ! -d "$lang_dir" ]]; then
echo "Warning: rules/$lang/ does not exist, skipping." >&2 echo "Warning: rules/$lang/ does not exist, skipping." >&2
@@ -101,6 +106,11 @@ if [[ "$TARGET" == "cursor" ]]; then
# Install language-specific rules # Install language-specific rules
for lang in "$@"; do for lang in "$@"; do
# Validate language name to prevent path traversal
if [[ ! "$lang" =~ ^[a-zA-Z0-9_-]+$ ]]; then
echo "Error: invalid language name '$lang'. Only alphanumeric, dash, and underscore allowed." >&2
continue
fi
if [[ -d "$CURSOR_SRC/rules" ]]; then if [[ -d "$CURSOR_SRC/rules" ]]; then
found=false found=false
for f in "$CURSOR_SRC/rules"/${lang}-*.md; do for f in "$CURSOR_SRC/rules"/${lang}-*.md; do

View File

@@ -59,8 +59,8 @@ process.stdin.on('end', () => {
if (hasConsole) { if (hasConsole) {
log('[Hook] Remove console.log statements before committing'); log('[Hook] Remove console.log statements before committing');
} }
} catch { } catch (err) {
// Silently ignore errors (git might not be available, etc.) log(`[Hook] check-console-log error: ${err.message}`);
} }
// Always output the original data // Always output the original data

View File

@@ -157,10 +157,10 @@ ${summarySection}
function buildSummarySection(summary) { function buildSummarySection(summary) {
let section = '## Session Summary\n\n'; let section = '## Session Summary\n\n';
// Tasks (from user messages) // Tasks (from user messages — escape backticks to prevent markdown breaks)
section += '### Tasks\n'; section += '### Tasks\n';
for (const msg of summary.userMessages) { for (const msg of summary.userMessages) {
section += `- ${msg}\n`; section += `- ${msg.replace(/`/g, '\\`')}\n`;
} }
section += '\n'; section += '\n';