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

> Explore Croc's classic mode security risks discover how the --classic flag exposes shared secrets on Unix systems understand usage implications and secure your transfers.

- Repository: [Zack/croc](https://github.com/schollz/croc)
- Tags: deep-dive
- Published: 2026-07-26

---

**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`](https://github.com/schollz/croc/blob/main/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`](https://github.com/schollz/croc/blob/main/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`](https://github.com/schollz/croc/blob/main/src/cli/cli.go)).

### Automatic Safety Guards

To prevent accidental exposure, Croc implements the `shouldExitForUnixSendCode` function (lines 15-17 in [`src/cli/cli.go`](https://github.com/schollz/croc/blob/main/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.

```bash
croc --classic

# Follow the interactive prompt to enable or disable

```

### Using Classic Mode for Transfers

When enabled:

```bash

# 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.

```bash
export CROC_SECRET=mysecret123
croc send file.txt

```

On the receiver:

```bash
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`](https://github.com/schollz/croc/blob/main/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.