Back to skill

Security audit

multi-agent-orchestrator

Security checks for vulnerabilities and agentic risk

Overview

This skill is not clearly malicious, but it overstates what it does and writes predictable files through an external renderer without enough scoping.

Review before installing. Use this only in a disposable or tightly scoped workspace, provide a trusted output directory, and do not rely on the documented CLI behavior unless the script is fixed to parse arguments and constrain output paths.

Vulnerability Patterns
  • 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
  • Embedded Malicious CodeShips malicious scripts inside the skill and executes them locally
Findings (1)

T09 · Insecure Skill Coding Practices

Warning
Location
scripts/orchestrate_and_visualize.py:17
Finding

Arbitrary File Overwrite Through Unsafe Output Handling

Content
View full analysis

Vulnerability Details

File Location: scripts/orchestrate_and_visualize.py, lines 17–19 and 37–39
Vulnerability Type: Predictable output paths, unsafe file overwrite, and symlink following
Risk Level: Medium

Vulnerable Code

python
org_chart_mermaid_path = f"{output_dir}/org_chart.mmd"
with open(org_chart_mermaid_path, "w") as f:
    f.write(org_chart_mermaid)
python
swimlane_mermaid_path = f"{output_dir}/swimlane.mmd"
with open(swimlane_mermaid_path, "w") as f:
    f.write(swimlane_mermaid)

Technical Analysis

The function accepts a caller-controlled output_dir and writes to the predictable filenames org_chart.mmd and swimlane.mmd using Python's truncating "w" mode. It does not verify whether either destination already exists, is a symbolic link, is a regular file, or resolves inside an approved output directory.

Python follows symbolic links when open() is used this way. Consequently, an attacker who can prepare the selected output directory can create one of the expected filenames as a symbolic link to another file. When the skill runs, the linked destination is opened, truncated, and replaced with generated Mermaid content.

Attack Path

  1. The attacker identifies an execution in which the skill will use an output directory that the attacker can modify.
  2. The attacker creates org_chart.mmd or swimlane.mmd in that directory as a symbolic link to a target file writable by the account running the skill.
  3. A user or more privileged process invokes orchestrate_and_visualize() with that directory.
  4. The corresponding open(..., "w") call follows the symbolic link and truncates the target.
  5. Generated Mermaid content is written into the target, corrupting or replacing its prior contents.

Exploitation requires the attacker to control or prepare the output directory and the executing account to have write access to the linked target.

Impact Asses

...[truncated 600 chars]

Remediation
View remediation

Remediation Suggestions

  1. Resolve the requested output directory to a canonical path and ensure it is within an explicitly approved base directory.
  2. Create the output directory with restrictive permissions and do not use a shared or attacker-writable directory for privileged execution.
  3. Reject existing symbolic links and non-regular destination files.
  4. Create new files atomically with exclusive and no-follow semantics, such as os.open() with O_CREAT | O_EXCL | O_NOFOLLOW, where supported.
  5. If overwriting is required, make it an explicit caller option and safely verify the destination before replacement.
  6. Prefer writing to a securely created temporary file in the same trusted directory and atomically replacing a validated regular destination.
  7. Apply the same validation to generated PNG destinations passed to manus-render-diagram, because those paths are also predictable and handled by an external renderer.
Vulnerability Patterns
  • Excessive AgencyUnrestricted Tool Access, Autonomous Decision Making, Scope Creep
  • Behavioral ASTexec() Call, eval() Call, Dynamic Import
  • 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 (8)

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

The declared one-click multi-agent orchestration and visualization capabilities appear overstated relative to the underlying behavior, which static analysis suggests is limited or hardcoded. In this context, functionality inflation is security-relevant because it can conceal the true operational behavior of the skill, mislead orchestration systems, and cause operators to approve execution in environments they would not otherwise trust.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

The declared one-click multi-agent orchestration and visualization capabilities appear overstated relative to the underlying behavior, which static analysis suggests is limited or hardcoded. In this context, functionality inflation is security-relevant because it can conceal the true operational behavior of the skill, mislead orchestration systems, and cause operators to approve execution in environments they would not otherwise trust.

Content

No source excerpt is available for this finding.

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
84% confidence
Finding

The skill documentation declares executable scripts with file-writing, shell, and likely network-capable behavior, but it does not define any explicit tool scope or permissions boundaries. In an agent environment, this can lead to over-privileged execution where the skill is invoked with broader capabilities than necessary, increasing the blast radius if the scripts are unsafe or later modified.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

The code invokes an external renderer on Mermaid content derived from generated agent data, which may be influenced by untrusted prompt input. Although shell injection is avoided by using an argument list, passing attacker-influenced diagram content to an external binary expands the attack surface and could enable exploitation of the renderer, unsafe file access, or unexpected host-side effects if the renderer is vulnerable.

Content

Scanner excerpt · scripts/orchestrate_and_visualize.py (reported line 27)May include surrounding context.

python
print("Rendering organizational chart to PNG...")
    org_chart_png_path = f"{output_dir}/org_chart.png"
    try:
        subprocess.run(["manus-render-diagram", org_chart_mermaid_path, org_chart_png_path], check=True)
        print(f"Organizational chart rendered to {org_chart_png_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error rendering organizational chart: {e}")

Context-Inappropriate Capability

Medium
Category
Not specified by scanner
Confidence
91% confidence
Finding

The skill's stated purpose is orchestration and visualization, but it achieves visualization by executing a host-level external command on generated content. In this context, the capability is more dangerous because user prompts indirectly influence the rendered diagram, so a visualization feature becomes a path to interact with local executables and any vulnerabilities or side effects they carry.

Content

No source excerpt is available for this finding.

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
87% confidence
Finding

This call has the same risk pattern as the organizational chart rendering path: untrusted or model-generated Mermaid content is handed to an external rendering executable. Even without shell=True, this can be dangerous if the renderer processes directives, loads external resources, or contains parser vulnerabilities triggered by crafted input.

Content

Scanner excerpt · scripts/orchestrate_and_visualize.py (reported line 44)May include surrounding context.

python
print("Rendering swimlane diagram to PNG...")
    swimlane_png_path = f"{output_dir}/swimlane.png"
    try:
        subprocess.run(["manus-render-diagram", swimlane_mermaid_path, swimlane_png_path], check=True)
        print(f"Swimlane diagram rendered to {swimlane_png_path}")
    except subprocess.CalledProcessError as e:
        print(f"Error rendering swimlane diagram: {e}")

subprocess module call

Medium
Category
Dangerous Code Execution
Confidence
70% confidence
Finding

subprocess module calls execute external commands. Without careful input validation, this enables command injection.

Content

Scanner excerpt · scripts/orchestrate_and_visualize.py (reported line 63)May include surrounding context.

python
if __name__ == "__main__":
    # Example usage
    output_directory = "/home/ubuntu/multi_agent_orchestrator_output"
    subprocess.run(["mkdir", "-p", output_directory], check=True)

    print("\n--- Orchestrating Software Development Team ---")
    sd_results = orchestrate_and_visualize("Create a software development team for an e-commerce platform.", output_directory)

Context-Inappropriate Capability

Low
Category
Not specified by scanner
Confidence
86% confidence
Finding

The main block creates a host directory by invoking the system mkdir command. While writing output files is consistent with visualization, executing host-level filesystem commands is a separate capability not described in the manifest and is unnecessary given native Python alternatives.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.