Skip to content

fix(hooks): verify tmux socket exists before trusting TMUX env var#329

Open
xiaolai wants to merge 1 commit intorohitg00:mainfrom
xiaolai:fix/nlpm-tmux-socket-validation
Open

fix(hooks): verify tmux socket exists before trusting TMUX env var#329
xiaolai wants to merge 1 commit intorohitg00:mainfrom
xiaolai:fix/nlpm-tmux-socket-validation

Conversation

@xiaolai
Copy link
Copy Markdown

@xiaolai xiaolai commented Apr 22, 2026

Automated audit: This PR was generated by NLPM, a natural language programming linter, running via claude-code-action. Please evaluate the diff on its merits.

Security Finding (Low)

hooks/scripts/block-dev-server.js guards dev-server commands (e.g. npm run dev, vite) by checking whether process.env.TMUX or process.env.STY is set. The intent is to require users to be inside a terminal multiplexer so the dev server won't become an orphaned process.

The issue: TMUX is just an environment variable. Any process — or a user typing export TMUX=fake — can set it without actually being inside tmux, bypassing the guard entirely.

Fix

TMUX, when set by tmux itself, contains the socket path followed by server PID and session ID, comma-separated (e.g. /tmp/tmux-1000/default,23456,0). The socket is a real file on disk. We verify it exists:

// Before
const inTmux = !!process.env.TMUX;

// After
const tmuxVal = process.env.TMUX || "";
const inTmux = tmuxVal !== "" && fs.existsSync(tmuxVal.split(",")[0]);

If the env var is set but no socket file exists at that path, inTmux is false — the guard holds. Legitimate tmux sessions are unaffected.

Files changed:

  • hooks/scripts/block-dev-server.js (+3 lines, -1 line)

Summary by CodeRabbit

Release Notes

  • Chores
    • Improved development server detection logic for enhanced reliability in specific development environments.

block-dev-server.js allowed dev server commands when process.env.TMUX
was set. However, TMUX is just an environment variable — any parent
process can set it without actually running inside tmux, which would
bypass the guard.

TMUX is set by tmux to the socket path (format: socket,pid,session).
We now verify the socket file exists with fs.existsSync() on the
first comma-delimited segment, confirming a real tmux server is
running rather than trusting the variable alone.

Co-Authored-By: Claude Code <noreply@anthropic.com>
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 22, 2026

📝 Walkthrough

Walkthrough

The dev server blocking script now imports Node's fs module and enhances tmux detection by parsing the TMUX environment variable, extracting its first component via string split, and verifying its filesystem existence rather than simply checking the environment variable's presence.

Changes

