Back to skill

Security audit

rust-dev

Security checks for vulnerabilities and agentic risk

Overview

This Rust guide needs review because one example exposes API tokens and some performance advice weakens system security.

Review before using this skill to make changes. Remove or redact the token-printing example, retain host security protections, and explicitly scope any profiling-policy change. Preview optional cache setup and consider its daemon, cleanup, and remote-sharing effects. Material scanner gaps were investigated, but downloaded tools remain outside this artifact review.

Vulnerability Patterns
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
  • Agent Memory PoisoningWrites attacker-controlled rules into memory that affect later sessions
  • Remote Payload Retrieval and ExecutionFetches external code whose behavior can change after review
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
Findings (22)

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · CHANGELOG.md (reported line 207)May include surrounding context.

md
### Deprecated

- references/crate-shortlist.md: `serde_yaml` and `bincode` were listed as plain "other formats" with no caveat. `serde_yaml` is archived at `0.9.34+deprecated` with no official successor; `bincode` 3.0.0 is a tombstone release whose entire `src/lib.rs` is `compile_error!("https://xkcd.com/2347/")`, so `bincode = "3"` fails to compile rather than failing at runtime - 2.0.1 is the last usable version.

### Security

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
91% confidence
Finding

The CLI example broadly fits a Rust crate guide, but its credential handling introduces undeclared security-sensitive behavior. Args derives Debug, and println!("{args:?}") prints the token when supplied through either the environment or --token. clap's hide_env_values setting affects help output, not this Debug output. The code does not transmit the token over a network.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
90% confidence
Finding

Although development-environment setup can support starting a Rust project, this chunk introduces persistent system changes and a compiler-cache daemon that are not disclosed by the language-and-crate guidance description. These capabilities go beyond incidental implementation details. The check and diagnostic commands are related verification steps, not separate mismatches.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

High
Category
MCP Tool Poisoning
Confidence
87% confidence
Finding

The supplied code performs a network request rather than providing the described Rust guidance. No supporting role for this remote fetch is established by the description or code. The destination is unspecified, and the snippet does not demonstrate exfiltration or other additional behavior.

Content

No source excerpt is available for this finding.

Chaining Abuse

High
Category
Tool Misuse
Confidence
70% confidence
Finding

Tool calls are chained to bypass individual safety checks or escalate capabilities beyond what any single tool call would allow.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

bash
# 1. Install the toolchain (rustup is the toolchain manager)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 2. Confirm components (rustfmt and clippy ship with stable, rust-src enables IDE features)
rustup component add rustfmt clippy rust-src

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 196)May include surrounding context.

md
- A `String` is not indexable. `s[0]` does not compile - see `references/ownership-and-types.md` for what to reach for instead.

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 325)May include surrounding context.

md
ct `rustc` never shares artifacts between them. Bump the pin deliberately (see `references/dev-environment.md`).

Incomplete referenced artifact analysis

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

Scanner excerpt · SKILL.md (reported line 374)May include surrounding context.

md
ature flags, build scripts, and what `rust-version` actually controls. That is `references/project-shape.md`.

Credential Access

High
Category
Privilege Escalation
Confidence
90% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/dev-environment.md (reported line 71)May include surrounding context.

md
nfiltered LIST of the prefix, which is a real cost on a large bucket. Since 0.15.0 `kache sync` exits non-zero if any transfer fails; pass `--allow-partial` when best-effort really is what you want. |
| An auto-started daemon does **not** inherit your shell environment | `KACHE_S3_*` credentials exported from your shell profile leave the launchd/systemd daemon with no credentials at all. Put the remote in the watched `[cache.remote]` config block, use an AWS profile (`cache.remote.profile`) or `~/.aws/credentials`, or start the daemon yourself from the intended environment with `kache daemon run`. Since 1.1.0 "A selected AWS profile now fails explicitly if it cannot supply credentials", instead of falling through to another identity. |
| Set `endpoint` for any non-AWS object store | Ceph, MinIO, and R2 all need `cache.remote.endpoint` (or `KACHE_S3_ENDPOINT`) set explicitly; omit it only for AWS S3. kache always addresses path-style, so you do not need bucket-subdomain DNS to work. |
|

Anti-Refusal Statement

High
Category
Anti-Refusal
Confidence
80% confidence
Finding

Skill instructs the agent to omit warnings, disclaimers, or ethical commentary. Stripping safety caveats hides risk from the user and is a common jailbreak preamble.

Content

Scanner excerpt · references/project-shape.md (reported line 97)May include surrounding context.

md
f a shared dependency, and cargo unifies them; a feature that *removes* or *changes* behavior will break somebody. If you find yourself wanting `no-std` and `std` as mutually exclusive features, that is the shape fighting you.

