跳到主要内容

security-guardian 精选

CLI security expert for RTK - command injection, shell escaping, hook security

编码 Claude CodeCodex CLI Apache-2.0 8.3 万
在 GitHub 打开

安装方式

cp -r .claude/skills/security-guardian ~/.claude/skills/security-guardian

把该 skill 目录放进客户端 skills 目录。不同客户端的目录可能不同,Claude Code 默认是 ~/.claude/skills/

整仓一次性获取:git clone --depth 1 https://github.com/rtk-ai/rtk.git

依赖与权限

  • 无需 API Key
  • 需要联网访问外部服务
  • 依赖外部命令:git pnpm docker gh curl cargo rustc rg
  • 以上为按正文与 frontmatter 自动推断的信号,仅供参考;安装前建议先阅读原文。
allowed-tools
Read Grep Glob Bash

SKILL.md 正文

来源 rtk-ai/rtk@311ebcb · 许可 Apache-2.0 · 内容未修改

Security Guardian

Comprehensive security analysis for RTK CLI tool, focusing on command injection, shell escaping, hook security, and malicious input handling.

When to Use

  • Automatically triggered: After filter changes, shell command execution logic, hook modifications
  • Manual invocation: Before release, after security-sensitive code changes
  • Proactive: When handling user input, executing shell commands, or parsing untrusted output

RTK Security Threat Model

RTK faces unique security challenges as a CLI proxy that:

  1. Executes shell commands based on user input
  2. Parses untrusted command output (git, cargo, gh, etc.)
  3. Integrates with Claude Code hooks (rtk-rewrite.sh, rtk-suggest.sh)
  4. Routes commands transparently (command injection vectors)

Threat Categories

ThreatSeverityImpactMitigation
Command Injection🔴 CRITICALRemote code executionInput validation, shell escaping
Shell Escaping🔴 CRITICALArbitrary command executionPlatform-specific escaping
Hook Injection🟡 HIGHHook hijacking, command interceptionPermission checks, signature validation
Malicious Output🟡 MEDIUMRTK crash, DoSRobust parsing, error handling
Path Traversal🟢 LOWFile access outside filters/Path sanitization

Security Analysis Workflow

1. Threat Identification

Questions to ask for every code change:

Input Validation:
- Does this code accept user input?
- Is the input validated before use?
- Can special characters (;, |, &, $, `, \, etc.) cause issues?

Shell Execution:
- Does this code execute shell commands?
- Are command arguments properly escaped?
- Is std::process::Command used (safe) or shell=true (dangerous)?

Output Parsing:
- Does this code parse external command output?
- Can malformed output cause panics or crashes?
- Are regex patterns tested against malicious input?

Hook Integration:
- Does this code modify hooks?
- Are hook permissions validated (executable bit)?
- Is hook source code integrity checked?

2. Code Audit Patterns

Command Injection Detection:

// 🔴 CRITICAL: Shell injection vulnerability
let user_input = env::args().nth(1).unwrap();
let cmd = format!("git log {}", user_input); // DANGEROUS!
std::process::Command::new("sh")
    .arg("-c")
    .arg(&cmd) // Attacker can inject: `; rm -rf /`
    .spawn();

// ✅ SAFE: Use Command builder, not shell
use std::process::Command;

let user_input = env::args().nth(1).unwrap();
Command::new("git")
    .arg("log")
    .arg(&user_input) // Safely passed as argument, not interpreted by shell
    .spawn();

Shell Escaping Vulnerability:

// 🔴 CRITICAL: No escaping for special chars
fn execute_raw(cmd: &str, args: &[&str]) -> Result<Output> {
    let full_cmd = format!("{} {}", cmd, args.join(" "));
    Command::new("sh")
        .arg("-c")
        .arg(&full_cmd) // DANGEROUS: args not escaped
        .output()
}

// ✅ SAFE: Use Command builder, automatic escaping
fn execute_raw(cmd: &str, args: &[&str]) -> Result<Output> {
    Command::new(cmd)
        .args(args) // Safely escaped by Command API
        .output()
}

Malicious Output Handling:

// 🔴 CRITICAL: Panic on unexpected output
fn filter_git_log(input: &str) -> String {
    let first_line = input.lines().next().unwrap(); // Panic if empty!
    let hash = &first_line[7..47]; // Panic if line too short!
    hash.to_string()
}

// ✅ SAFE: Graceful error handling
fn filter_git_log(input: &str) -> Result<String> {
    let first_line = input.lines().next()
        .ok_or_else(|| anyhow::anyhow!("Empty input"))?;

    if first_line.len() < 47 {
        bail!("Invalid git log format");
    }

    Ok(first_line[7..47].to_string())
}

Hook Injection Prevention:

# 🔴 CRITICAL: Hook not checking source
#!/bin/bash
# rtk-rewrite.sh

# Execute command without validation
eval "$CLAUDE_CODE_HOOK_BASH_TEMPLATE" # DANGEROUS!

# ✅ SAFE: Validate hook environment
#!/bin/bash
# rtk-rewrite.sh

# Verify running in Claude Code context
if [ -z "$CLAUDE_CODE_HOOK_BASH_TEMPLATE" ]; then
    echo "Error: Not running in Claude Code context"
    exit 1
fi

# Validate RTK binary exists and is executable
if ! command -v rtk >/dev/null 2>&1; then
    echo "Error: rtk binary not found"
    exit 1
fi

# Execute with explicit path (no PATH hijacking)
/usr/local/bin/rtk "$@"

3. Security Testing

Command Injection Tests:

#[cfg(test)]
mod security_tests {
    use super::*;

    #[test]
    fn test_command_injection_defense() {
        // Malicious input: attempt shell injection
        let malicious_inputs = vec![
            "; rm -rf /",
            "| cat /etc/passwd",
            "$(whoami)",
            "`id`",
            "&& curl evil.com",
        ];

        for input in malicious_inputs {
            // Should NOT execute injected commands
            let result = execute_command("git", &["log", input]);

            // Either:
            // 1. Returns error (command fails safely), OR
            // 2. Treats input as literal string (no shell interpretation)
            // Both acceptable - just don't execute injection!
        }
    }

    #[test]
    fn test_shell_escaping() {
        // Special characters that need escaping
        let special_chars = vec![
            ";", "|", "&", "$", "`", "\\", "\"", "'", "\n", "\r",
        ];

        for char in special_chars {
            let arg = format!("test{}value", char);
            let escaped = escape_for_shell(&arg);

            // Escaped version should NOT be interpreted by shell
            assert!(!escaped.contains(char) || escaped.contains('\\'));
        }
    }
}

