Croc's --classic Mode: Security Implications and Usage Guide

Croc's --classic flag enables a legacy transfer mode that exposes shared secrets in the process list, creating a local attack vector on multi-user Unix systems.

Croc supports two operating modes for file transfers: the default secure mode and the legacy classic mode activated by the --classic flag. Understanding Croc's --classic mode security implications and usage is critical for system administrators and users on shared machines, as the mode determines whether your transfer codes are visible to other local users via ps or protected within environment variables.

What is Classic Mode in Croc?

Classic mode replicates Croc's original pre-v9 behavior where transfer codes are passed directly on the command line. According to the schollz/croc source code in src/cli/cli.go, this mode exists for backward compatibility but trades security for convenience.

The Toggle Mechanism

The --classic flag is defined at lines 132-133 of src/cli/cli.go as a boolean that "toggles between the classic mode (insecure due to local attack vector) and new mode (secure)". When invoked, Croc checks for a hidden marker file named classic_enabled in the user's config directory ($HOME/.config/croc), managed by the getClassicConfigFile helper function (lines 80-86).

Security Implications of Classic Mode

Local Attack Vector via Process List

In classic mode, shared secrets are passed as command-line arguments (e.g., croc send --code <secret> file.txt). On Unix-like systems, any local user can view these arguments using ps or top, exposing the secret to potential eavesdroppers. The source code explicitly warns users about this during the enable/disable prompts (lines 77-84 and 100-107 in src/cli/cli.go).

Automatic Safety Guards

To prevent accidental exposure, Croc implements the shouldExitForUnixSendCode function (lines 15-17 in src/cli/cli.go). This safety guard aborts send operations on non-Windows platforms when the --code flag is used without classic mode enabled and without the CROC_SECRET environment variable set.

How to Enable and Disable Classic Mode

Checking and Toggling the Mode

Running croc --classic checks the classicInsecureMode state. If the marker file exists, Croc prompts to disable classic mode; otherwise, it prompts to enable it.

croc --classic

# Follow the interactive prompt to enable or disable

Using Classic Mode for Transfers

When enabled:


# Send with code visible in process list

croc send --code mysecret123 file.txt

# Receive with code on command line

croc mysecret123

Secure Alternative: Using CROC_SECRET

The recommended approach avoids classic mode entirely by using the CROC_SECRET environment variable, which never appears in the process list.

export CROC_SECRET=mysecret123
croc send file.txt

On the receiver:

export CROC_SECRET=mysecret123
croc

This method satisfies the safety guard in shouldExitForUnixSendCode and keeps secrets out of ps output on Linux and macOS.

Platform-Specific Considerations

On Windows, the process list exposure is less accessible to standard users compared to Unix systems, making classic mode marginally safer. However, the CROC_SECRET environment variable approach remains the cross-platform best practice and works identically on all operating systems.

Summary

  • Classic mode stores its state in $HOME/.config/croc/classic_enabled via the getClassicConfigFile helper in src/cli/cli.go
  • Enabling --classic exposes secrets in command-line arguments visible to ps on Unix systems
  • The shouldExitForUnixSendCode function prevents accidental secret exposure by requiring explicit classic mode or environment variables
  • Secure transfers use CROC_SECRET instead of --code arguments
  • Classic mode persists until explicitly disabled with croc --classic

Frequently Asked Questions

What exactly does the --classic flag do in Croc?

The --classic flag toggles Croc between modern secure mode and legacy classic mode. When enabled, it allows passing transfer codes directly on the command line using --code, storing the enabled state in a hidden classic_enabled file in your config directory.

Why is classic mode considered insecure on Linux and macOS?

Classic mode is insecure because it passes the shared secret as a command-line argument, which any local user can read using ps, top, or /proc filesystem inspection. This creates a local attack vector where malicious users on the same machine can intercept your transfer codes and steal files.

How do I send files securely without using classic mode?

Export the CROC_SECRET environment variable before running Croc. This keeps the secret out of the process list entirely. The sender runs export CROC_SECRET=<code> && croc send file.txt, and the receiver runs export CROC_SECRET=<code> && croc without exposing the code to other users.

Can I use classic mode safely on Windows?

While Windows process lists are less accessible to non-administrative users compared to Unix systems, classic mode still exposes secrets in the command line. For maximum security across all platforms, avoid classic mode and use the CROC_SECRET environment variable method instead.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →