Security checks
Reporting a vulnerability, rather than running the checks? See SECURITY.md, which also states what datui does and does not defend against.
Datui runs two automated security checks alongside the usual format and clippy
gates. Both are in the Security workflow, and both can be run locally.
Run them locally
Install the tools once:
cargo install cargo-deny --locked
uv tool install zizmor # or: pipx install zizmor
Then:
./scripts/code/check_security.sh
What runs
cargo-deny checks Cargo.lock against the RustSec advisory
database, plus licenses, banned and duplicate crates, and the
registries dependencies come from. It runs against the root workspace and
against crates/datui-pyo3 and fuzz, both of which are excluded from the
workspace and would otherwise never be audited. Configuration is in deny.toml
at the repository root.
Nothing audits the Python dependencies in scripts/. They are development
tooling and never reach a datui user, but an advisory in them still reaches a
contributor’s machine, so a version floor with the advisory ids written beside
it is the current answer.
zizmor analyzes the GitHub Actions workflow files for the patterns that let
a pull request steal a secret or poison a build: unpinned actions, over-broad
token permissions, expressions interpolated straight into shell, and cache
poisoning. It fails the build on a high-severity finding and reports everything
else to the Security tab. Suppressions live in zizmor.yml, and each one has to
say what the risk is and what would clear it.
A third check, OpenSSF Scorecard, runs on a schedule in its own workflow. It scores the repository’s supply-chain posture and writes each check to the Security tab with a specific remediation. It never fails a build.
When cargo-deny fails
Most advisory failures are cleared by updating the lockfile:
cargo update
cargo deny check advisories
If an advisory cannot be cleared, because the fix is in a version some other
dependency will not accept, add it to the ignore list in deny.toml with two
things written down: why it is acceptable today, and the event that should clear
it. Both are required for an exception.
The current entries are all of that shape. The two quick-xml denial-of-service
advisories are the ones worth watching. They used to be reachable whenever datui
opened an .xlsx file, which is untrusted data; calamine 0.36 moved to
quick-xml 0.41 and closed that path. What is left is the copy object_store
uses to parse S3 and GCS responses, which polars pins, so reaching it needs an
object-store endpoint the user chose that answers with hostile XML.
Adding a new action to a workflow
Pin it to a full commit SHA, with the version tag in a trailing comment:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0
Tags can be moved; a commit SHA identifies the reviewed version. Dependabot proposes updates to pinned actions.
Resolve the SHA for a tag with:
gh api repos/actions/checkout/tags --jq '.[] | select(.name == "v5.1.0") | .commit.sha'