Malicious Output Tests:

#[test]
fn test_malicious_output_handling() {
    // Malformed outputs that could crash RTK
    let malicious_outputs = vec![
        "", // Empty
        "\n\n\n", // Only newlines
        "x".repeat(1_000_000), // 1MB of 'x' (memory exhaustion)
        "\x00\x01\x02", // Binary data
        "\u{FFFD}".repeat(1000), // Unicode replacement chars
    ];

    for output in malicious_outputs {
        let result = filter_git_log(&output);

        // Should either:
        // 1. Return Ok with filtered output, OR
        // 2. Return Err (graceful failure)
        // Both acceptable - just don't panic!
        assert!(result.is_ok() || result.is_err());
    }
}

Security Vulnerabilities Checklist

Command Injection (🔴 Critical)

  • [ ] No shell=true: Never use .arg("-c") with user input
  • [ ] Command builder: Use std::process::Command API (not shell strings)
  • [ ] Input validation: Validate/sanitize before command execution
  • [ ] Whitelist approach: Only allow known-safe commands

Detection:

# Find dangerous shell execution
rg "\.arg\(\"-c\"\)" --type rust src/
rg "std::process::Command::new\(\"sh\"\)" --type rust src/
rg "format!.*\{.*Command" --type rust src/

Shell Escaping (🔴 Critical)

  • [ ] Platform-specific: Test escaping on macOS, Linux, Windows
  • [ ] Special chars: Handle ;, |, &, $, ` `, \, ", ', \n`
  • [ ] Use shell-escape crate: Don't roll your own escaping
  • [ ] Cross-platform tests: #[cfg(target_os = "...")] tests

Detection:

# Find potential escaping issues
rg "format!.*\{.*args" --type rust src/
rg "\.join\(\" \"\)" --type rust src/

Hook Security (🟡 High)

  • [ ] Permission checks: Verify hooks are executable (-rwxr-xr-x)
  • [ ] Source validation: Only execute hooks from .claude/hooks/
  • [ ] Environment validation: Check $CLAUDE_CODE_HOOK_BASH_TEMPLATE
  • [ ] No dynamic evaluation: No eval or source of untrusted files

Hook security checklist:

#!/bin/bash
# rtk-rewrite.sh

# 1. Verify Claude Code context
if [ -z "$CLAUDE_CODE_HOOK_BASH_TEMPLATE" ]; then
    exit 1
fi

# 2. Verify RTK binary exists
if ! command -v rtk >/dev/null 2>&1; then
    exit 1
fi

# 3. Use absolute path (prevent PATH hijacking)
RTK_BIN=$(which rtk)

# 4. Validate RTK version (prevent downgrade attacks)
if ! "$RTK_BIN" --version | grep -q "rtk 0.16"; then
    echo "Warning: RTK version mismatch"
fi

# 5. Execute with explicit path
"$RTK_BIN" "$@"

Malicious Output (🟡 Medium)

  • [ ] No .unwrap(): Use Result for parsing, graceful error handling
  • [ ] Bounds checking: Verify string lengths before slicing
  • [ ] Regex timeouts: Prevent ReDoS (Regular Expression Denial of Service)
  • [ ] Memory limits: Cap output size before parsing

Parsing safety pattern:

fn safe_parse(output: &str) -> Result<String> {
    // 1. Check output size (prevent memory exhaustion)
    if output.len() > 10_000_000 {
        bail!("Output too large (>10MB)");
    }

    // 2. Validate format (prevent malformed input)
    if !output.starts_with("commit ") {
        bail!("Invalid git log format");
    }

    // 3. Bounds checking (prevent panics)
    let first_line = output.lines().next()
        .ok_or_else(|| anyhow::anyhow!("Empty output"))?;

    if first_line.len() < 47 {
        bail!("Commit hash too short");
    }

    // 4. Safe extraction
    Ok(first_line[7..47].to_string())
}

Security Best Practices

Input Validation

Whitelist approach (safer than blacklist):

fn validate_command(cmd: &str) -> Result<()> {
    // ✅ SAFE: Whitelist known-safe commands
    const ALLOWED_COMMANDS: &[&str] = &[
        "git", "cargo", "gh", "pnpm", "docker",
        "rustc", "clippy", "rustfmt",
    ];

    if !ALLOWED_COMMANDS.contains(&cmd) {
        bail!("Command '{}' not allowed", cmd);
    }

    Ok(())
}

// ❌ UNSAFE: Blacklist approach (easy to bypass)
fn validate_command_unsafe(cmd: &str) -> Result<()> {
    const BLOCKED: &[&str] = &["rm", "dd", "mkfs"];

    if BLOCKED.contains(&cmd) {
        bail!("Command '{}' blocked", cmd);
    }

    Ok(())
    // Attacker can use: /bin/rm, rm.exe, RM (case variation), etc.
}

Shell Escaping

Use dedicated library:

use shell_escape::escape;

fn escape_arg(arg: &str) -> String {
    // ✅ SAFE: Use battle-tested escaping library
    escape(arg.into()).into()
}

