registry  /  @aidraw/agentdraw  /  0.1.18

@aidraw/agentdraw@0.1.18

Local-first editable whiteboard workspace for coding agents.

AI Security Review

scanned 2h ago · by lpm-firewall-ai

Running `agentdraw open` exposes a local HTTP `/api/scene` endpoint that reads and writes caller-supplied filesystem paths. The endpoint defaults to `127.0.0.1:3927` but emits `access-control-allow-origin: *`; its API path handling does not enforce the package's own blocked-directory guard.

Static reason
High-risk behavior combination matched malicious policy.; previous stored version diff introduced dangerous source
Trigger
User runs `agentdraw open` and leaves the local server running.
Impact
A malicious webpage reachable by the user's browser can read or overwrite files accessible to the user when it can connect to the running local AgentDraw server.
Mechanism
Cross-origin local HTTP arbitrary file read/write through unchecked `path.resolve` API paths.
Rationale
This is a legitimate local-first whiteboard CLI with normal bundled web assets, not a malware delivery chain. However, its user-invoked local server exposes a confirmed cross-origin arbitrary filesystem read/write surface because `/api/scene` accepts unvalidated paths and enables wildcard CORS. Classify as a warn-only critical vulnerability rather than malicious intent.
Evidence
package.jsondist/index.jsweb-dist/index.htmlweb-dist/assets/index-Cy2H_O9D.jsweb-dist/assets/subset-shared.chunk-RWQhCJhi.js<caller-supplied file query path><caller-supplied JSON filePath>
Network endpoints2
127.0.0.1:3927localhost

Decision evidence

public snapshot
AI called this Suspicious at 92.0% confidence as Critical Vulnerability with low false-positive risk.
Evidence for warning
  • `dist/index.js` has no `preinstall`, `install`, or `postinstall` lifecycle trigger in `package.json`; the executable is activated only through the `agentdraw` CLI.
  • When `agentdraw open` runs, `dist/index.js` starts an HTTP server defaulting to `127.0.0.1:3927`; its `/api/scene` GET route reads a path supplied in the `file` query parameter, and its POST route writes a path supplied in JSON `filePath`.
  • `dist/index.js` resolves API paths with `path.resolve(cwd, input)` but the `/api/scene` handler does not call its separately defined `assertSafePath` helper. Absolute paths and `../` traversal can therefore target paths outside the project working directory subject to the invoking user's filesystem permissions.
  • The HTTP API sets `access-control-allow-origin: *`, allowing a browser origin other than the local AgentDraw UI to make cross-origin requests to the local server once the user has started it.
  • The flagged `spawn` uses are bounded to the explicit `open --background` CLI flow, which relaunches the package's own Node entrypoint, and to the explicit browser-opening option. No `eval`, `Function`, shell command execution, remote JavaScript loader, credential collection, or lifecycle persistence was found in `dist/index.js`.
  • The high-entropy blobs are `.woff2` font assets, and the large base64-like string in `web-dist/assets/subset-shared.chunk-RWQhCJhi.js` is decoded into a WebAssembly module used by the bundled web application; it is not an unconsumed staged payload carrier.
  • The flagged U+202A occurrence in `web-dist/assets/index-Cy2H_O9D.js` is inside a minified bundled Excalidraw web asset. Inspection found no adjacent reviewer-directed text, hidden execution branch, or package-specific loader chain.
Evidence against
  • The local server is user-invoked through `agentdraw open`, defaults to loopback, and contains no install-time trigger; exploitation requires the server to be running and an attacker-controlled browser context to reach it.
  • The inspected package contains no foreign AI-agent configuration writes, MCP registration, shell startup changes, VCS hook setup, detached daemon beyond the user-selected background server, remote command execution, or data-exfiltration endpoint.
  • The bundled web distribution contains product-aligned Excalidraw collaboration/library URL strings, but inspection did not establish that AgentDraw automatically transmits local scene data or credentials to those hosts.
Behavioral surface
Source
ChildProcessCryptoEnvironmentVarsEvalFilesystemNetworkShell
Supply chain
HighEntropyStringsMinifiedObfuscatedProtestwareTelemetryUrlStrings
ManifestNo manifest risk signals triggered.
scanned 130 file(s), 7.86 MB of source, external domains: app.excalidraw.com, chevrotain.io, discord.gg, docs.excalidraw.com, en.wikipedia.org, excalidraw-room-persistence.firebaseio.com, github.com, json.excalidraw.com, langium.org, libraries.excalidraw.com, mermaid.js.org, oss-ai.excalidraw.com, oss-collab.excalidraw.com, player.vimeo.com, plus.excalidraw.com, react.dev, us-central1-excalidraw-room-persistence.cloudfunctions.net, www.w3.org, www.youtube.com, x.com, youtube.com

Source & flagged code

6 flagged · loading source
web-dist/assets/subset-shared.chunk-RWQhCJhi.jsView file
22patternName = aws_access_key severity = critical line = 22 matchedText = `,X.push...64};
Critical
Critical Secret

Package contains a critical-looking secret pattern.

web-dist/assets/subset-shared.chunk-RWQhCJhi.jsView on unpkg · L22
22patternName = aws_access_key severity = critical line = 22 matchedText = `,X.push...64};
Critical
Secret Pattern

AWS access key ID in web-dist/assets/subset-shared.chunk-RWQhCJhi.js

web-dist/assets/subset-shared.chunk-RWQhCJhi.jsView on unpkg · L22
web-dist/assets/index-Cy2H_O9D.jsView file
100contains invisible/control Unicode U+202A (left-to-right embedding) `)},$te=0,qc=[];function Hte(e){var t=D.useRef([]),n=D.useRef([0,0]),a=D.useRef(),i=D.useState($te++)[0],l=D.useState(OA)[0],s=D.useRef(e);D.useEffect(function(){s.current=e},[e]),D.useEffect(function(){if(e.inert){document.body.classList.a
Critical
Trojan Source Unicode

Source contains bidi control or invisible Unicode characters associated with Trojan Source attacks.

web-dist/assets/index-Cy2H_O9D.jsView on unpkg · L100
10patternName = google_api_key severity = high line = 10 matchedText = `).repla...AZZX
High
Secret Pattern

Google API key in web-dist/assets/index-Cy2H_O9D.js

web-dist/assets/index-Cy2H_O9D.jsView on unpkg · L10
web-dist/assets/Assistant-Bold-gm-uSS1B.woff2View file
path = web-dist/assets/Assistant-Bold-gm-uSS1B.woff2 kind = high_entropy_blob sizeBytes = 20380 magicHex = [redacted]
High
Ships High Entropy Blob

Package ships high-entropy non-source blobs.

web-dist/assets/Assistant-Bold-gm-uSS1B.woff2View on unpkg
dist/index.jsView file
matchType = previous_version_dangerous_delta matchedPackage = @aidraw/agentdraw@0.1.16 matchedIdentity = npm:QGFpZHJhdy9hZ2VudGRyYXc:0.1.16 similarity = 0.992 summary = stored previous version shares package body but lacks this dangerous source file
High
Previous Version Dangerous Delta

This package version adds a dangerous source file absent from the previous stored version; route for source-aware review.

dist/index.jsView on unpkg

Findings

3 Critical3 High4 Medium7 Low
CriticalCritical Secretweb-dist/assets/subset-shared.chunk-RWQhCJhi.js
CriticalTrojan Source Unicodeweb-dist/assets/index-Cy2H_O9D.js
CriticalSecret Patternweb-dist/assets/subset-shared.chunk-RWQhCJhi.js
HighShips High Entropy Blobweb-dist/assets/Assistant-Bold-gm-uSS1B.woff2
HighPrevious Version Dangerous Deltadist/index.js
HighSecret Patternweb-dist/assets/index-Cy2H_O9D.js
MediumNetwork
MediumEnvironment Vars
MediumProtestware
MediumStructural Risk Force Deep Review
LowScripts Present
LowEval
LowFilesystem
LowObfuscated
LowHigh Entropy Strings
LowTelemetry
LowUrl Strings