Back to skill

Security audit

Channel Activity

Security checks for vulnerabilities and agentic risk

Overview

This skill provides useful multi-channel memory, but it can share stored conversation summaries across channels and identities without adequate access controls or consent safeguards.

Review before installing, especially in multi-user or multi-channel deployments. Use only with trusted users unless family sharing, cross-channel recall, automatic hooks, and long-term memory access are explicitly consented to and scoped. Pin the installer version, remove hard-coded import paths, isolate cache files per user or tenant, restrict file permissions, and avoid automatic prompt injection of memory records.

Vulnerability Patterns
  • Unauthorized Access and Privilege EscalationObtains permissions beyond the task's legitimate needs
  • Tool Hijacking and SpoofingModifies or replaces tools so legitimate-looking calls execute attacker logic
  • Insecure DependenciesIntroduces malicious components through unsafe dependency sources
  • Insecure Skill Coding PracticesFinds exploitable flaws such as hardcoded secrets or command injection
  • Skill Instruction HijackingAlters the agent's session goals or safety constraints when the skill loads
Findings (6)

T05 · Unauthorized Access and Privilege Escalation

Error
Location
channel_activity.py:49
Finding

Unauthenticated Family-Group Membership Enables Cross-User Memory Disclosure

Content
View full analysis
datetime.now() - timedelta(minutes=30): all_entries.append({ "identity": member_identity, "channel": channel, "time": entry["time"], "summary": entry["summary"], "from_family": True }) ``` ### Technical Analysis Family-group membership is managed through caller-supplied string identifiers. The code does not authenticate the caller, verify group ownership, request consent from the ...[truncated 1556 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
complete_context.py:236
Finding

Untrusted Stored Messages Are Injected Directly into Agent Context

Content
View full analysis
str: combined = [] if stm_entries: combined.append("[短期记忆 - 最近30分钟]") for entry in stm_entries: timestamp = entry.get('created_at', '') content = entry.get('content', '') channel = entry.get('channel', '') combined.append(f"- [{channel}] {timestamp}: {content}") combined.append("") if ltm_content: combined.append("[长期记忆 - 永久记忆]") combined.append(ltm_content) return "\n".join(combined) ``` The integration guide additionally recommends automatically calling the session hook before every session and injecting its result into the model context. ### Technical Analysis Message content and long-term-memory content are treated as trusted context even though they can originate from user-controlled chat messages or mutable local files. The implementation concatenates the content into a prompt-like string without: - Marking it as untrusted data. - Escaping instruction delimiters or control syntax. - Preventing the model from following instructions found in memory. - Applying provenance, authorization, or content-policy checks. - Separating data from higher-priority agent instructions. This creates a stored prompt-injection channel. Truncating a message does not neutralize instruction-like content because a short malicious instruction can remain fully effective. Automatic session-hook integration increases the risk because the malicious content can be inserted into unrelated sessions without an explicit retrieval request. ### Attack Path 1. An attacker submits a message on a monitored channel containing an instruction aimed at the ...[truncated 1054 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
short_term_memory.py:137
Finding

Optional User Filters Permit Enumeration of the Shared Memory Cache

Content
View full analysis
List[Dict[str, Any]]: results = [] now = time.time() for entry in reversed(self.entries): if entry.get('expires_at', 0) <= now: continue if channel and entry.get('channel') != channel: continue if user_id and entry.get('user_id') != user_id: continue results.append(entry) if len(results) >= limit: break return results ``` ```python def query(self, query_text: str, limit: int = 5) -> List[Dict[str, Any]]: results = [] query_lower = query_text.lower() now = time.time() for entry in reversed(self.entries): if entry.get('expires_at', 0) <= now: continue if query_lower in entry.get('content', '').lower(): results.append(entry) if len(results) >= limit: break return results ``` ### Technical Analysis The `read()` method treats `user_id` and `channel` as optional convenience filters rather than mandatory authorization scope. Calling `read()` without filters returns entries belonging to every user in the shared cache. The `query()` method is more permissive: it has no user or tenant scope at all and searches every unexpired entry. Returned records contain the complete stored content and associated metadata. A caller can also supply another user's identifier because the library does not authenticate or bind that identifier to the caller. Similar optional-filter behavior is present in `CompleteContext.get_complete_context()`. ### Attack Path 1. An attacker gains access to an application endpoint or plugin operation that exposes these methods. 2. The attacker calls `r ...[truncated 853 chars]
Remediation
View remediation

