contract diagram
WarnAudited by ClawScan on May 10, 2026.
Overview
This looks like a local diagram viewer, but its bundled web server exposes unsafe file read/write behavior and should be reviewed before use.
Do not run this skill on important files without a backup. If you test it, run the server only in a trusted environment, stop it immediately afterward, avoid opening untrusted viewer URLs or Markdown files, and consider fixing the write endpoint and HTML escaping before installation.
Findings (5)
Artifact-based informational review of SKILL.md, metadata, install specs, static scan signals, and capability signals. ClawScan does not execute the skill or run runtime probes.
While the server is running, another local process, browser page, or possibly a network peer could alter files served by the skill or exploit weak path handling.
The server accepts a path and content from any HTTP POST to /write and writes it to disk. The containment check is a simple prefix check, and the listener is not explicitly restricted to localhost.
const { path: filePath, content } = JSON.parse(body); const fullPath = path.join(ENGINE_DIR, filePath); ... fs.writeFileSync(fullPath, content, 'utf8'); ... server.listen(PORT, () => {Remove the write endpoint unless required, bind explicitly to 127.0.0.1, add an unguessable token or approval flow, use path.resolve/realpath with strict directory checks, and only allow writes to the user-selected contract file.
If a user opens a malicious viewer URL while the server is running, injected browser code could run in the local viewer and interact with the server endpoints.
The md URL parameter is later inserted into innerHTML on error without escaping. A crafted URL can inject browser HTML/script into the viewer origin.
const mdPath = urlParams.get('md'); ... document.querySelector('.container').innerHTML = `... <p>Path: <code>${path}</code></p> ...`;Render user-controlled values with textContent or HTML escaping, avoid innerHTML for error messages, and combine this with authentication on local endpoints.
A contract markdown file or skill file could be emptied during what appears to be a harmless access check.
The client code defines a write-permission test that sends empty content to /write, while the server writes supplied content to disk. If this code path is used, a permission check can become a file-truncating action.
// Test write access with empty write (no actual change) ... body: JSON.stringify({ path: mdPath, content: '' })Do not test write permissions by writing empty content to the target file. Use a temporary file, a non-mutating access check, or explicit user-approved save actions with backups.
The local server may continue accepting requests until the user stops it.
The documented workflow starts the server in the background and enables polling by default. This is aligned with live diagram viewing, but it can keep running beyond the immediate task.
AI executes: cd ~/Documents/skills/contract-diagram/engine ./serve.sh & open "http://localhost:8080/?md=../../epic-notes/webhook-contract.md" ... Hot reload enabled by default
Show users how to stop the background server, avoid leaving it running, and prefer foreground execution unless background operation is explicitly requested.
Users may run local code without realizing Node is required or that a server process will be started.
The launcher requires Node even though the metadata declares no required binaries and no install spec. This is expected for the bundled server, but the runtime requirement is under-declared.
cd "$ENGINE_DIR" && node server.js
Declare Node as a required binary and document exactly what code runs and how to stop it.
