Back to skill

Security audit

Agent Network

Security checks for vulnerabilities and agentic risk

Overview

This skill provides the advertised local multi-agent chat, task, and voting system, but it lacks access controls, so any caller with package access can impersonate agents and read, alter, or delete shared collaboration records.

Install only for trusted, local experimentation or single-operator workflows. Do not use it as a security boundary between independent agents or teams until it adds authentication, group membership checks, role-based authorization, audit logging, scoped reads, and safer deletion/recovery controls. Treat webhook and state-persistence examples as patterns that need hardening before use with sensitive content.

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

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/agent_network/coordinator.py:94
Finding

Unauthenticated Agent Impersonation and Administrative Operations

Content
View full analysis
bool: """Register an Agent with the coordinator.""" agent = AgentManager.get_by_id(agent_id) if not agent: print(f"[Coordinator] Agent {agent_id} does not exist") return False AgentManager.go_online(agent_id) session = AgentSession(agent=agent, handler=message_handler) self.sessions[agent_id] = session if message_handler: if agent_id not in self.message_handlers: self.message_handlers[agent_id] = [] self.message_handlers[agent_id].append(message_handler) print(f"[Coordinator] Agent '{agent.name}' registered and online") self.broadcast_system_message(f"Agent '{agent.name}' is online") return True ``` The CLI likewise selects an identity solely by list position: ```python idx = int(choice) - 1 if 0 <= idx < len(agents): self.current_agent = agents[idx] AgentManager.go_online(self.current_agent.id) ``` ### Technical Analysis The system treats a caller-supplied `agent_id` as proof of identity. There is no credential, session token, API key, cryptographic signature, or authenticated principal associated with the requested agent. Registration immediately creates an active session and marks that identity online. The exported `AgentManager` methods also accept arbitrary agent IDs for status changes and deletion. Consequently, possession or discovery of an integer ID is sufficient to act as another agent. Because messages, tasks, and votes rely on caller-supplied agent IDs, this defect compromises attribution throughout the application rather than affecting ...[truncated 817 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/agent_network/message_manager.py:88
Finding

Group Membership Is Not Enforced for Message Access or Routing

Content
View full analysis
Optional[Message]: """Send a message.""" mentions = MessageManager.detect_mentions(content) if mentions and msg_type == "chat": msg_type = "mention" msg_id = db.insert( """INSERT INTO messages (group_id, from_agent_id, to_agent_id, content, type, reply_to, created_at) VALUES (?, ?, ?, ?, ?, ?, ?)""", (group_id, from_agent_id, to_agent_id, content, msg_type, reply_to, datetime.now().isoformat()) ) for mentioned_agent in mentions: MessageManager.create_inbox_notification(mentioned_agent.id, msg_id) if to_agent_id: MessageManager.create_inbox_notification(to_agent_id, msg_id) return MessageManager.get_by_id(msg_id) ``` Group history is returned solely by group ID: ```python @staticmethod def get_group_messages(group_id: int, limit: int = 50, offset: int = 0) -> List[Message]: rows = db.fetch_all( """SELECT m.*, fa.name as from_agent_name, ta.name as to_agent_name, g.name as group_name FROM messages m LEFT JOIN agents fa ON m.from_agent_id = fa.id LEFT JOIN agents ta ON m.to_agent_id = ta.id LEFT JOIN groups g ON m.group_id = g.id WHERE m.group_id = ? ORDER BY m.created_at DESC LIMIT ? OFFSET ?""", (group_id, limit, offset) ...[truncated 1674 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/agent_network/group_manager.py:177
Finding

Unrestricted Group Administration and Ownership Transfer

Content
View full analysis
bool: """Update group information.""" updates = [] params = [] if name: updates.append("name = ?") params.append(name) if description: updates.append("description = ?") params.append(description) if not updates: return False params.append(group_id) affected = db.execute( f"UPDATE groups SET {', '.join(updates)} WHERE id = ?", tuple(params) ) return affected > 0 @staticmethod def delete(group_id: int) -> bool: """Delete a group.""" affected = db.execute("DELETE FROM groups WHERE id = ?", (group_id,)) return affected > 0 @staticmethod def transfer_ownership(group_id: int, new_owner_id: int) -> bool: """Transfer group ownership.""" if not GroupManager.is_member(group_id, new_owner_id): GroupManager.add_member(group_id, new_owner_id) affected = db.execute( "UPDATE groups SET owner_id = ? WHERE id = ?", (new_owner_id, group_id) ) return affected > 0 ``` ### Technical Analysis Privileged group operations accept only the target group and desired change. They do not accept or authenticate an acting principal and therefore cannot verify that the caller is the current owner or an administrator. Ownership transfer additionally adds the new owner to the group automatically. This permits a caller to install any agent as owner without consent from the current owner. Related `add_member()` and `remove_member()` functions similarly lack an authorization check. The dynamic SQL in `update()` uses a fixed internal field allowlist and parameterized values, so the primary issue is authorization rather than SQL ...[truncated 644 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/agent_network/task_manager.py:216
Finding

