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_enabledvia thegetClassicConfigFilehelper insrc/cli/cli.go - Enabling
--classicexposes secrets in command-line arguments visible topson Unix systems - The
shouldExitForUnixSendCodefunction prevents accidental secret exposure by requiring explicit classic mode or environment variables - Secure transfers use
CROC_SECRETinstead of--codearguments - 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:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →