Announcing Beacon: Self-improving memory for coding agents
← All skills
Skill

nexttrace

skill:nxtrace/ntrace-core#nexttrace

Use NextTrace through its deploy MCP endpoint for traceroute, MTR, MTU discovery, speed tests, IP annotation, GeoIP lookup, and Globalping multi-location traceroute. Trigger when an agent needs network path diagnostics or needs to call NextTrace MCP tools.

Verdict
Suspicious

Risky behavior the analysis could not rule out.

Analyzed Oct 27, 2026, 22:12 UTC at 7ff73b2

Dispute security verdict

If you believe this verdict is incorrect, submit a dispute and we'll review it.

2
findings
high
highest severity
1
threat classes
516
files scanned
404/404
checks satisfied
0
package advisories

Why this verdict

  • suspicious: finding skill:skills/nexttrace:server/web/assets/mtr_truncation.test.cjs:39:EXEC
  • suspicious: finding skill:skills/nexttrace:skills/nexttrace/references/validation.md:54:EXEC

Security findings 2

Code execution

highContextual riskmedium confidence

Undeclared residue R1-R3: the Node test file mtr_truncation.test.cjs reads the artifact's own sibling app.js from disk and evaluates it with vm.runInContext to unit-test ingest/render functions — a local, plainly visible self-test harness pattern that the declared network-diagnostics purpose does not cover, but which executes only the artifact's own code in a sandboxed context and shows no harmful source-to-sink chain.

vm.runInContext(fs.readFileSync(appPath, 'utf8'), context, {filename: appPath});
vector:code
Counter-argument considered

The claim matches the shown code: the test vm-evaluates only its own sibling app.js (const appPath = path.join(__dirname, 'app.js')) inside a context holding just console/DOM stubs with no fs, process, or network objects, validation.md steers agents to run it via node --test, and no declared claim covers the dynamic-code residue; no carve-out, declaration, or mitigation in the evidence defeats it, so it stands as contextual_risk.

Code execution

highContextual risklow confidence

The validation reference instructs the agent to run node --test over the glob-matched server/web/assets/*.test.cjs scripts, whose contents (including vm.runInContext use flagged by deterministic leads) are not shown in this pass, so what executes is unverifiable here.

node --test server/web/assets/*.test.cjs
vector:instruction
Counter-argument considered

The instruction is real, plainly reachable in the skill's validation reference, undeclared (the only declared exec checks in validation.md are go test rows), and directly chained to executing the glob-matched scripts; the claim's unverifiability gloss is partially wrong since the flagged vm.runInContext contents are shown in SRC:a88c2746b3d6b1f2 as a restricted self-test harness, but that weakens severity without failing any gate or supplying a carve-out/mitigation.

Open questions 7

What the analysis could not settle from the code alone.

Does server/web/assets/app.js insert the t('mapOpen') translation string into HTML without escaping? The recovered comment states it is assumed not user-supplied and only the URL is escaped, which is unverifiable from the shown fragment.
Manipulation
Contradiction lead C5: the WebUI live-trace WebSocket (socket = new WebSocket(wsUrl)) in runTrace is flagged as contradicting D14/D42 ('runs without network connectivity', replay-scoped claims); from the shown evidence the claims apply to replay mode while this WebSocket serves the declared live traceroute feature of the deploy server's WebUI — confirm whether D14 in docs/mtr-session.md is scoped to replay only, which would make the lead spurious.
Contradiction lead C6: fetch('/api/cache/clear', {method: 'POST'}) is a same-origin POST from the deploy server's own WebUI to its own cache-clear API, which does not appear to contradict the replay-scoped claims D14/D42 or the Globalping claims D49/D50 — confirm whether any claim is genuinely broken by this local control call.
Contradiction lead C7: the '$TOKEN' environment variable in the SKILL.md deploy example is passed via the --deploy-token flag, not a URL query string, so it appears compliant with D28/D64 ('Do not put tokens in URL query strings') and unrelated to the D34 tool-choice table — confirm no instruction elsewhere directs tokens into query URLs.
Credential access
Contradiction lead C8: the '$TOKEN' environment variable in cli-fallback.md's Deploy MCP example uses the --deploy-token flag rather than a query-string URL, so it appears to comply with rather than contradict D64/D34 — confirm the contradiction links are spurious.
Credential access
createMetaItem inserts its value into innerHTML unescaped when allowHTML=true; confirm whether any caller passes remote- or user-derived values with allowHTML=true, which would enable script injection in the WebUI.
Manipulation
Contradiction leads C9-C11 (env 'TOKEN' vs D34/D64) and C3 (file_write '.json.assert' vs D13/D16 and other file_write claims) were adjudicated as not genuine contradictions on inspection: the smoke checks pass the deploy token via Authorization/X-NextTrace-Token headers, which is exactly the alternative the 'Do not use query token URLs' claim mandates and does not touch tool selection (D34), and '<case>.json.assert' is per-case test-failure output distinct from the mtr-session recording files th⟦… 90 more chars …⟧

Coverage gaps 16

Parts of the artifact the static analysis could not fully examine.

context:unanalyzable_binary pe content is only byte-scanned
assets/windivert/x64/WinDivert.dll
context:unanalyzable_binary pe content is only byte-scanned
assets/windivert/x64/WinDivert64.sys
context:unanalyzable_binary pe content is only byte-scanned
assets/windivert/x86/WinDivert.dll
context:unanalyzable_binary pe content is only byte-scanned
assets/windivert/x86/WinDivert32.sys
no_dataflow_for_go go file: string-literal extraction only
internal/routeprobe/poll.go
no_dataflow_for_go go file: string-literal extraction only
internal/routeprobe/raw_disconnect_linux.go
no_dataflow_for_go go file: string-literal extraction only
internal/routeprobe/raw_disconnect_socketcall_linux.go
no_dataflow_for_go go file: string-literal extraction only
internal/routeprobe/raw_source_linux.go
no_dataflow_for_go go file: string-literal extraction only
internal/routeprobe/route_linux.go
no_dataflow_for_go go file: string-literal extraction only
internal/routeprobe/types.go
no_dataflow_for_go go file: string-literal extraction only
server/mcp.go
no_dataflow_for_go go file: string-literal extraction only
trace/mtr_raw.go
no_dataflow_for_go go file: string-literal extraction only
trace/mtr_stats.go
no_dataflow_for_dynamic_code line 39: invoked code is not structurally extracted
server/web/assets/mtr_truncation.test.cjs
no_dataflow_for_dynamic_code line 44: invoked code is not structurally extracted
server/web/assets/mtr_truncation.test.cjs
no_dataflow_for_dynamic_code line 57: invoked code is not structurally extracted
server/web/assets/mtr_truncation.test.cjs