A binary can be gated too, with `required-features = ["admin"]` on its `[[bin]]`: "If any of the required features are not enabled, the target will be skipped." Skipped silently - `cargo build`, `cargo test`, and `cargo install` without that feature all leave it out with no warning, so a CI job that never enables the feature never compiles the binary either. If you gate one, add a CI step that builds it with the feature on.

**dev-dependencies take part in unification only while they are being built.** The Cargo reference: "Features enabled on dev-dependencies will not be unified when those same dependencies are used as a normal dependency, unless those dev-dependencies are currently being built." Two consequences. `cargo build` and `cargo test` resolve differen

Credential Access

High
Category
Privilege Escalation
Confidence
70% confidence
Finding

Code accesses credential files (SSH keys, AWS credentials, etc.). This could indicate credential theft attempts.

Content

Scanner excerpt · references/releasing.md (reported line 102)May include surrounding context.

md
### Use a PAT for the release PR, not `GITHUB_TOKEN`

A pull request opened by the default `GITHUB_TOKEN` does not get CI the way a human-opened one does - GitHub gates that to prevent recursive workflow runs. The current behavior is that the resulting `pull_request` runs are created in an **approval-required** state rather than never existing at all, so the symptom is a release PR sitting with no green checks until somebody clicks through, which is the same practical failure: you merge a version bump nothing has tested. Give the `release-pr` step a personal access token (or a GitHub App token) instead.

### `[profile.dist]`: pay for optimization only at release

The setup workflow instructs execution of a downloaded shell script without warning about its system-level effects.

Medium
Category
Output Handling
Confidence
90% confidence
Finding

The beginner setup workflow pipes a remotely retrieved installer directly into a shell without explaining that it executes code with the user's permissions and can persistently modify the development environment. The official Rust endpoint and explicit installation purpose reduce suspicion, but do not remove the remote-code trust boundary or the need for informed approval.

Content

No source excerpt is available for this finding.

L347 claims TaskTracker::close() rejects new tasks, but it does not prevent subsequent task spawning or tracking.

Medium
Category
Excessive Agency
Confidence
99% confidence
Finding

TaskTracker::close() does not reject new tasks; it permits wait() to complete once the tracker is empty. Teaching it as an admission barrier can produce shutdown races in applications that continue spawning work, potentially abandoning tasks or hanging shutdown, although the illustrated fixed-worker example does not itself demonstrate exploitation.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
50% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · references/crate-shortlist.md (reported line 227)May include surrounding context.

md
.build()?;

    let repo: Repo = client
        .get("https://api.github.com/repos/rust-lang/rust")
        .send()
        .await?
        .json()

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/dev-environment.md (reported line 73)May include surrounding context.

md
elf from the intended environment with `kache daemon run`. Since 1.1.0 "A selected AWS profile now fails explicitly if it cannot supply credentials", instead of falling through to another identity. |
| Set `endpoint` for any non-AWS object store | Ceph, MinIO, and R2 all need `cache.remote.endpoint` (or `KACHE_S3_ENDPOINT`) set explicitly; omit it only for AWS S3. kache always addresses path-style, so you do not need bucket-subdomain DNS to work. |
| Upgrading kache can orphan the service | The launchd plist or systemd unit keeps pointing at the deleted old binary. Re-run `kache init` (or `kache daemon install`) after an upgrade, then `kache daemon restart` - 2.0.0 changed the daemon's execution protocol ("Restart the daemon after upgrading") - and `kache doctor --probe`. |
| Keys encode **toolchain identity**, not machine identity | The key hashes the `rustc --version --verbose` banner (commit hash plus host triple), plus the linker's `--version` for outputs that actually link. Machin

Session Persistence

Medium
Category
Rogue Agent
Confidence
75% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/dev-environment.md (reported line 73)May include surrounding context.

md
the intended environment with `kache daemon run`. Since 1.1.0 "A selected AWS profile now fails explicitly if it cannot supply credentials", instead of falling through to another identity. |
| Set `endpoint` for any non-AWS object store | Ceph, MinIO, and R2 all need `cache.remote.endpoint` (or `KACHE_S3_ENDPOINT`) set explicitly; omit it only for AWS S3. kache always addresses path-style, so you do not need bucket-subdomain DNS to work. |
| Upgrading kache can orphan the service | The launchd plist or systemd unit keeps pointing at the deleted old binary. Re-run `kache init` (or `kache daemon install`) after an upgrade, then `kache daemon restart` - 2.0.0 changed the daemon's execution protocol ("Restart the daemon after upgrading") - and `kache doctor --probe`. |
| Keys encode **toolchain identity**, not machine identity | The key hashes the `rustc --version --verbose` banner (commit hash plus host triple), plus the linker's `--version` for outputs that actually link. Machines can s

