Problem
I just realized that cargo publish has been silently adding untracked files to my published crates (without needing to pass --allow-dirty) and that's apparently because it only detects untracked files if it's run from the root of the repo.
This seems like a pretty dangerous foot gun / security risk :/
I only realised this when I saw that the latest jni releases are over 3M compressed (~19M uncompressed) because several perf.data files (from previous runs of perf record) were added to the published archive, as well as a couple of docs that I had locally.
I feel luckily in this case that I didn't accidentally add more sensitive data.
In the case of the jni-rs repo it has a crates/ directory and I have been running cargo publish -p jni from the crates/jni directory instead of from the root of the repo.
Investigating this afterwards, wondering why there was no error about untracked files, I've seen that if I would have run the same command from the top of the repo instead (I initially tested with --dry-run) then cargo publish will then give an error about those untracked files - but if run from cargo/jni it will happily add untracked files with no warning or error.
I've then seen that cargo package --list exhibits the same behaviour, and I assume cargo publish builds on `cargo package.
Steps
- Fetch a repo with multiple crates and add some sensitive / untracked file:
git clone https://github.com/jni-rs/jni-rs
echo "secret" > jni-rs/crates/jni/secret
- Confirm
cargo package --list detects the file from the root of the repo
cd jni-rs/
cargo package -p jni --list
output:
error: 1 files in the working directory contain changes that were not yet committed into git:
crates/jni/secret
to proceed despite this and include the uncommitted changes, pass the `--allow-dirty` flag
- Then repeat from the crate subdirectory:
cd crates/jni
cargo package -p jni --list|grep secret
output:
Note in this case there is no error, even though we didn't need to pass --allow-dirty
Possible Solution(s)
It's normally expected that cargo commands can be run from any directory within a workspace and behave consistently, and similarly commands that need to interact with Git would normally be expected to look for a .git directory in parent directories.
In this case I think I'd expect cargo package and cargo publish to at least traverse up to the top of the cargo workspace in order to find a .git directory so that it can detect untracked files consistently, no matter what subdirectory it was initially run from.
Notes
No response
Version
cargo 1.93.1 (083ac5135 2025-12-15)
release: 1.93.1
commit-hash: 083ac5135f967fd9dc906ab057a2315861c7a80d
commit-date: 2025-12-15
host: x86_64-unknown-linux-gnu
libgit2: 1.9.1 (sys:0.20.2 vendored)
libcurl: 8.15.0-DEV (sys:0.4.83+curl-8.15.0 vendored ssl:OpenSSL/3.5.4)
ssl: OpenSSL 3.5.4 30 Sep 2025
os: Arch Linux Rolling Release [64-bit]
Problem
I just realized that
cargo publishhas been silently adding untracked files to my published crates (without needing to pass--allow-dirty) and that's apparently because it only detects untracked files if it's run from the root of the repo.This seems like a pretty dangerous foot gun / security risk :/
I only realised this when I saw that the latest
jnireleases are over 3M compressed (~19M uncompressed) because severalperf.datafiles (from previous runs ofperf record) were added to the published archive, as well as a couple of docs that I had locally.I feel luckily in this case that I didn't accidentally add more sensitive data.
In the case of the
jni-rsrepo it has acrates/directory and I have been runningcargo publish -p jnifrom thecrates/jnidirectory instead of from the root of the repo.Investigating this afterwards, wondering why there was no error about untracked files, I've seen that if I would have run the same command from the top of the repo instead (I initially tested with
--dry-run) thencargo publishwill then give an error about those untracked files - but if run fromcargo/jniit will happily add untracked files with no warning or error.I've then seen that
cargo package --listexhibits the same behaviour, and I assumecargo publishbuilds on `cargo package.Steps
cargo package --listdetects the file from the root of the repocd jni-rs/ cargo package -p jni --listoutput:
output:
Note in this case there is no error, even though we didn't need to pass
--allow-dirtyPossible Solution(s)
It's normally expected that
cargocommands can be run from any directory within a workspace and behave consistently, and similarly commands that need to interact with Git would normally be expected to look for a.gitdirectory in parent directories.In this case I think I'd expect
cargo packageandcargo publishto at least traverse up to the top of the cargo workspace in order to find a.gitdirectory so that it can detect untracked files consistently, no matter what subdirectory it was initially run from.Notes
No response
Version