T07 · Tool Hijacking and Spoofing

Warning
Location
session_hook.py:6
Finding

Hard-Coded Import Precedence Path Allows Local Module Spoofing

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
channel_activity.py:33
Finding

Plaintext Memory Storage and Incomplete TTL Purging Retain Sensitive Data

Content
View full analysis
max_length: summary = message[:max_length] + "..." else: summary = message if identity not in self.data["identities"]: self.data["identities"][identity] = {} if channel not in self.data["identities"][identity]: self.data["identities"][identity][channel] = [] entry = { "time": now.isoformat(), "summary": summary, "user_id": user_id } self.data["identities"][identity][channel].append(entry) cutoff = now - timedelta(minutes=self.ttl_minutes) self.data["identities"][identity][channel] = [ e for e in self.data["identities"][identity][channel] if datetime.fromisoformat(e["time"]) > cutoff ] self._save() ``` ### Technical Analysis Message summaries and user identifiers are serialized to a plaintext JSON file. The write operation does not explicitly establish restrictive file permissions, encryption, or integrity protection. The advertised 30-minute TTL is not enforced as physical deletion across the entire cache. Cleanup in `record()` only processes the identity and channel currently receiving a new record. Inactive channels can retain expired entries on disk indefinitely. Retrieval methods filter expired records from output, but filtering does not erase the underlying plaintext data. Local users, backups, diagnostic tools, or compr ...[truncated 1070 chars]
Remediation
View remediation

T08 · Insecure Dependencies

Warning
Location
SKILL.md:14
Finding

Mutable Latest-Tag Installer Executes Unpinned Third-Party Code

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
  • MCP Tool PoisoningHidden Instructions, Unicode Deception, Parameter Description Injection
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
Findings (40)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The documented purpose is short-term channel memory, but the finding indicates undeclared local persistence, retention behavior differences, and long-term memory upgrade capability not disclosed in the description. This mismatch is dangerous because users and agent frameworks may authorize a low-risk transient memory skill while it actually stores data longer or more broadly than expected, increasing privacy and data handling risk.

Content

No source excerpt is available for this finding.

Context-Inappropriate Capability

High
Category
Not specified by scanner
Confidence
97% confidence
Finding

get_context_summary intentionally includes recent message summaries from other identities in the same family group whenever ai_decision is enabled, with no demonstrated consent, authorization, or policy check. This creates a direct cross-identity information disclosure path where private conversation summaries from one user can be surfaced to another user or channel context.

Content

No source excerpt is available for this finding.

Missing User Warnings

High
Category
Not specified by scanner
Confidence
98% confidence
Finding

The family-group sharing logic exposes summaries of other members' recent activity with only a comment claiming the AI can decide sharing, but no actual privacy safeguard or warning. In practice this means private content from one identity may be silently revealed in another identity's context, which is a serious confidentiality issue in a memory skill.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The recommended automatic hook injects session data into context before every conversation without any notice about collection, retention, or cross-channel reuse of user content. Automating this behavior increases the likelihood of silent privacy violations and unintended disclosure because the model receives data from other channels by default.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

These instructions normalize carrying user content from one channel directly into another channel's prompt and response flow. Because the transfer is automatic and happens at the prompt layer, it creates a natural-language exfiltration channel that can leak private information across otherwise separate conversations, especially if channels have different audiences, devices, or trust levels.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The example workflow shows the assistant disclosing what the user said in Feishu when asked from QQ, effectively endorsing cross-channel recall as normal behavior. In practice, this can reveal sensitive notes, personal data, or confidential business information to a different client, session, or observer without verifying whether disclosure is appropriate in the current context.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation explicitly describes retrieving recent activity from other channels and surfacing it in the current conversation, but provides no user consent, access control, or privacy warning. This creates a cross-channel data disclosure path where content shared in Feishu can be revealed in QQ (and vice versa) merely based on channel context rather than explicit user authorization.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The README explicitly describes collecting and caching cross-channel user content together with persistent user IDs, and even promoting short-term entries into long-term memory, but provides no privacy notice, retention guidance, access-control expectations, or consent considerations. In a multi-channel memory skill, that omission is security-relevant because it can lead operators to deploy cross-context data aggregation and retention in ways that expose personal data, enable unintended profiling, or violate least-privilege and data-minimization principles.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

The skill explicitly stores per-channel message summaries and user_id values, then enables retrieval across channels, but the README provides no consent, minimization, access-control, or privacy-boundary guidance. This creates a real risk of unintended disclosure of user activity and identifiers between contexts that users may reasonably expect to remain separate.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
70% confidence
Finding

npx commands without a version suffix (e.g. @1.0.0) create a rug-pull risk if the upstream server is compromised and publishes a malicious update.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The examples instruct the assistant to restate content said in one channel inside another channel in plain language, which directly normalizes cross-context disclosure of potentially sensitive conversation data. In a multi-channel assistant, this is especially dangerous because channel separation often implies different audiences, devices, or trust levels, so a benign memory feature can become a privacy leak.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
80% confidence
Finding

The skill advertises installable code and its documented behavior implies stateful memory, but the manifest declares no explicit tool scope or permissions despite detected file read/write capability. This creates a transparency and least-privilege problem: an agent or operator may grant or run the skill without understanding that it can persist or access local data.

Content

No source excerpt is available for this finding.

Rp1

Medium
Category
MCP Rug Pull
Confidence
93% confidence
Finding

Using npx clawhub@latest install channel-activity pulls the latest package version at install time, which is a supply-chain risk because future compromised or incompatible releases could be executed automatically. In a skill installation path, this is especially risky because users may treat the command as trusted setup guidance and run unreviewed code.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The documentation explicitly describes recording what users say in one channel, retaining it for 30 minutes, and then promoting expired content into permanent memory without any consent, minimization, or disclosure controls. This creates a real privacy and data-governance risk because sensitive content shared in one context may be silently persisted and later exposed in another context.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
97% confidence
Finding

These instructions describe retaining user messages across channels and sessions and automatically converting temporary memory into permanent memory. In the context of an AI assistant, that behavior is dangerous because it breaks contextual boundaries and can cause unauthorized long-term storage of sensitive information that users may have only intended for a single channel or short-lived interaction.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
98% confidence
Finding

The example workflow shows the assistant recalling a statement from Feishu and surfacing it in QQ as conversation context. That is a concrete cross-channel data disclosure pattern: information provided in one platform can be revealed in another without verifying identity, consent, or whether the destination channel should receive the data.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The guidance instructs the AI to include long-term memory and channel activity summaries in every reply context. This broad default inclusion increases the chance of prompt-context overexposure, unnecessary retention, and accidental disclosure of unrelated or sensitive information to users, tools, or downstream model calls.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

The skill writes conversation summaries to a persistent JSON file on disk without any notice, retention confirmation beyond code comments, or protection mechanism shown here. Persisting cross-channel activity data increases exposure to local compromise, accidental reuse, forensic recovery, or misuse by other components that can read the file.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The code introduces family-group membership and cross-identity grouping even though the skill is described as short-term channel activity memory. That hidden expansion of scope materially changes the trust boundary: data associated with one identity may later be linked to a broader sharing domain than a user would reasonably expect.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The manifest describes the skill as 'Multi-channel short-term memory for AI assistants', which implies transient recording and retrieval of recent context. Beyond that, the code adds explicit update, delete, search, and full clear capabilities over stored memories, expanding behavior from simple short-term memory into broader memory management.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
87% confidence
Finding

This Python file contains user-facing natural-language documentation and runtime messages entirely in Chinese, including the module description and status output. Because the skill does not offer any language/locale opt-in or explain that it is intentionally region-specific, it creates a language-policy concern under the locale-choice rule.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The skill advertises multi-channel short-term memory but its main context API also loads and returns long-term memory from MEMORY.md. This creates a scope mismatch that can expose durable, potentially sensitive data to callers who expect only time-limited channel activity, increasing the chance of unintended data disclosure across sessions or users.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The query interface searches long-term memory in addition to short-term entries, despite the skill being presented as short-term channel activity memory. This broadens retrieval scope silently and may let a user discover sensitive persistent information through simple keyword searches that were expected to be limited to recent ephemeral context.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

This JSON file contains user-facing natural-language summaries such as "项目 A 需要处理", "下午 3 点开会", and "妈妈去买菜了" in Chinese only. Under the policy, forcing a specific language without user opt-in or a documented locale justification is a natural-language policy violation.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

The cache stores a persistent user identifier together with task-specific message content, which constitutes sensitive conversational and identity-linked data retention. In a multi-channel memory component, this increases privacy risk because anyone with access to the cache can correlate a specific user to their requests, and the upgrade_to_long_term setting makes the context more dangerous by potentially extending retention beyond the short-term purpose.

Content

No source excerpt is available for this finding.