Unauthorized Task Creation, State Mutation, Comment Forgery, and Deletion

Content
View full analysis
bool: """Update task status.""" valid_status = ['pending', 'in_progress', 'completed', 'cancelled'] if new_status not in valid_status: print(f"Invalid status: {new_status}") return False task = TaskManager.get_by_id(task_db_id) if not task: return False completed_at = datetime.now().isoformat() if new_status == 'completed' else None affected = db.execute( "UPDATE tasks SET status = ?, completed_at = ? WHERE id = ?", (new_status, completed_at, task_db_id) ) if affected > 0: comment_text = f"Status changed to: {new_status}" if comment: comment_text += f" | Note: {comment}" TaskManager.add_comment(task_db_id, updater_id, comment_text) MessageManager.send_message( from_agent_id=updater_id, content=f"Task {task.task_id} status updated: {new_status}", group_id=task.group_id, to_agent_id=task.assignee_id if updater_id != task.assignee_id else task.assigner_id, msg_type="task_complete" if new_status == 'completed' else "chat" ) return True return False @staticmethod def add_comment(task_db_id: int, agent_id: int, comment: str) -> bool: try: db.execute( "INSERT INTO task_comments (task_id, agent_id, comment, created_at) VALUES (?, ?, ?, ?)", (task_db_id, agent_id, comment, datetime.now().isoformat()) ) return True except Exception as e: print(f"Failed to add comment: {e}") return False @staticmethod def delete(task ...[truncated 1388 chars]
Remediation
View remediation

T05 · Unauthorized Access and Privilege Escalation

Error
Location
scripts/agent_network/decision_manager.py:215
Finding

Decision Vote Inflation and Unauthorized Decision Control

Content
View full analysis
bool: valid_status = ['proposed', 'discussing', 'approved', 'rejected', 'implemented'] if new_status not in valid_status: return False decision = DecisionManager.get_by_id(decision_db_id) if not decision: return False affected = db.execute( "UPDATE decisions SET status = ?, decided_at = ? WHERE id = ?", (new_status, decided_at, decision_db_id) ) ``` ### Technical Analysis When an existing voter changes or resubmits a vote, the vote row is updated but the previous aggregate is never decremented. The selected aggregate is then incremented unconditionally. A single voter can therefore increase `votes_for` or `votes_against` repeatedly while only one vote row exist ...[truncated 979 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/ADVANCED.md:52
Finding

Unrestricted Webhook Destinations Can Disclose Messages and Enable SSRF

Content
View full analysis
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Warning
Location
references/ADVANCED.md:320
Finding

Path Traversal in Documented Agent State Persistence

Content
View full analysis
Remediation
View remediation
Vulnerability Patterns
  • Prompt InjectionInstruction Override, Hidden Instructions, Exfiltration Commands
  • Data ExfiltrationExternal Transmission, Env Variable Harvesting, File System Enumeration
  • Rogue AgentSelf-Modification, Session Persistence
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (27)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

A second independent description-behavior mismatch finding indicates the skill may overstate collaboration, messaging, and decision features relative to what is actually present. Overclaiming functionality can mask the true operational model and data flows, causing users to rely on nonexistent controls or to miss narrower-but-stateful behaviors such as persistent registry management.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

A second independent description-behavior mismatch finding indicates the skill may overstate collaboration, messaging, and decision features relative to what is actually present. Overclaiming functionality can mask the true operational model and data flows, causing users to rely on nonexistent controls or to miss narrower-but-stateful behaviors such as persistent registry management.

Content

No source excerpt is available for this finding.

os.system() or os exec-family call

High
Category
Dangerous Code Execution
Confidence
85% confidence
Finding

os.system() and os exec-family calls run shell commands with the process's full privileges, enabling arbitrary command execution.

Content

Scanner excerpt · scripts/cli.py (reported line 49)May include surrounding context.

python
def clear_screen(self):
        """清屏"""
        os.system('clear' if os.name == 'posix' else 'cls')
    
    def print_header(self, title: str):
        """打印标题"""

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
89% confidence
Finding

The skill advertises executable usage patterns and references local Python scripts/CLI, but does not declare any explicit tool scope or permissions despite implying file and shell capabilities. This creates a trust and containment gap: an agent or reviewer cannot easily determine what the skill may access or execute, increasing the chance of unintended file reads or command execution in environments that honor skill metadata for sandboxing.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The skill stores messages, tasks, votes, and inbox data in SQLite, but the description does not prominently warn about this persistence or its privacy implications. In a multi-agent setting, silent local retention of potentially sensitive coordination data can expose internal prompts, decisions, assignments, and operational metadata to later unauthorized access or accidental disclosure.

Content

No source excerpt is available for this finding.

Ssd 3

Medium
Category
Not specified by scanner
Confidence
96% confidence
Finding

This example forwards full plain-language message content and surrounding context to an external service on any mention trigger. Because the skill is specifically designed for structured multi-agent coordination, messages are likely to contain sensitive operational, business, or user-derived information, making this a meaningful exfiltration pattern.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
94% confidence
Finding

The webhook example sends raw message content, sender identity, timestamp, and group metadata to an external URL whenever a mention appears. In a multi-agent collaboration system, messages may contain sensitive prompts, task details, or user-derived data, so documenting this pattern without explicit minimization or warning creates a real data disclosure risk.

Content

No source excerpt is available for this finding.

External Transmission

Medium
Category
Data Exfiltration
Confidence
95% confidence
Finding

The direct requests.post call transmits collected message data to an external endpoint. Although the code uses HTTPS in the example, it still creates an outbound data transfer path that can leak sensitive collaboration content if users copy the pattern without safeguards.

Content

Scanner excerpt · references/ADVANCED.md (reported line 79)May include surrounding context.

md
}
            
            try:
                requests.post(self.webhook_url, json=payload, timeout=5)
            except Exception as e:
                print(f"Webhook failed: {e}")

Session Persistence

Medium
Category
Rogue Agent
Confidence
80% confidence
Finding

Skill establishes unauthorized persistence across sessions via cron jobs, startup scripts, or state files. Session persistence allows an attacker to maintain access beyond the current interaction.

Content

Scanner excerpt · references/ADVANCED.md (reported line 273)May include surrounding context.

md
if not agent:
            return
        
        # Create task for tomorrow morning
        tomorrow = (datetime.now() + timedelta(days=1)).strftime("%Y-%m-%d")
        
        task = TaskManager.create(

Ssd 3

Medium
Category
Not specified by scanner
Confidence
88% confidence
Finding

The persistence example encourages storing agent status, activity timestamps, and task context on disk in JSON files without discussing access controls, encryption, retention, or data minimization. In this skill context, persisted task state can easily include sensitive prompts, user requests, or internal workflow details, so insecure local retention creates a real confidentiality risk.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The delete method performs an irreversible removal of an agent record from the database, but the code provides no confirmation prompt, logging, print statement, or warning comment/docstring beyond the terse method name. For a code file, destructive operations should include some visible disclosure unless clearly covered elsewhere, which is not evident in this file.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

The delete method performs a destructive database deletion of a decision record, but there is no confirmation prompt, logging, print statement, or explanatory comment warning the user that the operation is irreversible. In this file, the deletion action is silent and not accompanied by visible disclosure.

Content

No source excerpt is available for this finding.

Missing User Warnings

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The delete method removes task records from the database, which is an irreversible operation in this code path. While the docstring says '删除任务', there is no confirmation prompt, user-facing log, or other disclosure around the destructive action in the implementation shown.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
92% confidence
Finding

This code file contains user-facing natural-language strings entirely in Chinese, starting with the module description and continuing throughout the CLI. Under the policy, forcing a specific language without user opt-in is a natural-language policy violation unless the locale restriction is explicitly documented and justified, which is not present here.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
90% confidence
Finding

The task view fetches all tasks via TaskManager.get_all() and displays them to any logged-in agent, even though a collaboration tool should generally scope visibility to the current user or authorized group context. This can leak cross-group task titles, descriptions, assignees, and metadata, creating an information disclosure issue in a multi-agent environment.

Content

No source excerpt is available for this finding.

Description-Behavior Mismatch

Medium
Category
Not specified by scanner
Confidence
93% confidence
Finding

The decision view calls DecisionManager.get_all() and renders global decisions regardless of the current agent's group membership or collaboration context. In a multi-agent coordination system, this exposes potentially sensitive planning and voting information across unrelated groups, which is an authorization and data-segregation failure.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Medium
Category
Not specified by scanner
Confidence
95% confidence
Finding

This code file contains user-facing docstrings, prompts, and printed instructions entirely in Chinese, including the main demo guidance and error/cancellation messages. The file does not indicate that the skill is region-specific or provide any user opt-in for language/locale, which can violate language choice policy.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
79% confidence
Finding

The guide repeatedly uses Chinese-only agent names such as "小邢", "小金", and later "老邢" in example instructions, which implicitly fixes the examples to a specific language context. There is no note that these are merely placeholders or that users may substitute names appropriate to their locale.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
95% confidence
Finding

This SQL file contains natural-language comments such as Chinese descriptions for tables and fields, but there is no indication that Chinese is an optional or justified locale requirement. Under the policy, forcing a specific language without user opt-in is a natural-language policy concern applicable to all file types.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
82% confidence
Finding

The default agent roster uses fixed Chinese display names in string literals, with no indication that users can choose or override the language/locale. This may conflict with a policy requiring language choice or user opt-in rather than imposing a specific locale by default.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
85% confidence
Finding

The module's human-facing documentation and printed messages are written only in Chinese, and the runtime output shown in this file likewise assumes that locale. Under the language/locale policy, forcing a single language without opt-in can be a policy concern when no user choice or justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
93% confidence
Finding

This Python file contains natural-language descriptions and runtime print messages in Chinese, establishing a fixed language for operator interaction. The file does not offer any opt-in language selection or indicate that the skill is intentionally limited to a Chinese-speaking environment, which matches the locale-policy violation criteria.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

This code file contains user-facing natural-language documentation and warning text exclusively in Chinese, including the module description and printed warning. Under the policy rule, forcing a specific language without opt-in can be a locale/language policy violation when no alternative language choice or justification is provided.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
87% confidence
Finding

User-visible messages, prompts, and module descriptions throughout the file are written exclusively in Chinese, including status messages and voting notifications. This can violate language/locale policy when the skill does not offer a language choice, opt-in, or documented locale restriction.

Content

No source excerpt is available for this finding.

Natural-Language Policy Violations

Low
Category
Not specified by scanner
Confidence
90% confidence
Finding

The module docstring is written entirely in Chinese, which imposes a language choice in natural-language content embedded in the skill. The file does not indicate that the language is optional, configurable, or justified as region-specific.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.