Cohort / File(s) Summary
Dev Server Blocking Script
hooks/scripts/block-dev-server.js
Updated tmux detection to parse TMUX environment variable by splitting on commas and checking if the extracted path exists on disk using fs.existsSync(), replacing simple environment variable truthy check.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 In tmux we check, with filesystem care,
Splitting those values, ensuring they're there,
The dev server blocks when the path isn't true,
A rabbit's small script keeping things clean and new! 🌿

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main change: verifying tmux socket exists before trusting the TMUX environment variable, which directly addresses the security issue in the PR objectives.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@hooks/scripts/block-dev-server.js`:
- Around line 29-31: The inTmux and inScreen checks are vulnerable to env
spoofing; update the TMUX validation to parse tmuxVal.split(",")[0] into
socketPath and then verify fs.existsSync(socketPath) AND that
fs.statSync(socketPath).isSocket() (catch and treat stat errors as non-tmux),
and disable the inScreen detection by setting inScreen = false (remove relying
on process.env.STY) until a proper Unix-socket validation is implemented; refer
to the tmuxVal, inTmux and inScreen symbols when making these changes.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 2d4fcb14-3e4c-41a7-a0ec-c51e625de006

📥 Commits

Reviewing files that changed from the base of the PR and between 659efb0 and 138c417.

📒 Files selected for processing (1)
  • hooks/scripts/block-dev-server.js

Comment on lines +29 to 31
const tmuxVal = process.env.TMUX || "";
const inTmux = tmuxVal !== "" && fs.existsSync(tmuxVal.split(",")[0]);
const inScreen = !!process.env.STY;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
# Description: Inspect existing project docs/tests for expected tmux/screen support and socket assumptions.
rg -n -C3 '\b(TMUX|STY|screen|tmux|block-dev-server)\b'

Repository: rohitg00/awesome-claude-code-toolkit

Length of output: 32265


🏁 Script executed:

# Look for tests or documentation related to block-dev-server.js
find . -type f \( -name "*.test.*" -o -name "*.spec.*" \) | xargs grep -l "block-dev-server\|TMUX\|STY" 2>/dev/null || echo "No test files found"

# Check for any documentation about multiplexer expectations
find . -type f \( -name "*.md" -o -name "*.txt" -o -name "*.json" \) | xargs grep -l "screen.*socket\|tmux.*socket\|STY" 2>/dev/null || echo "No socket docs found"

Repository: rohitg00/awesome-claude-code-toolkit

Length of output: 120


🏁 Script executed:

# Check for references to STY usage anywhere in the codebase
rg -i '\bSTY\b' --type-list | head -20
rg -i '\bSTY\b' 2>/dev/null || echo "STY not referenced elsewhere"

# Check if there are comments explaining the STY/screen usage in the file
sed -n '20,45p' hooks/scripts/block-dev-server.js

Repository: rohitg00/awesome-claude-code-toolkit

Length of output: 1263


🏁 Script executed:

# Look for socket validation patterns in similar Node.js files
rg 'isSocket|statSync' --type-list | head -5
rg 'isSocket|statSync' 2>/dev/null || echo "No socket validation patterns found"

Repository: rohitg00/awesome-claude-code-toolkit

Length of output: 560


🏁 Script executed:

# Check the full context of block-dev-server.js to understand purpose and any comments
cat -n hooks/scripts/block-dev-server.js

Repository: rohitg00/awesome-claude-code-toolkit

Length of output: 1453


🏁 Script executed:

# Search for any usage of tmux or screen in shell scripts or config
rg 'tmux|screen' hooks/ --type-list 2>/dev/null || rg 'tmux|screen' hooks/ 2>/dev/null | head -20

Repository: rohitg00/awesome-claude-code-toolkit

Length of output: 691


🏁 Script executed:

# Check if there are any tests at all for hooks
find . -path "*/hooks/*test*" -o -path "*/test*hooks*" 2>/dev/null | head -10
ls -la hooks/ 2>/dev/null

Repository: rohitg00/awesome-claude-code-toolkit

Length of output: 340


Harden beyond path existence to prevent environment variable spoofing.

Lines 30–31 are vulnerable:

  • TMUX=/tmp,1,1 passes fs.existsSync() even though /tmp is not a tmux socket; any existing path bypasses the check.
  • STY=fake bypasses the guard entirely with zero validation.

To close both spoofing vectors, validate that paths are actually Unix sockets:

Recommended fix
 const tmuxVal = process.env.TMUX || "";
-const inTmux = tmuxVal !== "" && fs.existsSync(tmuxVal.split(",")[0]);
-const inScreen = !!process.env.STY;
+const isSocket = (socketPath) => {
+  if (!socketPath) return false;
+  try {
+    return fs.statSync(socketPath).isSocket();
+  } catch {
+    return false;
+  }
+};
+
+const inTmux = isSocket(tmuxVal.split(",")[0]);
+const inScreen = false; // screen socket validation not yet implemented

For tmux, the socket validation above is sufficient. For screen, no socket path assumptions are documented in the project, so inScreen is disabled until proper socket validation is added.

📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
const tmuxVal = process.env.TMUX || "";
const inTmux = tmuxVal !== "" && fs.existsSync(tmuxVal.split(",")[0]);
const inScreen = !!process.env.STY;
const tmuxVal = process.env.TMUX || "";
const isSocket = (socketPath) => {
if (!socketPath) return false;
try {
return fs.statSync(socketPath).isSocket();
} catch {
return false;
}
};
const inTmux = isSocket(tmuxVal.split(",")[0]);
const inScreen = false; // screen socket validation not yet implemented
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@hooks/scripts/block-dev-server.js` around lines 29 - 31, The inTmux and
inScreen checks are vulnerable to env spoofing; update the TMUX validation to
parse tmuxVal.split(",")[0] into socketPath and then verify
fs.existsSync(socketPath) AND that fs.statSync(socketPath).isSocket() (catch and
treat stat errors as non-tmux), and disable the inScreen detection by setting
inScreen = false (remove relying on process.env.STY) until a proper Unix-socket
validation is implemented; refer to the tmuxVal, inTmux and inScreen symbols
when making these changes.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant