Skip to content

Conversation

@rushilpatel0
Copy link
Contributor

Motivation

Content

Testing

Please check the following before marking your PR as ready for review

  • I have added tests for my changes
  • I have updated the documentation or added new documentation as needed

@rushilpatel0 rushilpatel0 requested review from a team and codegen-team as code owners August 19, 2025 19:36
@codecov
Copy link

codecov bot commented Aug 19, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ All tests successful. No failed tests found.

@rushilpatel0 rushilpatel0 merged commit 6afa33e into develop Aug 19, 2025
18 checks passed
@rushilpatel0 rushilpatel0 deleted the rpatel/fix branch August 19, 2025 19:39
@github-actions
Copy link
Contributor

🎉 This PR is included in version 0.56.13 🎉

The release is available on GitHub release

Your semantic-release bot 📦🚀

@codegen-sh
Copy link
Contributor

codegen-sh bot commented Aug 19, 2025

LGTM ✅ No issues found.

🔍 View my analysis

@codegen-sh
Copy link
Contributor

codegen-sh bot commented Aug 19, 2025

Found 1 critical and 1 important issue. PR is already closed, so I couldn't attach inline comments to the diff. Sharing precise suggestions below for follow-up PR.

  1. Security vulnerability (Critical): session context file is written world-readable by default
  • Code writes ~/.codegen/claude-session.json without restricting permissions. On Unix-like systems with umask 022, this becomes 0644 (readable by other users). It contains session_id and agent_run_id, which may expose sensitive context.

Suggested fix (src/codegen/cli/commands/claude/main.py – secure write with 0o600):

    # Write session context file for downstream hooks and tools (after hook setup)
    try:
        SESSION_FILE.parent.mkdir(exist_ok=True)
        session_payload = {
            "session_id": session_id,
            "agent_run_id": agent_run_id,
            "org_id": resolved_org_id,
            "hook_event": "Startup",
        }
        # Ensure file is created with 0600 permissions
        fd = os.open(SESSION_FILE, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
        with os.fdopen(fd, "w") as f:
            json.dump(session_payload, f, indent=2)
            f.write("\n")
        console.print("📝 Wrote session file to ~/.codegen/claude-session.json", style="dim")
    except Exception as e:
        console.print(f"⚠️  Could not write session file: {e}", style="yellow")
  1. Logic/race condition (Important): single shared filename can cause cross-session interference
  • Multiple concurrent sessions will read/write ~/.codegen/claude-session.json. If environment variables are missing in a hook invocation, a hook from one session may pick up another session’s data.

Low-impact change to mitigate: pass a per-session file path via env and teach hooks to read it for fallback.

a) In src/codegen/cli/commands/claude/main.py, set a per-session file and export it:

    # Write session context file for downstream hooks and tools (after hook setup)
    try:
        SESSION_FILE.parent.mkdir(exist_ok=True)
        session_file = SESSION_FILE.parent / f"claude-session-{session_id}.json"
        os.environ["CODEGEN_CLAUDE_SESSION_FILE"] = str(session_file)
        session_payload = {
            "session_id": session_id,
            "agent_run_id": agent_run_id,
            "org_id": resolved_org_id,
            "hook_event": "Startup",
        }
        fd = os.open(session_file, os.O_WRONLY | os.O_CREAT | os.O_TRUNC, 0o600)
        with os.fdopen(fd, "w") as f:
            json.dump(session_payload, f, indent=2)
            f.write("\n")
        console.print(f"📝 Wrote session file to {session_file}", style="dim")
    except Exception as e:
        console.print(f"⚠️  Could not write session file: {e}", style="yellow")

b) In both hooks (src/codegen/cli/commands/claude/config/claude_session_active_hook.py and .../claude_session_stop_hook.py), prefer CODEGEN_CLAUDE_SESSION_FILE when falling back to a file:

def read_session_file() -> dict:
    """Read session data written by the CLI, if available."""
    env_path = os.environ.get("CODEGEN_CLAUDE_SESSION_FILE")
    session_path = Path(env_path) if env_path else (Path.home() / ".codegen" / "claude-session.json")
    if not session_path.exists():
        return {}
    try:
        with open(session_path) as f:
            return json.load(f)
    except Exception:
        return {}

These changes keep current behavior (hooks still prefer env-based context) while removing cross-session risk when they must fall back to reading a file. The secure write also prevents unintended disclosure of session identifiers.

🔍 View my analysis

@codegen-sh
Copy link
Contributor

codegen-sh bot commented Aug 19, 2025

Additional important issue related to concurrency:

  1. Logic error (Important): ensure_claude_hook() unconditionally deletes the session file
  • In src/codegen/cli/commands/claude/hooks.py lines 31–34, ensure_claude_hook removes ~/.codegen/claude-session.json at startup. When multiple sessions run concurrently, launching a second session will delete the first session’s fallback file mid-run, breaking hooks that rely on file fallback.

Suggested fix: Avoid unlinking the session file in ensure_claude_hook; perform cleanup at session end only (cleanup_claude_hook already removes the file), or move to per-session files as outlined earlier.

        # Create .codegen directory if it doesn't exist
        CODEGEN_DIR.mkdir(exist_ok=True)

        # Do not remove existing session file here to avoid affecting concurrent sessions
        # Cleanup should occur at session end (see cleanup_claude_hook)

This aligns with the per-session file approach and prevents cross-session interference.

🔍 View my analysis

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

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants