Back to skill

Security audit

Slack Hub Skill

Security checks for vulnerabilities and agentic risk

Overview

This Slack skill mostly matches its stated purpose, but its channel-listing command requests private-channel metadata even though the documentation says it lists public channels only.

Review this skill before installing. Use a Slack bot token with the narrowest scopes and channel memberships possible, and avoid running the list action unless private-channel metadata exposure is acceptable. Treat send and search results as sensitive actions: verify message targets and content, and avoid sharing search results outside their intended audience.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • 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
Findings (1)

T05 · Unauthorized Access and Privilege Escalation

Warning
Location
slack_hub.py:35
Finding

Private Channel Enumeration Exceeds the Declared Scope

Content
View full analysis

Vulnerability Details

File Location: slack_hub.py:35-36
Vulnerability Type: Least-privilege violation through unnecessary private-channel enumeration
Risk Level: Medium

Vulnerable Code

python
if args.action == "list":
    print(json.dumps(hub._call("conversations.list", {"types": "public_channel,private_channel"})))

Technical Analysis

The documented slack_list_channels functionality promises to list public channels only. However, the implementation requests both public_channel and private_channel objects from Slack.

Slack still applies the bot token's OAuth scopes and membership restrictions, so this code does not bypass Slack's access controls. Nevertheless, it requests private-channel metadata beyond the Skill's declared operational need. It also serializes and prints the complete API response, potentially placing accessible private-channel names, identifiers, and related metadata into terminal output, logs, or downstream Agent context.

The fixed network destination and Bearer-token transmission elsewhere in the implementation are necessary for Slack API authentication and do not indicate credential exfiltration. The issue is specifically the unnecessarily broad channel type requested by this operation.

Attack Path

  1. A user or Agent invokes the list action expecting the documented public-channel listing.
  2. The Skill sends a conversations.list request containing types: "public_channel,private_channel".
  3. Slack returns public channels and any private-channel metadata available under the bot token's granted scopes and memberships.
  4. The Skill prints the complete response.
  5. Private-channel metadata may consequently enter console history, application logs, captured tool output, or downstream Agent context without the user explicitly requesting private-channel access.

Impact Assessment

The maximum accessible scope remains bounded by the Slack bot token's OAuth ...[truncated 434 chars]

Remediation
View remediation

Remediation Suggestions

  1. Restrict the default listing operation to public channels:

    python
    if args.action == "list":
        print(json.dumps(
            hub._call("conversations.list", {"types": "public_channel"})
        ))
    
  2. If private-channel enumeration is a legitimate requirement, implement it as a separate, explicitly named action and document the behavior and required Slack scopes.

  3. Require explicit user confirmation before requesting or displaying private-channel metadata.

  4. Return only fields required by the caller rather than printing the complete Slack API response.

  5. Review the bot's OAuth scopes and channel memberships, removing any permissions not essential to messaging, workspace search, and public-channel listing.

  6. Prevent sensitive response data from being retained in verbose logs, terminal history, or unrelated Agent context.

Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Privilege EscalationExcessive Permissions, Sudo/Root Execution, Credential Access
  • Supply ChainUnpinned Dependencies, External Script Fetching, Obfuscated Code
Findings (6)

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill documents a message-sending function without warning that posted messages may disclose information to channels or users, trigger notifications, and be difficult or impossible to fully retract. In agent-driven workflows, this creates a real risk of accidental outbound disclosure or unintended actions if the destination or content is wrong.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The skill exposes a workspace search capability but does not warn users that searches may return sensitive messages or files from across Slack, depending on the bot's granted scopes and channel access. This omission can lead users or downstream agents to overuse search without understanding the privacy and data-exposure implications, increasing the risk of unintended disclosure.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
80% confidence
Finding

Data is being sent to an external URL. This could be legitimate telemetry or data exfiltration. Manual review is recommended.

Content

Scanner excerpt · slack_hub.py (reported line 16)May include surrounding context.

python
"Authorization": f"Bearer {self.token}",
            "Content-Type": "application/json; charset=utf-8"
        }
        response = requests.post(f"{self.base_url}/{endpoint}", headers=headers, json=data)
        return response.json()

    def send(self, target, message, thread_ts=None):

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
84% confidence
Finding

The script exposes workspace enumeration via conversations.list without any evident restriction, stated business need, or scoping controls. In an agent/skill context, listing public and private channels can leak internal workspace structure and sensitive metadata that may aid reconnaissance or enable broader misuse of the Slack bot token.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The CLI allows sending messages and listing channels immediately based on arguments, with no user-facing confirmation, policy check, or guardrail around sensitive Slack actions. In an agent setting, this can enable unintended message posting, spam, disclosure into the wrong channel, or silent reconnaissance using the bot token.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
80% confidence
Finding

The code reads a sensitive credential from the SLACK_BOT_TOKEN environment variable, but there is no user-facing disclosure, comment, or documentation indicating that the skill depends on and accesses this secret. This can surprise users in environments where credential use should be explicit.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.