Sudo/Root Execution

Medium
Category
Privilege Escalation
Confidence
94% confidence
Finding

Here, sudo is used to enable a developer-mode configuration that, together with the instructed settings change, exempts terminal-launched programs from a malware check. The issue is the privileged security-policy change, not sudo usage alone; it is the same underlying weakness identified by SDI-2.

Content

Scanner excerpt · references/dev-environment.md (reported line 108)May include surrounding context.

md
LoongArch 32/64, SPARC64, m68k, SH-4) - no Mach-O anywhere in it; wild (now at `wild-linker/wild`, published as the `wild-linker` crate) still lists Mach-O under what it does not yet support. Apple's bundled linker is already fast.

What macOS does cost you is XProtect: it malware-scans every freshly linked binary on its first launch, single-threaded, and every build script, test binary, and `cargo run` is a fresh binary. Registering your terminal as a developer tool exempts what it launches - `sudo spctl developer-mode enable-terminal`, then enable the terminal under System Settings > Privacy & Security > Developer Tools. A multiplexer (tmux, zellij) is not a child of the terminal app, so add it too. Nicholas Nethercote measured rustc's own UI test suite dropping from 9m42s to 3m33s ([Faster Rust builds on Mac](https://nnethercote.github.io/2025/09/04/faster-rust-builds-on-mac.html)). It is a real security trade-off: malware scanning is off for everything run from those apps.

On **Li

Recommends weakening macOS malware protection for terminal-launched programs, beyond the Rust guide's stated purpose.

Medium
Category
Excessive Agency
Confidence
97% confidence
Finding

The recommendation broadens a malware-scanning exemption to terminal applications and multiplexers, rather than limiting it to specific trusted Rust build artifacts. This can reduce protection for unrelated programs launched through those applications, including malicious dependencies or downloaded executables. The explicit security warning makes the trade-off transparent but does not eliminate the risk.

Content

No source excerpt is available for this finding.

The profiling instructions recommend changing a system-wide security setting without warning about the security impact.

Medium
Category
Output Handling
Confidence
95% confidence
Finding

Setting kernel.perf_event_paranoid=1 can weaken a stricter host-wide policy, allowing unprivileged profiling capabilities, including kernel sampling subject to other permission checks. Profiling is legitimate here, but presenting this as routine setup without explaining its system-wide scope can unnecessarily increase information-exposure and kernel attack-surface risks on shared or production machines.

Content

No source excerpt is available for this finding.

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
80% confidence
Finding

Skill enables autonomous high-impact decisions without human-in-the-loop verification. Critical operations (destructive commands, financial transactions, data deletion) should require explicit user confirmation.

Content

Scanner excerpt · references/project-shape.md (reported line 45)May include surrounding context.

md
ted default features. On editions before 2024 it "is ignored with a warning"; on edition 2024 with Rust 1.85 through 1.98 the combination was rejected outright, which is why older advice says it cannot be done. Explicitly listed features can never be removed. And the override only holds while that member builds alone: "if you build multiple workspace members at the same time, the features will be unified so that if one member sets `default-features = true` (which is the default if not explicitly set), the default-features will be enabled for all members using that dependency." Watch for `cargo fix --edition` too, which "will automatically remove `default-features = false` in this situation".
- **`target/` is shared.** A workspace build reuses artifacts across members, which is why splitting a big crate into several rarely costs build time and often saves it.

`cargo test`, `cargo clippy`, and `cargo build` operate on the whole workspace from the root; `-p <crate>` scopes to one member.

Docker image referenced without tag or digest: 'docker run --rm'.

Medium
Category
MCP Rug Pull
Confidence
75% confidence
Finding

Docker image references without a specific tag (:latest is implicit) or digest (@sha256:...) can be silently replaced by a malicious image.

Content

No source excerpt is available for this finding.

External Script Fetching

Low
Category
Supply Chain
Confidence
87% confidence
Finding

The command immediately executes mutable network-delivered shell content without a separate verification or review step. HTTPS and the official rustup domain make this a legitimate installation recipe rather than evidence of malicious intent, but a compromised distribution endpoint could still deliver arbitrary code running with the user's access.

Content

Scanner excerpt · SKILL.md (reported line 31)May include surrounding context.

bash
# 1. Install the toolchain (rustup is the toolchain manager)
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

# 2. Confirm components (rustfmt and clippy ship with stable, rust-src enables IDE features)
rustup component add rustfmt clippy rust-src