← MCP server and skill grades

slack-mcp-server

korotovsky/slack-mcp-server

C
Type
MCP server
Scanned
Oct 29, 2026
Version
b88c0de3f706
Files read
74

This project is an MCP server that connects AI agents to Slack workspaces to read messages, search channels and users, download attachments, post messages, and manage user groups and saved items. The main risks are that several workspace-modifying tools are enabled by default without opt-in guards (exposing the user's Slack account to prompt injection when reading untrusted messages), and SSE/HTTP network modes run without authentication unless an API key is explicitly configured.

What it can reach

Secrets
Reads Slack authentication tokens (SLACK_MCP_XOXP_TOKEN, SLACK_MCP_XOXB_TOKEN, SLACK_MCP_XOXC_TOKEN, SLACK_MCP_XOXD_TOKEN) and optional server API keys (SLACK_MCP_API_KEY) from environment variables.
Network
Makes HTTPS requests to Slack APIs (slack.com, edgeapi.slack.com, slack-gov.com) and optional proxy servers, and can listen on TCP ports in SSE or HTTP transport modes (127.0.0.1:13080 by default, or 0.0.0.0:3001 in Docker).
Files
Reads and writes local JSON cache files for Slack users and channels in the user cache directory (or paths set via SLACK_MCP_USERS_CACHE and SLACK_MCP_CHANNELS_CACHE) and reads custom CA certificates if SLACK_MCP_SERVER_CA is set.
Other
Accesses and modifies the user's Slack workspace (channels, direct messages, files, reactions, user groups, and saved items) using the configured user, bot, or browser session credentials.

Findings

1 high3 medium
  1. HighUnauthenticated Network Listener in SSE and HTTP Modes by Default

    pkg/server/auth/sse_auth.go:28

    When the server is run in SSE or HTTP transport mode, authentication is completely bypassed if SLACK_MCP_API_KEY (or SLACK_MCP_SSE_API_KEY) is not set. Because the provided Dockerfile defaults to SSE mode and docker-compose.yml binds SLACK_MCP_HOST to 0.0.0.0:3001 without configuring an API key, any client able to reach the port can read Slack messages, channels, and user directories or invoke enabled tools without authentication. Additionally, because authentication is only applied as a middleware on tool and resource execution, unauthenticated clients can still connect, initialize, and enumerate tools and resources (including the workspace name) even when an API key is set.

    Fix: Require SLACK_MCP_API_KEY to be configured when starting SSE or HTTP transports (especially when bound to non-loopback interfaces), and enforce Bearer token validation at the HTTP handler level for all MCP requests.

  2. MediumState-Modifying Slack Tools Enabled by Default Without Opt-In Guards

    pkg/server/server.go:70

    Although message posting and reactions are disabled by default to protect workspaces against unintended actions, several other state-modifying and destructive tools are registered and enabled by default without an environment variable check: conversations_leave, conversations_join, usergroups_create, usergroups_update, usergroups_users_update, usergroups_me, saved_update, and saved_clear_completed. A prompt injection in a Slack message or external document read by the agent can trigger these tools to make the user leave private channels, overwrite user group memberships across the workspace, or clear completed saved items.

    Fix: Require explicit opt-in via environment variables or SLACK_MCP_ENABLED_TOOLS before registering or executing state-modifying tools such as conversations_leave, conversations_join, usergroups_*, and saved_*.

  3. MediumSetting SLACK_MCP_SERVER_CA_INSECURE=false Disables TLS Certificate Verification

    pkg/transport/transport.go:378

    The README documents the default value of SLACK_MCP_SERVER_CA_INSECURE as 'false'. However, the code only checks whether the environment variable is non-empty. If a user explicitly sets SLACK_MCP_SERVER_CA_INSECURE=false or SLACK_MCP_SERVER_CA_INSECURE=0 in their environment or .env file, the server sets InsecureSkipVerify to true and disables TLS certificate verification for all Slack API connections, exposing tokens and messages to man-in-the-middle attacks. The same non-empty check is used for SLACK_MCP_SERVER_CA_TOOLKIT, which trusts a hardcoded HTTP Toolkit CA certificate even when set to 'false'.

    Fix: Parse boolean environment variables explicitly (for example, checking for 'true', '1', or 'yes') rather than checking if the string is non-empty.

  4. MediumLink Unfurling Domain Allowlist Bypass via Block Kit JSON or Malformed URLs

    pkg/handler/conversations.go:254

    When SLACK_MCP_ADD_MESSAGE_UNFURLING is set to a comma-separated domain allowlist, the server attempts to prevent data exfiltration via Slack link unfurling by disabling unfurling if a message contains non-whitelisted domains. However, ConversationsAddMessageHandler only passes params.text to IsUnfurlingEnabled and does not inspect params.blocks. An attacker using prompt injection can place arbitrary external exfiltration URLs inside the blocks parameter while leaving text empty or benign, causing IsUnfurlingEnabled to return true and enabling link unfurling. Furthermore, IsUnfurlingEnabled in pkg/text/text_processor.go skips URLs that fail url.Parse and removes them before checking bare domains, allowing malformed URLs to bypass the check.

    Fix: Check both params.text and the serialized params.blocks content in IsUnfurlingEnabled, and fail closed (return false) if url.Parse returns an error on any matched URL.