Skip to content

[LOW] Race Condition in Temporary File Handling (Predictable Naming) #72

@tembo

Description

@tembo

Summary

The editReply function creates temporary files with predictable names based on Date.now(), potentially exposing the application to symlink attacks on multi-user systems.

Severity: LOW

Affected Files

  • src/commands/reply.ts (Lines 144-151, 194-199)

Vulnerable Code

const tmpFile = join(tmpdir(), `ship-reply-${Date.now()}.txt`);
const header = `# Edit your reply below...`;
writeFileSync(tmpFile, header + currentReply, 'utf8');
// ... editor interaction ...
try {
  unlinkSync(tmpFile);
} catch {
  // Ignore cleanup errors
}

Description

The temporary file is created in the system temp directory with a predictable name based on Date.now(). On Unix-like systems with multiple users, another process could:

  1. Predict the filename that will be used
  2. Create a symlink at that path before the file is written
  3. Cause the editor to write to an arbitrary file

Risk Assessment

This is a low severity issue because:

  • Requires local access to the system
  • Requires precise timing
  • The content written is relatively benign (reply text)

Recommended Fix

Use fs.mkdtempSync() to create a secure temporary directory:

import { mkdtempSync, rmdirSync } from 'fs';
import { join } from 'path';
import { tmpdir } from 'os';

const tmpDir = mkdtempSync(join(tmpdir(), 'ship-reply-'));
const tmpFile = join(tmpDir, 'reply.txt');

// ... use tmpFile ...

// Cleanup
try {
  unlinkSync(tmpFile);
  rmdirSync(tmpDir);
} catch {
  // Ignore cleanup errors
}

Or use the tmp npm package for secure temporary file handling.

References

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions