SkillTotal

Is Drawio Skill safe?

No malicious indicators - review capabilities before installing
Notable — review in context (capabilities are not malware):
  • Python shell/command execution
  • Python network egress
  • Python filesystem read

repo is an AI directory analyzed by SkillTotal's deterministic static scanner. The scan found no malicious indicators, though 4 risky constructs are reported for review. It can: filesystem read, filesystem write, network egress and shell execution — capabilities are what the code can do, not a verdict on intent. Risk score 0/100 (low).

repo

directory · https://github.com/Agents365-ai/drawio-skill
LOW
0
/ 100 risk score
Snapshot · scanned Aug 5, 2026 · repo@2ee141e · engine 0.38.1 / ruleset 42

Automated static-analysis result. It can contain false positives and false negatives, and is not a claim about the intent of Drawio Skill's authors. Report a false positive.

Capabilities — what this component can do (not a risk score):
filesystem readfilesystem writenetwork egressshell execution

Behavioral traits

How this component maps to the CSA agentic threat model. Descriptive — it never affects the risk score.

Execution authority
Tool Access Control / Direct Tool Access
Filesystem reach
Tool Execution Context
Network egress
Interaction & Communication / Direct Communication

Findings (4)

HIGHPython shell/command executionST-SHELL-PY

The component can run operating-system commands or spawn processes.

proc = subprocess.run(
            ["dot", "-Tplain"], input=dot_src,
            capture_output=True, text=True, check=True,
        )
r = subprocess.run(["drawio", "-x", "-f", "png", "--page-index", "1",
                                "--width", "2000", "-o", png_path, src], capture_output=True)
r = subprocess.run(
            [sys.executable, os.path.join(HERE, "autolayout.py"), gpath, "-o", opath],
            capture_output=True, text=True,
        )
r = subprocess.run(["drawio", "-x", "-f", "png", "--page-index", str(index),
                        "-s", str(scale), "-o", out_png, drawio_file],
                       capture_output=True)
r = subprocess.run(["drawio", "-x", "-f", "svg", "--page-index", str(index),
                        "-o", out_svg, drawio_file], capture_output=True)
out = subprocess.run(["tred"], input=dot, capture_output=True,
                             text=True, check=True).stdout
out = subprocess.run(["tred"], input=dot, capture_output=True,
                             text=True, check=True).stdout
r = subprocess.run(
            ["git", "-C", repo, "diff", "--name-status", f"{base}..{head}", "--", "*.drawio"],
            capture_output=True, text=True)
r = subprocess.run(["git", "-C", repo, "show", f"{ref}:{path}"], capture_output=True)
r = subprocess.run(["drawio", "-x", "-f", "png", "--page-index", "1", "-o", out_png, src_drawio],
                       capture_output=True)
r1 = subprocess.run([sys.executable, os.path.join(HERE, "drawiodiff.py"),
                        base_drawio, head_drawio, "-o", diff_json], capture_output=True)
r2 = subprocess.run([sys.executable, os.path.join(HERE, "autolayout.py"),
                        diff_json, "-o", diff_drawio], capture_output=True)
out = subprocess.run(["tred"], input=dot, capture_output=True,
                             text=True, check=True).stdout
out = subprocess.run(["tred"], input=dot, capture_output=True,
                             text=True, check=True).stdout
r = subprocess.run([sys.executable, autolayout, graph_path],
                           capture_output=True, text=True)
out = subprocess.run(["tred"], input=dot, capture_output=True,
                             text=True, check=True).stdout
r = subprocess.run(["drawio", "-x", "-f", "svg", "-o", out, path],
                           capture_output=True)
out = subprocess.run(["tred"], input=dot, capture_output=True,
                             text=True, check=True).stdout
p = subprocess.run(["git", "-C", root, *args], capture_output=True)
imp = subprocess.run(
        [sys.executable, os.path.join(HERE, importer + ".py"), work_path,
         "-o", graph_json, *importer_args],
        capture_output=True)
lay = subprocess.run(
        [sys.executable, os.path.join(HERE, "autolayout.py"), graph_json, "-o", drawio],
        capture_output=True)
exp = subprocess.run(["drawio", "-x", "-f", "png", "--width", "1600",
                          "-o", png, drawio], capture_output=True)

Why it matters: Powerful and often legitimate — confirm the commands aren't built from untrusted input.

Fix: Confirm the command and its arguments are fully controlled and not derived from untrusted input; avoid shell=True.

MEDIUMPython filesystem readST-FS-PY-READ

The component reads files from disk.

manifest = json.load(open(MANIFEST, encoding="utf-8"))
with open(_PALETTE_FILE, encoding="utf-8") as fh:
with open(args.input, encoding="utf-8") as f:
with open(args.input, encoding="utf-8") as f:
with open(path, encoding="utf-8") as f:
with open(path, encoding="utf-8") as f:
with open(opath, encoding="utf-8") as f:
text = sys.stdin.read() if args.input == "-" else open(args.input, encoding="utf-8").read()
with open(out, encoding="utf-8") as f:
with open(args[0], "r", encoding="utf-8") as f:
m = MODULE.search(open(gomod, encoding="utf-8", errors="ignore").read())
src = open(path, encoding="utf-8", errors="ignore").read()
with open(path, encoding="utf-8") as f:
src = open(path, encoding="utf-8", errors="ignore").read()
with open(path, encoding="utf-8") as f:
with open(path, encoding="utf-8") as f:
with open(path, encoding="utf-8") as f:
tree = ast.parse(open(path, encoding="utf-8").read(), filename=path)
tree = ast.parse(open(path, encoding="utf-8").read(), filename=path)
with open(args.input, encoding="utf-8") as f:
with open(args.mapfile, encoding="utf-8") as f:
with open(path, encoding="utf-8") as f:

Why it matters: Usually legitimate, but worth confirming it can't be steered into reading sensitive files.

Fix: Confirm which files are read and that paths cannot be influenced by untrusted input to reach sensitive locations.

MEDIUMPython filesystem write/deleteST-FS-PY-WRITE

The component writes or deletes files on disk.

with open(args.output, "w", encoding="utf-8") as f:
with open(f"{os.path.splitext(out)[0]}-frame{k + 1:03d}.png", "wb") as f:
with open(out, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
with open(gpath, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
with open(out, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
open(args.output, "w", encoding="utf-8").write(text)
open(args.output, "w", encoding="utf-8").write(text)
with open(args.output, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:
open(args.output, "w", encoding="utf-8").write(text)
open(args.output, "w", encoding="utf-8").write(text)
with open(args.output, "w", encoding="utf-8") as f:
with open(args.output, "w", encoding="utf-8") as f:

Why it matters: Usually legitimate, but worth confirming the paths can't be controlled by untrusted input.

Fix: Confirm which files are written/deleted and that paths cannot be influenced by untrusted input.

MEDIUMPython network egressST-NET-PY

The component makes outbound network requests.

svg = urllib.request.urlopen(url, timeout=15).read()
svg = urllib.request.urlopen(url, timeout=15).read()
pre = urllib.parse.quote(xml, safe="!~*'()")
+ urllib.parse.quote(_deflate_b64(xml), safe="")

Why it matters: Usually legitimate, but confirm the destinations are expected and no sensitive data leaves.

Fix: Confirm the destination hosts are expected and that no sensitive data is sent off-host.

Check your own component

Run the same evidence-backed scan on any MCP server, agent skill, or package.

Scan your own component

How we determine this: deterministic static analysis (regex + AST), evidence-anchored, no code execution. Methodology →