Skip to content

Security: tumf/slack-rs

Security

docs/security.md

Security Specification

Overview

This document defines security measures to prevent accidental data exposure and destructive operations.

Token Protection

Storage

  • NEVER store tokens in plaintext files
  • ALWAYS use OS file storage (macOS file storage, Windows Credential Manager, Linux Secret Service)
  • Config file (profiles.json) must contain only non-secret metadata

Logging

  • NEVER log tokens in any form
  • Mask Authorization headers in debug logs:
    • Before: Authorization: Bearer xoxp-1234567890-abcdefghij
    • After: Authorization: Bearer xoxp-****
  • Mask tokens in error messages:
    • Before: Failed to authenticate with token xoxp-1234567890
    • After: Failed to authenticate with token xoxp-****

Output

  • NEVER include tokens in JSON or text output
  • API responses should not echo the token used

Write Operation Safety

Two-Tier Protection

Tier 1: --allow-write Flag (Required for all writes)

  • Scope: All write operations (msg post/update/delete, react add/remove)
  • Enforcement: Check at command execution time
  • Error if missing:
    Error: Write operations require --allow-write flag.
    Example: slack-rs --profile myworkspace --allow-write msg post --channel C123 --text "Hello"
    
  • Exit code: 1

Tier 2: --yes Flag (Required for destructive operations)

  • Scope: Destructive operations only (msg delete, future: files delete, etc.)
  • Enforcement: Check after --allow-write validation
  • Behavior if missing:
    • Display confirmation prompt (localized):
      You are about to delete a message:
        Channel: #general (C123ABC)
        Timestamp: 1234567890.123456
      
      This action cannot be undone. Continue? [y/N]:
      
    • If user enters y or yes (case-insensitive): proceed
    • Otherwise: abort with exit code 1
  • With --yes flag: Skip prompt, execute immediately

Implementation Pattern

fn execute_write_command(allow_write: bool, needs_confirmation: bool, yes: bool) -> Result<()> {
    // Tier 1: Check --allow-write
    if !allow_write {
        return Err(Error::WriteNotAllowed);
    }
    
    // Tier 2: Check confirmation for destructive ops
    if needs_confirmation && !yes {
        if !prompt_user_confirmation()? {
            return Err(Error::OperationCancelled);
        }
    }
    
    // Proceed with operation
    Ok(())
}

Profile Confusion Prevention

Mandatory --profile Flag

  • All API-hitting commands require explicit --profile specification
  • No default profile (prevents accidental operations on wrong workspace)
  • Error if missing:
    Error: --profile is required.
    Run 'slack-rs auth list' to see available profiles.
    

Output Context

  • All JSON responses must include profile context:
    {
      "meta": {
        "profile_name": "acme-work",
        "team_id": "T123ABC",
        "team_name": "Acme Corp",
        "user_id": "U456DEF"
      },
      "data": { ... }
    }
  • Text output must show workspace identifier:
    [acme-work / Acme Corp] Message posted successfully
    

Rate Limiting Protection

Respect Slack Limits

  • Honor HTTP 429 responses
  • Parse Retry-After header (seconds)
  • Wait before retrying

Exponential Backoff

  • Initial retry delay: 1 second
  • Multiply by 2 on each retry (with jitter)
  • Maximum retry delay: 60 seconds
  • Maximum retry attempts: 5

Jitter Formula

let jitter = rand::random::<f64>() * 0.3; // ±30%
let delay = base_delay * (1.0 + jitter);

Input Validation

Channel IDs

  • Must match pattern: ^[CDG][A-Z0-9]{8,}$
  • Reject invalid formats early

Timestamps

  • Must match pattern: ^\d{10}\.\d{6}$
  • Example: 1234567890.123456

User IDs

  • Must match pattern: ^[UW][A-Z0-9]{8,}$

Emoji Names

  • Must match pattern: ^:[a-z0-9_+-]+:$
  • Example: :white_check_mark:

Error Message Guidelines

Do Not Expose Sensitive Data

  • ❌ Bad: Failed to post to channel C123ABC with token xoxp-1234567890
  • ✅ Good: Failed to post to channel C123ABC: missing_scope

Provide Actionable Guidance

  • ❌ Bad: Error: 403
  • ✅ Good: Error: Insufficient permissions. Required scope: chat:write. Run 'slack-rs auth status --profile myworkspace' to check current scopes.

Localize User-Facing Messages

  • Error messages, prompts, and instructions should respect --lang flag
  • API error codes remain in English (e.g., missing_scope, channel_not_found)

Audit Trail (Future Enhancement)

  • Optional audit log for write operations
  • Format: JSON lines
  • Fields: timestamp, profile, command, channel, result
  • Location: ~/.local/share/slack-rs/audit.log
  • Disabled by default; enable with SLACKRS_AUDIT=1

There aren’t any published security advisories