// ❌ UNSAFE: Roll your own escaping (likely has bugs)
fn escape_arg_unsafe(arg: &str) -> String {
    arg.replace('"', r#"\""#) // Misses many special chars!
}

Platform-specific escaping:

#[cfg(target_os = "windows")]
fn escape_for_shell(arg: &str) -> String {
    // PowerShell escaping
    format!("\"{}\"", arg.replace('"', "`\""))
}

#[cfg(not(target_os = "windows"))]
fn escape_for_shell(arg: &str) -> String {
    // Bash/zsh escaping
    shell_escape::escape(arg.into()).into()
}

Secure Command Execution

Always use Command builder:

use std::process::Command;

// ✅ SAFE: Command builder (no shell)
fn execute_git(args: &[&str]) -> Result<Output> {
    Command::new("git")
        .args(args) // Safely escaped
        .output()
        .context("Failed to execute git")
}

// ❌ UNSAFE: Shell string concatenation
fn execute_git_unsafe(args: &[&str]) -> Result<Output> {
    let cmd = format!("git {}", args.join(" "));
    Command::new("sh")
        .arg("-c")
        .arg(&cmd) // Shell interprets args!
        .output()
}

Security Audit Command Reference

Find potential vulnerabilities:

# Command injection
rg "\.arg\(\"-c\"\)" --type rust src/
rg "format!.*Command" --type rust src/

# Shell escaping
rg "\.join\(\" \"\)" --type rust src/
rg "format!.*\{.*args" --type rust src/

# Unsafe unwraps (can panic on malicious input)
rg "\.unwrap\(\)" --type rust src/

# Bounds violations
rg "\[.*\.\.\.\]" --type rust src/
rg "\[.*\.\.]" --type rust src/

# Hook security
rg "eval|source" --type bash .claude/hooks/

Incident Response

If vulnerability discovered:

  1. Assess severity: Use CVSS scoring (Critical/High/Medium/Low)
  2. Develop patch: Fix vulnerability in isolated branch
  3. Test fix: Verify with security tests + integration tests
  4. Release hotfix: PATCH version bump (e.g., v0.16.0 → v0.16.1)
  5. Disclose responsibly: GitHub Security Advisory, CVE if applicable

Example advisory template:

## Security Advisory: Command Injection in rtk v0.16.0

**Severity**: CRITICAL (CVSS 9.8)
**Affected versions**: v0.15.0 - v0.16.0
**Fixed in**: v0.16.1

**Description**:
RTK versions 0.15.0 through 0.16.0 are vulnerable to command injection
via malicious git repository names. An attacker can execute arbitrary
shell commands by creating a repository with special characters in the name.

**Impact**:
Remote code execution with user privileges.

**Mitigation**:
Upgrade to v0.16.1 immediately. As a workaround, avoid using RTK in
directories with untrusted repository names.

**Credits**:
Reported by: Security Researcher Name

Security Resources

Tools:

  • cargo audit - Dependency vulnerability scanning
  • cargo-geiger - Unsafe code detection
  • cargo-deny - Dependency policy enforcement
  • semgrep - Static analysis for security patterns

Run security checks:

# Dependency vulnerabilities
cargo install cargo-audit
cargo audit

# Unsafe code detection
cargo install cargo-geiger
cargo geiger

# Static analysis
cargo install semgrep
semgrep --config auto

质量与来源

所属仓库
rtk-ai/rtk
仓库星标
8.3 万
最近更新
今天
采集时间
今天
commit
311ebcbfd8ef
内容指纹
sha256:d41c23635f53e72
文件路径
.claude/skills/security-guardian/SKILL.md

同仓库其它 Skill

查看全部 12 个
code-simplifier
Review RTK Rust code for idiomatic simplification. Detects over-engineering, unnecessary allocations, verbose patterns. Applies Rust idioms without changing behavior.
精选 rtk-ai/rtk 8.3 万 原文
Claude CodeCodex CLI
design-patterns
Rust design patterns for RTK. Newtype, Builder, RAII, Trait Objects, State Machine. Applied to CLI filter modules. Use when designing new modules or refactoring existing ones.
精选 rtk-ai/rtk 8.3 万 原文
Claude CodeCodex CLI
issue-triage
Issue triage: audit open issues, categorize, detect duplicates, cross-ref PRs, risk assessment, post comments. Args: "all" for deep analysis of all, issue numbers to focus (e.g. "42 57"), "en"/"fr" for language, no arg = audit only in French.
精选 rtk-ai/rtk 8.3 万 原文
Claude CodeCodex CLI
performance
CLI performance optimization - startup time, memory usage, token savings benchmarking
精选 rtk-ai/rtk 8.3 万 原文
Claude CodeCodex CLI
pr-review
Batch review des PRs RTK par ordre de complexité croissante (XS → S → M → L). Pour chaque PR : vérifie l'état (conflits, CLA, reviews), lit le diff complet, analyse le code en contexte, présente un résumé avec lien + taille + recommandation. Attend validation explicite avant tout merge. Poste des commentaires boldguy-adapt sur les PRs bloquées (conflit, CLA, CHANGES_REQUESTED). Args: "triage" pour lancer un triage complet avant la review. "from:<num>" pour reprendre à partir d'un numéro de PR spécifique.
精选 rtk-ai/rtk 8.3 万 原文
Claude CodeCodex CLI
pr-triage
PR triage: audit open PRs, deep review selected ones, draft and post review comments. Args: "all" to review all, PR numbers to focus (e.g. "42 57"), "en"/"fr" for language, no arg = audit only in French.
精选 rtk-ai/rtk 8.3 万 原文
Claude CodeCodex CLI

相似 Skill

更多「编码」
access
Manage Discord channel access — approve pairings, edit allowlists, set DM/group policy. Use when the user asks to pair, approve someone, check who's allowed, or change policy for the Discord channel.
精选 anthropics/claude-plugins-official 3.8 万 原文
Claude CodeMCP 客户端
configure
Set up the Discord channel — save the bot token and review access policy. Use when the user pastes a Discord bot token, asks to configure Discord, asks "how do I set this up" or "who can reach me," or wants to check channel status.
精选 anthropics/claude-plugins-official 3.8 万 原文
Claude CodeMCP 客户端
access
Manage iMessage channel access — approve pairings, edit allowlists, set DM/group policy. Use when the user asks to pair, approve someone, check who's allowed, or change policy for the iMessage channel.
精选 anthropics/claude-plugins-official 3.8 万 原文
Claude CodeMCP 客户端
configure
Check iMessage channel setup and review access policy. Use when the user asks to configure iMessage, asks "how do I set this up" or "who can reach me," or wants to know why texts aren't reaching the assistant.
精选 anthropics/claude-plugins-official 3.8 万 原文
Claude CodeMCP 客户端
access
Manage Telegram channel access — approve pairings, edit allowlists, set DM/group policy. Use when the user asks to pair, approve someone, check who's allowed, or change policy for the Telegram channel.
精选 anthropics/claude-plugins-official 3.8 万 原文
Claude CodeMCP 客户端
configure
Set up the Telegram channel — save the bot token and review access policy. Use when the user pastes a Telegram bot token, asks to configure Telegram, asks "how do I set this up" or "who can reach me," or wants to check channel status.
精选 anthropics/claude-plugins-official 3.8 万 原文
Claude CodeMCP 客户端