Back to skill

Security audit

Rust Code Review

Security checks for vulnerabilities and agentic risk

Overview

This is a Rust code-review guidance skill, and I found no hidden execution, persistence, or data-exfiltration behavior.

This skill is appropriate for Rust code review. Before installing, expect it to guide an agent to inspect Rust project files and possibly recommend standard Rust checks; use normal caution before running cargo commands on code you do not trust.

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
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Rogue AgentSelf-Modification, Session Persistence
  • YARA SignaturesMalware Match, Webshell Match, Cryptominer Match
Findings (13)

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
| Async pitfalls, Send/Sync bounds, poll contract, Pin mechanics, cancellation soundness | [references/async-concurrency.md](references/async-concurrency.md) |

Ae1

High
Category
analysis-evasion
Confidence
100% confidence
Finding

Referenced artifact was not completely inspected

Content

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

md
repr, PhantomData, generics vs dyn Trait, wide pointers, auto-trait leakage | [references/types-layout.md](references/types-layout.md) |

YARA rule 'exploit_framework': Exploit framework components and payloads [hacktools]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · references/error-handling.md (reported line 547)May include surrounding context.

ly moves the string into self. Using it on a function that immediately calls .as_ref() is a misleading signature — switch to &str.

Symmetric trap: returning String when the function sometimes already has a borrowed slice forces an unnecessary allocation on the happy path. Cow<'_, str> is the right answer when the borrowed case is common.

Fallible and Blocking Destructors

Drop::drop(&mut self) cannot return Result, cannot .await, and cannot reliably spawn async work because the executor may be shutting down. For I/O-flavored types whose cleanup can fail:

  • Provide best-effort Drop that swallows errors and does what it can synchronously
  • Provide an explicit destructor — fn close(self) -> Result<(), CloseError> (or async fn close(self)) — and document it prominently
rust
impl Connection {
    pub fn close(self) -> Result<(), CloseError> {
        // graceful shutdown, surfaces errors
    }
}

The move-out trap. Once you implement Drop,

YARA rule 'exploit_framework': Exploit framework components and payloads [hacktools]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · references/interface-design.md (reported line 103)May include surrounding context.

ly moves the string into self. Using it on a function that immediately calls .as_ref() is a misleading signature — switch to &str.

Symmetric trap: returning String when the function sometimes already has a borrowed slice forces an unnecessary allocation on the happy path. Cow<'_, str> is the right answer when the borrowed case is common.

Fallible and Blocking Destructors

Drop::drop(&mut self) cannot return Result, cannot .await, and cannot reliably spawn async work because the executor may be shutting down. For I/O-flavored types whose cleanup can fail:

  • Provide best-effort Drop that swallows errors and does what it can synchronously
  • Provide an explicit destructor — fn close(self) -> Result<(), CloseError> (or async fn close(self)) — and document it prominently
rust
impl Connection {
    pub fn close(self) -> Result<(), CloseError> {
        // graceful shutdown, surfaces errors
    }
}

The move-out trap. Once you implement Drop,

YARA rule 'exploit_framework': Exploit framework components and payloads [hacktools]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · references/unsafe-deep.md (reported line 230)May include surrounding context.

ly moves the string into self. Using it on a function that immediately calls .as_ref() is a misleading signature — switch to &str.

Symmetric trap: returning String when the function sometimes already has a borrowed slice forces an unnecessary allocation on the happy path. Cow<'_, str> is the right answer when the borrowed case is common.

Fallible and Blocking Destructors

Drop::drop(&mut self) cannot return Result, cannot .await, and cannot reliably spawn async work because the executor may be shutting down. For I/O-flavored types whose cleanup can fail:

  • Provide best-effort Drop that swallows errors and does what it can synchronously
  • Provide an explicit destructor — fn close(self) -> Result<(), CloseError> (or async fn close(self)) — and document it prominently
rust
impl Connection {
    pub fn close(self) -> Result<(), CloseError> {
        // graceful shutdown, surfaces errors
    }
}

The move-out trap. Once you implement Drop,

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/lock-free-patterns.md (reported line 140)May include surrounding context.

md
### Drop safety

YARA rule 'exploit_framework': Exploit framework components and payloads [hacktools]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · references/lock-free-patterns.md (reported line 146)May include surrounding context.

::Acquire) { std::thread::park(); } unsafe { (*self.channel.message.get()).assume_init_read() } } }

text

### Drop safety

A channel storing `MaybeUninit<T>` **must** implement `Drop` to run `T`'s destructor when dropped with an unreceived message. Forgetting this leaks any non-trivial `T` (`Vec`, `Box`, `File`, `Arc`).

```rust
impl<T> Drop for Channel<T> {
    fn drop(&mut self) {
        if *self.ready.get_mut() {
            unsafe { self.message.get_mut().assume_init_drop() }
        }
    }
}
rust
// BAD: unconditional drop. Runs T::drop on uninit memory if no send happened.
impl<T> Drop for Channel<T> {
    fn drop(&mut self) {
        unsafe { self.message.get_mut().assume_init_drop() }
    }
}

Panic safety

send writes the MaybeUninit<T>, then flips the ready flag. If the user's T::clone or moves can panic, the flag must only be set after the value is fully written. Code that flips ready before writing exposes the rec

YARA rule 'exploit_framework': Exploit framework components and payloads [hacktools]

High
Category
YARA Match
Confidence
80% confidence
Finding

YARA rule matched a hack tool or exploit indicator (offensive tools, reconnaissance, privilege escalation, or exploit frameworks).

Content

Scanner excerpt · references/patterns-in-the-wild.md (reported line 50)May include surrounding context.

to a local; when the scope unwinds, drop runs. Tokio uses this for the executor handle during Future::poll so the handle is cleared even if poll panics. scopeguard::defer! packages the pattern for ad-hoc use.

rust
fn with_flag(flag: &AtomicBool, f: impl FnOnce()) {
    flag.store(true, Ordering::Release);
    struct Guard<'a>(&'a AtomicBool);
    impl Drop for Guard<'_> {
        fn drop(&mut self) { self.0.store(false, Ordering::Release); }
    }
    let _guard = Guard(flag);
    f();
} // _guard drops here, even on panic

The single most common bug: let _ = Guard(flag) instead of let _guard = Guard(flag). The bare _ pattern is not a binding — it drops the value immediately at the ;, before the protected code runs. Reviewers miss this because the two lines look identical at a glance.

State-restore variant uses mem::replace / mem::take to capture the prior value:

rust
struct Restore<'a, T>(&'a mut T, Option<T>);
impl<T> Drop for Restore<'_, T> {

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/unsafe-deep.md (reported line 129)May include surrounding context.

md
| Pointer validity | Non-null, aligned, initialized, within allocation bounds |
| Aliasing | No simultaneous `&T` and `&mut T` to the same memory |
| Panic safety | State is consistent if user-provided code panics mid-operation |
| Drop safety | `Drop` impl doesn't access dangling data; `PhantomData` used for drop check |
| Send/Sync | Manual implementations have correct bounds; raw pointers covered |
| UnsafeCell | All interior mutation goes through `UnsafeCell` |
| FFI | Extern blocks are `unsafe extern` (Edition 2024); signatures match the foreign ABI |

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% 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/concurrency-primitives.md (reported line 156)May include surrounding context.

md
- A `Drop` impl that unconditionally calls `assume_init_drop` on a `MaybeUninit<T>` field — drops uninitialized memory when the gate flag is false. The correct shape is `if *self.ready.get_mut() { unsafe { self.value.get_mut().assume_init_drop() } }`.
- For lazy one-shot init, prefer `OnceLock::get_or_init` over hand-rolled `MaybeUninit` + `AtomicBool` unless allocation or `const fn` construction is a hard requirement.

- `[FILE:LINE] MAYBEUNINIT_UNCONDITIONAL_DROP` — `assume_init_drop` in a `Drop` impl without checking an init flag.
- `[FILE:LINE] MAYBEUNINIT_DOUBLE_READ` — two `assume_init_read` calls reachable on the same `MaybeUninit` storage.

## Mutex and RwLock Poisoning

Autonomous Decision Making

Medium
Category
Excessive Agency
Confidence
75% 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/lock-free-patterns.md (reported line 189)May include surrounding context.

md
- A `Drop` impl that unconditionally calls `assume_init_drop` on a `MaybeUninit<T>` field — drops uninitialized memory when the gate flag is false. The correct shape is `if *self.ready.get_mut() { unsafe { self.value.get_mut().assume_init_drop() } }`.
- For lazy one-shot init, prefer `OnceLock::get_or_init` over hand-rolled `MaybeUninit` + `AtomicBool` unless allocation or `const fn` construction is a hard requirement.

- `[FILE:LINE] MAYBEUNINIT_UNCONDITIONAL_DROP` — `assume_init_drop` in a `Drop` impl without checking an init flag.
- `[FILE:LINE] MAYBEUNINIT_DOUBLE_READ` — two `assume_init_read` calls reachable on the same `MaybeUninit` storage.

## Mutex and RwLock Poisoning

Session Persistence

Medium
Category
Rogue Agent
Confidence
60% 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/error-handling.md (reported line 118)May include surrounding context.

// GOOD - log if you can't propagate if let Err(e) = save_to_disk(&data) { tracing::error!(error = %e, "failed to save data to disk"); }

text

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
76% confidence
Finding

This is a natural-language locale/platform policy concern because the guidance singles out Apple Silicon behavior as a default portability constraint rather than clearly framing it as conditional platform-specific advice. Although technical in nature, it could be interpreted as forcing a specific platform assumption without explicit opt-in.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.