Back to skill

Security audit

Cloud Architecture Diagrams

Security checks for vulnerabilities and agentic risk

Overview

The skill is a coherent cloud diagram generator, but it has under-scoped URL fetching and icon-pack import code that could expose local/internal resources or delete directories if misused.

Install only if you are comfortable running it on trusted diagram specs. Do not let untrusted input set icon_url, avoid arbitrary remote icon URLs, and do not run the icon-pack import/refresh scripts with provider or source values supplied by someone else. Prefer using the bundled offline icons and run maintenance commands only in a disposable or version-controlled copy of the skill.

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 (2)

T09 · Insecure Skill Coding Practices

Error
Location
scripts/build_diagram.py:106
Finding

Arbitrary URL Access Enables Local File Disclosure and Server-Side Request Forgery

Content
View full analysis
str | None: """Return raw SVG text (cached on disk).""" cache.mkdir(parents=True, exist_ok=True) fname = re.sub(r"[^A-Za-z0-9._-]", "_", url.split("/")[-1]) f = cache / fname try: if not f.exists(): safe = urllib.parse.quote(url, safe=":/?#[]@!$&'()*+,;=~") data = urllib.request.urlopen(safe, timeout=30).read() f.write_bytes(data) return f.read_text("utf-8", "replace") except Exception as e: print(f" ! could not fetch {url}: {e}", file=sys.stderr) return None ``` ```python def resolve_icon(node: dict, cache: Path, providers=None) -> tuple[str | None, str]: """Return (raw_svg_or_None, note). Honors node['icon_url'] if given. A node may set its own 'provider' to override the diagram default.""" if node.get("icon_url"): return fetch_svg(node["icon_url"], cache), node["icon_url"] ``` ### Technical Analysis The diagram specification directly controls the `icon_url` value. That value is passed to `urllib.request.urlopen()` without validating: - The URL scheme - The destination hostname or IP address - Redirect destinations - Loopback, private, or link-local address ranges - The response content type - Whether the response is actually an SVG - The maximum response size `urllib.request.urlopen()` supports schemes other than HTTPS, including `file:`. Consequently, an untrusted diagram specification can cause the process to read a local file accessible to the current user. The resulting bytes are cached, decoded as text, and subsequently embedded into generated Excalidraw or draw.io output. HTTP and HTTPS destinations are similarly unrestricted. This creates a server-side request forger ...[truncated 2394 chars]
Remediation
View remediation

T09 · Insecure Skill Coding Practices

Error
Location
scripts/add_icon_pack.py:176
Finding

Path Traversal in Provider Identifier Enables Recursive Directory Deletion

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
  • Trigger AbuseOverly Broad Trigger, Shadow Command Trigger, Keyword Baiting Trigger
  • Taint TrackingDirect Taint Flow, Variable-Mediated Taint Flow, Credential Exfiltration Chain
  • MCP Least PrivilegeUnderdeclared Capability, Wildcard Permission, Missing Permission Declaration
Findings (12)

Tp4

High
Category
MCP Tool Poisoning
Confidence
95% confidence
Finding

This finding highlights that the skill can download remote icon assets and modify local asset stores and metadata, which are materially different capabilities from simple diagram creation. In context, that makes the skill more dangerous because its primary use case does not inherently require broad maintenance operations, so these extra behaviors expand attack surface without clear user expectation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
99% confidence
Finding

This finding highlights that the skill can download remote icon assets and modify local asset stores and metadata, which are materially different capabilities from simple diagram creation. In context, that makes the skill more dangerous because its primary use case does not inherently require broad maintenance operations, so these extra behaviors expand attack surface without clear user expectation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
97% confidence
Finding

This finding highlights that the skill can download remote icon assets and modify local asset stores and metadata, which are materially different capabilities from simple diagram creation. In context, that makes the skill more dangerous because its primary use case does not inherently require broad maintenance operations, so these extra behaviors expand attack surface without clear user expectation.

Content

No source excerpt is available for this finding.

Tp4

High
Category
MCP Tool Poisoning
Confidence
94% confidence
Finding

This finding highlights that the skill can download remote icon assets and modify local asset stores and metadata, which are materially different capabilities from simple diagram creation. In context, that makes the skill more dangerous because its primary use case does not inherently require broad maintenance operations, so these extra behaviors expand attack surface without clear user expectation.

Content

No source excerpt is available for this finding.

Hidden Instructions

High
Category
Prompt Injection
Confidence
60% confidence
Finding

Hidden instructions were detected in comments or invisible text. These could contain malicious directives. Manual review is recommended.

Content

Scanner excerpt · assets/icons/azure/02390-icon-service-Azure-SQL.svg (reported line 1)May include surrounding context.

text
<svg xmlns="http://www.w3.org/2000/svg" width="18" height="18" viewBox="0 0 18 18"><defs><linearGradient id="f67d1585-6164-4ad0-b2dd-f9cc59b2969f" x1="9.908" y1="15.943" x2="7.516" y2="2.383" gradientUnits="userSpaceOnUse"><stop offset="0.15" stop-color="#0078d4" /><stop offset="0.8" stop-color="#5ea0ef" /><stop offset="1" stop-color="#83b9f9" /></linearGradient></defs><g id="a4fd1868-54fe-4ca6-8ff6-3b01866dc27b"><path d="M14.49,7.15A5.147,5.147,0,0,0,9.24,2.164,5.272,5.272,0,0,0,4.216,5.653,4.869,4.869,0,0,0,0,10.4a4.946,4.946,0,0,0,5.068,4.814H13.82A4.292,4.292,0,0,0,18,11.127,4.105,4.105,0,0,0,14.49,7.15Z" fill="url(#f67d1585-6164-4ad0-b2dd-f9cc59b2969f)" /><path d="M12.9,11.4V8H12v4.13h2.46V11.4ZM5.76,9.73a1.825,1.825,0,0,1-.51-.31.441.441,0,0,1-.12-.32.342.342,0,0,1,.15-.3.683.683,0,0,1,.42-.12,1.62,1.62,0,0,1,1,.29V8.11a2.58,2.58,0,0,0-1-.16,1.641,1.641,0,0,0-1.09.34,1.08,1.08,0,0,0-.42.89c0,.51.32.91,1,1.21a2.907,2.907,0,0,1,.62.36.419.419,0,0,1,.15.32.381.381,0,0,1-.16.31.806.806,0,0,1-.45.11,1.66,1.66,0,0,1-1.09-.42V12a2.173,2.173,0,0,0,1.07.24,1.877,1.877,0,0,0,1.18-.33A1.08,1.08,0,0,0,6.84,11a1.048,1.048,0,0,0-.25-.7A2.425,2.425,0,0,0,5.76,9.73ZM11,11.32A2.191,2.191,0,0,0,11,9a1.808,1.808,0,0,0-.7-.75,2,2,0,0,0-1-.26,2.112,2.112,0,0,0-1.08.27A1.856,1.856,0,0,0,7.49,9a2.465,2.465,0,0,0-.26,1.14,2.256,2.256,0,0,0,.24,1,1.766,1.766,0,0,0,.69.74,2.056,2.056,0,0,0,1,.3l.86,1h1.21L10,12.08A1.79,1.79,0,0,0,11,11.32Zm-1-.25a.941.941,0,0,1-.76.35.916.916,0,0,1-.76-.36,1.523,1.523,0,0,1-.29-1,1.529,1.529,0,0,1,.29-1,1,1,0,0,1,.78-.37.869.869,0,0,1,.75.37,1.619,1.619,0,0,1,.27,1A1.459,1.459,0,0,1,10,11.07Z" fill="#f2f2f2" /></g>​
</svg>

Undeclared Tool Scope

Medium
Category
MCP Least Privilege
Confidence
82% confidence
Finding

The skill documentation describes commands that read local files, write output files, and in some cases fetch remote resources, but it declares no explicit tool or permission scope. That creates an avoidable least-privilege gap: an agent may be granted broader filesystem or network access than users expect, increasing the blast radius if the skill is misused or compromised.

Content

No source excerpt is available for this finding.

Tainted flow: 'prims' from sys.stdin.read (line 531, user input) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/build_diagram.py (reported line 536)May include surrounding context.

python
written = []
    if args.only in (None, "excalidraw"):
        out = Path(f"{args.out_prefix}.excalidraw")
        out.write_text(to_excalidraw(prims))
        written.append(str(out))
    if args.only in (None, "drawio"):
        out = Path(f"{args.out_prefix}.drawio")

Tainted flow: 'prims' from sys.stdin.read (line 531, user input) → pathlib.Path.write_text (file write)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/build_diagram.py (reported line 540)May include surrounding context.

python
written.append(str(out))
    if args.only in (None, "drawio"):
        out = Path(f"{args.out_prefix}.drawio")
        out.write_text(to_drawio(prims))
        written.append(str(out))

    print("Wrote: " + ", ".join(written))

Tainted flow: 'url' from urllib.request.urlopen (line 45, network input) → urllib.request.urlopen (network output)

Medium
Category
Data Flow
Confidence
65% confidence
Finding

Data from a source is assigned to a variable that is later passed to a sink, creating a variable-mediated taint flow.

Content

Scanner excerpt · scripts/build_icon_index.py (reported line 46)May include surrounding context.

python
if not m:
        sys.exit("Could not locate the JS bundle in index.html (site layout changed?)")
    url = SITE + m.group(1)
    return urllib.request.urlopen(url, timeout=60).read().decode("utf-8", "replace")


def humanize(filename: str) -> str:

Vague Triggers

Low
Category
Not specified by scanner
Confidence
78% confidence
Finding

This is a manifest-type file, so vague-trigger checks apply. The file provides only a broad title and provider without any explicit activation conditions, exclusions, or scope constraints, which can leave it unclear when the skill should or should not be invoked.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
92% confidence
Finding

The script performs remote fetches for user-supplied icon_url values and for matched icon resources without any explicit trust restrictions, allowlist, or user warning. In an agent context, this creates SSRF-style risk and unintended outbound requests to attacker-controlled hosts, potentially exposing internal network reachability, metadata endpoints, or sensitive request context via server-side fetches and cached content.

Content

No source excerpt is available for this finding.

Missing User Warnings

Low
Category
Not specified by scanner
Confidence
84% confidence
Finding

This Python file performs HTTP requests to download remote SVGs from URLs in the index and writes them to disk, but the only user-visible messaging is a generic fetch progress print. There is no explicit warning that running the script will contact external servers and persist downloaded content locally.

Content

No source excerpt is available for this finding.

Static analysis

No suspicious patterns detected.