mirror of
https://github.com/Ark0N/Codeman.git
synced 2026-10-07 07:59:42 +02:00
fix(security): push-endpoint SSRF guard + tmux name validation; document tail-file roots
- M7 (SSRF): add isSafePushEndpoint (https-only; reject internal/loopback/link-local/metadata IPs incl. IPv4-mapped); enforce in PushSubscribeSchema and re-check before webpush.sendNotification. + unit test. - M1 (command injection): validate tmux session names with isValidMuxName in sessionExists, killSession, and reconcileSessions before they reach a shell call site. - M5: keep the intentional /var/log + ~/logs log-tail roots (a tested feature) and document the wider read scope in docs/security-architecture.md section 5 instead of dropping it. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
+18
-7
@@ -920,6 +920,7 @@ export class TmuxManager extends EventEmitter implements TerminalMultiplexer {
|
||||
|
||||
private sessionExists(muxName: string): boolean {
|
||||
if (IS_TEST_MODE) return false;
|
||||
if (!isValidMuxName(muxName)) return false;
|
||||
|
||||
try {
|
||||
execSync(`${this.tmux()} has-session -t "${muxName}" 2>/dev/null`, {
|
||||
@@ -1060,13 +1061,15 @@ export class TmuxManager extends EventEmitter implements TerminalMultiplexer {
|
||||
}
|
||||
}
|
||||
|
||||
// Strategy 3: Kill tmux session by name
|
||||
try {
|
||||
execSync(`${this.tmux()} kill-session -t "${session.muxName}" 2>/dev/null`, {
|
||||
timeout: EXEC_TIMEOUT_MS,
|
||||
});
|
||||
} catch {
|
||||
// Session may already be dead
|
||||
// Strategy 3: Kill tmux session by name (guard the name before it reaches the shell)
|
||||
if (isValidMuxName(session.muxName)) {
|
||||
try {
|
||||
execSync(`${this.tmux()} kill-session -t "${session.muxName}" 2>/dev/null`, {
|
||||
timeout: EXEC_TIMEOUT_MS,
|
||||
});
|
||||
} catch {
|
||||
// Session may already be dead
|
||||
}
|
||||
}
|
||||
|
||||
// Strategy 4: Direct kill by PID as final fallback
|
||||
@@ -1166,6 +1169,14 @@ export class TmuxManager extends EventEmitter implements TerminalMultiplexer {
|
||||
|
||||
for (const [sessionName, pid] of active) {
|
||||
if (!sessionName.startsWith('codeman-') && !sessionName.startsWith('claudeman-')) continue;
|
||||
// Only admit names that pass the safe-name pattern. A foreign process on the
|
||||
// shared `tmux -L codeman` socket could create a `codeman-…` session whose name
|
||||
// contains shell metacharacters; rejecting it here keeps it out of this.sessions
|
||||
// and away from the name-interpolating tmux call sites (M1).
|
||||
if (!isValidMuxName(sessionName)) {
|
||||
console.warn(`[TmuxManager] Skipping discovered tmux session with unsafe name: ${sessionName}`);
|
||||
continue;
|
||||
}
|
||||
if (knownMuxNames.has(sessionName)) continue;
|
||||
|
||||
const fragment = sessionName.replace(/^(?:codeman|claudeman)-/, '');
|
||||
|
||||
Reference in New Issue
Block a user