bfs
is a command line program running on multi-user operating systems.
Those other users may be malicious, but bfs
should not allow them to do anything they couldn't already do.
That includes situations where one user (especially root
) is running bfs
on files owned or controlled by another user.
On the other hand, bfs
implicitly trusts the user running it.
Anyone with enough control over the command line of bfs
or any find
-compatible tool can wreak havoc with dangerous actions like -exec
, -delete
, etc.
Caution
The only untrusted input that should ever be passed on the bfs
command line are file paths.
It is always unsafe to allow any other part of the command line to be affected by untrusted input.
Use the -f
flag, or -files0-from
, to ensure that the input is interpreted as a path.
This still has security implications, including:
- Information disclosure: an attacker may learn whether particular files exist by observing
bfs
's output, exit status, or even side channels like execution time. - Denial of service: large directory trees or slow/network storage may cause
bfs
to consume excessive system resources.
Tip
When in doubt, do not pass any untrusted input to bfs
.
The -exec
family of actions execute commands, passing the matched paths as arguments.
File names that begin with a dash may be misinterpreted as options, so bfs
adds a leading ./
in some instances:
user@host$ bfs -execdir echo {} \;
./-rf
This might save you from accidentally running rm -rf
(for example) when you didn't mean to.
This mitigation applies to -execdir
, but not -exec
, because the full path typically does not begin with a dash.
But it is possible, so be careful:
user@host$ bfs -f -rf -exec echo {} \;
-rf
Like many programs that interface with the file system, bfs
can be affected by race conditions—in particular, "time-of-check to time-of-use" (TOCTTOU) issues.
For example,
user@host$ bfs / -user user -exec dangerous_command {} \;
is not guaranteed to only run dangerous_command
on files you own, because another user may run
evil@host$ mv /path/to/file /path/to/exile
evil@host$ mv ~/malicious /path/to/file
in between checking -user user
and executing the command.
Warning
Be careful when running bfs
on directories that other users have write access to, because they can modify the directory tree while bfs
is running, leading to unpredictable results and possible TOCTTOU issues.
In general, printing arbitrary data to a terminal may have security implications.
On many platforms, file paths may be completely arbitrary data (except for NUL (\0
) bytes).
Therefore, when bfs
is writing output to a terminal, it will escape non-printable characters:
user@host$ touch $'\e[1mBOLD\e[0m' user@host$ bfs . ./$'\e[1mBOLD\e[0m'
However, this is fragile as it only applies when outputting directly to a terminal:
user@host$ bfs | grep BOLD BOLD
Every correctness issue in bfs
is a potential security issue, because acting on the wrong path may do arbitrarily bad things.
For example:
root@host# bfs /etc -name passwd -exec cat {} \;
should print /etc/passwd
but not /etc/shadow
.
bfs
tries to ensure correct behavior through careful programming practice, an extensive testsuite, and static analysis.
bfs
is written in C, which is a memory unsafe language.
Bugs that lead to memory corruption are likely to be exploitable due to the nature of C.
We use sanitizers to try to detect these bugs.
Fuzzing has also been applied in the past, and deploying continuous fuzzing is a work in progress.
bfs
comes with no warranty, and is maintained by me and other volunteers in our spare time.
In that sense, there are no supported versions.
However, as long as I maintain bfs
I will attempt to address any security issues swiftly.
In general, security fixes will be part of the latest release, though for significant issues I may backport fixes to older release series.
If you think you have found a sensitive security issue in bfs
, you can report it privately.
Or you can report it publicly; I won't judge you.