rust
Clippy lint suppression detected. Clippy warnings exist because the flagged pattern is typically incorrect or suboptimal. Understand the lint before suppressing it — if suppression is truly justified, add a comment explaining why above the attribute.
#[allow(dead_code)] silences a warning that usually means unused code should be deleted. Remove dead code rather than suppressing the warning. If the code is intentionally kept (e.g., for future use or a public API), add a comment explaining why.
#[allow(unused_*)] suppresses warnings about unused variables, imports, or functions. Unused items are usually dead code — remove them rather than hiding the warning.
dbg!() is a debugging macro that prints to stderr at runtime — it should not appear in committed source code. Remove before merging, or use a structured logger (tracing, log crate) for persistent diagnostics.
str::from_utf8_unchecked() skips UTF-8 validation and is undefined behaviour on invalid input. Use str::from_utf8() which returns a Result<&str, Utf8Error> and handle the error explicitly.
Numeric cast to a narrower integer type silently truncates on overflow — Rust does not panic or saturate. Use .try_into().expect() to make the bounds check explicit, or TryFrom/TryInto for fallible conversion.
mem::transmute reinterprets raw bytes across types with no runtime checks — it is one of the most dangerous operations in Rust. Use From/Into, bytemuck::cast, or a union with a safe accessor pattern instead.
panic!() in library code terminates the entire caller's program without recovery. Library code should return Result<T, E> and let the caller decide how to handle errors. Reserve panic!() for truly unrecoverable invariant violations that indicate a programming bug.
Raw pointer cast detected. Raw pointers bypass borrow-checker safety. Prefer references, Box<T>, or a safe abstraction. If this is required for FFI, wrap it in a safe function that enforces all invariants.
todo!() and unimplemented!() are placeholder macros that panic at runtime. They must not ship in production code — complete the implementation or return a proper error.
unsafe blocks are banned. Rust's safety guarantees exist to prevent memory corruption and undefined behaviour — every unsafe block is a hole in those guarantees. Rewrite using safe abstractions. If FFI is required, isolate it behind a safe wrapper and justify the invariants in a comment.
.unwrap() panics on None or Err, crashing the process. Use the ? operator to propagate errors, match/if-let to handle them, or .unwrap_or()/.unwrap_or_else() for fallbacks. Reserve .unwrap() for test code and cases where you can prove the value is always Some/Ok.
RISK: building a Command argument with format!() injects arbitrary OS commands when the formatted value contains attacker-controlled data (CWE-78). In notify.rs the osascript/PowerShell script string is interpolated from user-visible title/body strings — any unescaped quote or backtick terminates the AppleScript expression or the PowerShell -Command block and runs attacker code. FIX: pass each logical argument as a separate .arg() call so the OS never interprets shell metacharacters, or use a structured notification library (notify-rust) that never shells out.
RISK: passing -c (sh/bash) or the equivalent flag to a Command causes the OS to interpret the next argument as a full shell expression, collapsing all downstream .arg() calls into one shell-parsed string and enabling CWE-78 command injection. FIX: invoke the target binary directly with individual .arg() calls; never pass -c to a shell.
RISK: std::mem::uninitialized() is deprecated and produces immediate undefined behaviour for almost every type because the value is implicitly dropped on panic. FIX: use std::mem::MaybeUninit<T> and only read with .assume_init() after fully initialising via ptr::write.
RISK: a reqwest Client created without an explicit timeout will block its task/thread indefinitely on a stalled server or a connection that never closes, causing unbounded resource exhaustion (CWE-400). A single hung request in the voice-core or screenshots-core HTTP path can freeze the axum worker pool. FIX: always set both a connect timeout and a read timeout: reqwest::Client::builder().connect_timeout(Duration::from_secs(10)).timeout(Duration::from_secs(30)).build(). Consider per-request timeouts for bulk operations.
RISK: printing secrets, tokens, or credential fields via dbg!/println!/eprintln! leaks them to stdout, stderr, log files, crash dumps, and any log aggregator pipeline (CWE-532). Voice-core and screenshots-core roll daily logs to ~/.sigmashake/ which may be readable by co-located processes. FIX: never log raw secret values — log only their length, a redacted prefix (first 4 chars + "***"), or a boolean presence flag. Use a secrets-aware tracing subscriber (tracing-subscriber's EnvFilter) rather than println! for structured diagnostics.
RISK: building SQL via format!() or string concatenation lets any value that touches the query string perform SQL injection (CWE-89, CVE-2021-45230 class). Even values that look safe today may become attacker-controlled when the call site is refactored. FIX: use parameterized queries — sqlx::query!("SELECT … WHERE id = ?", id), diesel query builder, or rusqlite params![]. Never interpolate runtime values into a query string.
RISK: disabling TLS certificate or hostname verification in reqwest lets any MITM attacker intercept HTTPS traffic and steal credentials. FIX: keep verification enabled; if you must trust a self-signed cert, load it explicitly with reqwest::Certificate::from_pem() and add_root_certificate().
RISK: tokio-tar and async-tar contain the unpatched TARmageddon boundary-parsing bug (CVE-2025-62518, CVSS 8.1) that enables RCE via crafted archives; tokio-tar is unmaintained. FIX: migrate to the patched fork astral-tokio-tar >= 0.5.6.
RISK: silencing cargo-audit / cargo-deny advisories without written justification masks unpatched vulnerabilities; the rust-coreutils audit (44 CVEs, CVE-2026-35338..35381) shows how a single unreviewed ignore entry can become a production CVSS 7+ vulnerability. FIX: each entry in ignore = [...] needs an inline comment with: advisory ID, impact analysis, and a planned remediation date — remove the entry once a patched version ships.
RISK: NSS lookups (getpwnam/getgrnam/User::from_name) after chroot read /etc/passwd from the new root, letting an attacker who controls the chroot tree inject arbitrary uid/gid mappings into your privilege-drop logic (CVE-2026-35368, CVSS 7.8). FIX: resolve the user/group identity BEFORE calling chroot, then pass the numeric uid/gid into the chrooted region.
Executing shell commands with untrusted input can lead to command injection. Avoid using a shell unless absolutely necessary, and prefer passing arguments directly to the target executable.
RISK: std::env::set_var / remove_var are unsafe in Rust 2024 because they race with getenv in other threads and can cause memory unsafety in multi-threaded programs. FIX: set environment variables before spawning threads, or pass configuration through function arguments / a typed config struct instead.
RISK: File::create opens with O_CREAT|O_TRUNC|O_WRONLY without O_EXCL or an explicit mode; a pre-placed symlink at the target is followed and a TOCTOU window lets an attacker redirect the write (CVE-2026-35360 touch, CVE-2026-35367 nohup default 0644, CVSS 5.5-6.8). FIX: use OpenOptions::new().mode(0o600).custom_flags(libc::O_NOFOLLOW | libc::O_EXCL).create_new(true).open(p).
RISK: std::fs::copy dereferences symlinks at both ends, so a target-side symlink swap silently writes through to an attacker-chosen file, and cross-device recursive copies expand symlinks into real data (CVE-2026-35365 mv, CVE-2026-35372 ln, CVSS 6.5). FIX: use fs::symlink_metadata first; on symlinks call fs::read_link + fs::symlink; for regular files use OpenOptions with O_NOFOLLOW on both sides and io::copy on the fds.
RISK: fs::remove_dir on an arbitrary cleanup path silently fails on FIFOs, device nodes, and symlinks, leaving mislabeled or partially-created nodes behind (CVE-2026-35361 mknod cleanup, CVSS 5.3). FIX: stat with fs::symlink_metadata first; use fs::remove_file for non-directory entries; only call fs::remove_dir when file_type().is_dir() is confirmed.
RISK: path-based fs::set_permissions races a malicious symlink swap between create and chmod, letting an attacker apply your mode to /etc/shadow (CVE-2026-35341/CVE-2026-35356/CVE-2026-35357, CVSS 7.0). FIX: open the file once with OpenOptions::new().mode(0o600).custom_flags(libc::O_NOFOLLOW).create_new(true).open(p), then call File::set_permissions on the resulting fd — never re-resolve the path.
MD5 and SHA-1 are cryptographically broken. Use stronger hashing algorithms like SHA-256 (e.g., via the sha2 crate) or Blake3.
RISK: lossy UTF-8 conversion replaces non-UTF-8 bytes with U+FFFD, mangling filenames and corrupting output when handling real Unix paths (CVE-2026-35346 comm, CVE-2026-35366 printenv, CVE-2026-35373 ln, CVE-2026-35375 split, CVSS 4.3-6.5). FIX: keep OsStr/OsString through the pipeline; only convert at display boundaries; on Unix use OsStrExt::as_bytes() for byte-accurate path handling.
RISK: Path/OsStr::to_str().expect() or .unwrap() panics on any non-UTF-8 path — an attacker who can place such a filename (trivial on Unix) crashes the process (CVE-2026-35348 sort, CVSS 5.3). FIX: handle non-UTF-8 paths via OsStr (Unix: OsStrExt::as_bytes()); reserve to_str().unwrap_or() for display only.
RISK: comparing path == "/" to enforce --preserve-root is bypassed by trivial inputs like "//", "/.", "/foo/..", or a symlink whose target is / (CVE-2026-35338 chmod, CVE-2026-35349 rm, CVE-2026-35363 rm trailing-slash, CVSS 7.5). FIX: stat the path with fs::metadata, compare (st_dev, st_ino) against fs::metadata("/")?.dev/ino; reject the operation when they match.
RISK: .ok(); at statement position discards the Err arm of a Result, hiding write/chmod/chown failures and producing a successful exit code on partial failure (CVE-2026-35339 chmod -R, CVE-2026-35340 chown -R, CVE-2026-35344 dd, CVSS 4.3-5.3). FIX: accumulate errors with a Vec<Error> or boolean flag; exit non-zero if any operation failed.
RISK: a Deserialize struct without #[serde(deny_unknown_fields)] silently accepts and ignores extra JSON fields from callers (CWE-915). In the screenshots-core and voice-core HTTP handlers, a caller can smuggle fields whose names will be reflected in logs or consumed by future code revisions without any validation gate. FIX: add #[serde(deny_unknown_fields)] to every struct that deserialises untrusted input (HTTP request bodies, IPC messages, plugin payloads); use a separate internal struct for trusted inter-service data where evolution is expected.
Using format! to construct SQL queries is highly vulnerable to SQL injection. Use parameterized queries via your database driver or ORM (e.g., sqlx, diesel).
RISK: env::var("TMPDIR") returns Ok("") for an empty (but set) TMPDIR; .unwrap_or("/tmp") only fires for the Err arm, so an attacker who exports TMPDIR= causes temp files to land in CWD instead (CVE-2026-35342 mktemp, CVSS 5.5). FIX: prefer std::env::temp_dir() which handles the empty case, or match Ok(s) if !s.is_empty() with an explicit /tmp fallback.