An issue was discovered in Croc through 9.6.5. A sender may send dangerous new files to a receiver, such as executable content or a .ssh/authorized_keys file.
If more than one file is transferred via Croc then, before the transfer starts, the receiver only sees a summary line about the files about to be received, like:

    Accept 2 files (159 B)? (Y/n)

Only after confirming this dialog the full file reception list will be printed, like:

    Receiving (<-[ip]:[port])
    file1 100% |████████████████████| (140/140 B, 610 B/s) 1/2
    file2 100% |████████████████████| ( 0/ 1 B) 2/2

The Croc protocol allows the sender to specify arbitrary paths to be transferred. Via social engineering an attacker could attempt to transfer one or more malicious files in a larger file list, that otherwise looks unsuspicious.

There is a file overwrite check in Croc that prevents existing files from being overwritten without user consent (at least by default, there's the `--overwrite` switch to disable the prompt). For not yet existing files there are no security boundaries though. So if e.g. `$HOME/.ssh/authorized_keys` is not existing yet on the receiver side, then the sender can transfer this, maybe unnoticed by the receiver. Even if the receiver notices it after the fact, it might be too late, and the attacker already had the chance to compromise the receiver's system.

Two relevant pieces of information might be missing for an attacker in this scenario: the receiver's home directory location and its current working directory. Guessing or determining the receiver's home directory path via social engineering might be well within reach though.imply implying that the CWD is the home directory might otherwise be a good guess. Also relative paths like `../.ssh/authorized_keys` can be transferred. An attacker has to be careful about this, though, because if the path reaches above the home directory, then "permission denied" errors will become visible on the receiver end, which are more likely to raise alarm.

Fixing this kind of attack scenario is difficult, when trying to parse incoming file paths and to detect dangerous situations in userspace. Especially since there is also the possibility of symlinks and Croc even explicitly supports the creation of symlinks in its protocol. In other file transfer tools like [Warpinator](https://www.openwall.com/lists/oss-security/2023/04/26/1) the developers ended up using isolation techniques to lock the receiver process side in a specific download directory.

Using mount namespaces (ideally an existing tool for creating a namespace jail) or Linux features like Landlock is probably the best solution for this problem. Since Croc is cross platform, implementing isolation can become a large effort though, since there are no shared APIs available for this.
Possible (Concealed) Creation of Files in Dangerous Path Locations
This is a GitHub Issue
repo:croc
owner:schollz
Title : Possible (Concealed) Creation of Files in Dangerous Path Locations
Issue date:

--- start body ---
If more than one file is transferred via Croc then, before the transfer starts, the receiver only sees a summary line about the files about to be received, like:

    Accept 2 files (159 B)? (Y/n)

Only after confirming this dialog the full file reception list will be printed, like:

    Receiving (<-[ip]:[port])
    file1 100% |████████████████████| (140/140 B, 610 B/s) 1/2
    file2 100% |████████████████████| ( 0/ 1 B) 2/2

The Croc protocol allows the sender to specify arbitrary paths to be transferred. Via social engineering an attacker could attempt to transfer one or more malicious files in a larger file list, that otherwise looks unsuspicious.

There is a file overwrite check in Croc that prevents existing files from being overwritten without user consent (at least by default, there's the `--overwrite` switch to disable the prompt). For not yet existing files there are no security boundaries though. So if e.g. `$HOME/.ssh/authorized_keys` is not existing yet on the receiver side, then the sender can transfer this, maybe unnoticed by the receiver. Even if the receiver notices it after the fact, it might be too late, and the attacker already had the chance to compromise the receiver's system.

Two relevant pieces of information might be missing for an attacker in this scenario: the receiver's home directory location and its current working directory. Guessing or determining the receiver's home directory path via social engineering might be well within reach though.imply implying that the CWD is the home directory might otherwise be a good guess. Also relative paths like `../.ssh/authorized_keys` can be transferred. An attacker has to be careful about this, though, because if the path reaches above the home directory, then "permission denied" errors will become visible on the receiver end, which are more likely to raise alarm.

Fixing this kind of attack scenario is difficult, when trying to parse incoming file paths and to detect dangerous situations in userspace. Especially since there is also the possibility of symlinks and Croc even explicitly supports the creation of symlinks in its protocol. In other file transfer tools like [Warpinator](https://www.openwall.com/lists/oss-security/2023/04/26/1) the developers ended up using isolation techniques to lock the receiver process side in a specific download directory.

Using mount namespaces (ideally an existing tool for creating a namespace jail) or Linux features like Landlock is probably the best solution for this problem. Since Croc is cross platform, implementing isolation can become a large effort though, since there are no shared APIs available for this.
--- end body ---
