Plugin Development Overview

A single page covering the four plugin forms, which WASM SDK applies where, the signing and publishing flow, and where to start.

最后更新 2026-10-05

This article is for third-party developers: all you need is the official TestSecScan distribution package plus this documentation to write, from scratch, a plugin that the controller, a scan node, or the AI penetration agent can invoke.

1. Four Plugin Forms: Choose the Right Track First

A TestSecScan "plugin" is not a single thing but four independent extension points, each with its own SDK and signing system. The classic symptom of choosing the wrong track is: your code compiles, but the host will never call it.

FormExtension pointHostDevelopment languageSDK / Docs
Controller pluginSubscribes to and handles TCP commands forwarded by the controllerControllerGo / Rust / C / C++ (WASI)Controller Plugin Development
WASM POC templateHandles one traffic packet and produces vulnerability findingsScan nodeGo / Rust / C / C++ (WASI)WASM POC Template Development
Application pluginHooks into scan node business points (task / traffic / MITM)Scan nodeGo / Rust / C / C++ (WASI, c-shared)Application Plugin Development
AIAgent external toolActs as a "tool" the large model can callAI penetration agentAny executable program / WASI wasmAiAgent External Tool Development

There is also the Go hot-load POC (see Go Hot-Load POC Development): it is not a plugin but one form of vulnerability template. It is written in plain Go source and interpreted in-process by the scan node (the target machine needs no Go toolchain), which suits scenarios where "you need a Turing-complete script, but a full WASM build chain is not worth it".

2. The Boundary Between the Two WASM SDKs (the Easiest Trap to Fall Into)

A scan node injects two completely non-overlapping sets of host functions for the two kinds of WASM modules:

WASM POC template (scan_*)Application plugin (app_*)
Host namespacescan_http / scan_log / scan_report / scan_call / scan_t / scan_config / scan_set_timeoutapp_log / app_send_tcp* / app_call / app_spawn_tool / …
Entry point_start (func main), one traffic packet per invocationExported functions prefixed with 应用_, called per hook
Build modeAn ordinary wasip1 command moduleRequires -buildmode=c-shared
Where it takes effectOnly entries with PocType=wasm in the POC template list (vulnerability templates)Scan node application plugins installed from the plugin store
SDK file (inside the downloaded SDK package)scan.goapp.go

Key limitation: the scan_* host functions are injected only on the "POC template execution" call path. In other words, putting scan.HTTP(...) into an application plugin, or app.SpawnTool(...) into a WASM POC, will make instantiation fail, because the host does not export the corresponding functions. Telling the two apart is easy:

  • Your artifact is scanned as a vulnerability from the POC template list → use scan.*;
  • Your artifact runs as a resident plugin from the plugin store / application plugin directory → use app.*.

By the same token, controller plugins use ctl_* and AiAgent external tools use stdin/stdout JSON — the four sets are not interchangeable.

3. The Shortest Path to Getting Started

① Choose the form (table above)
② Copy the matching SDK into your project (every article shows how to wire up go.mod)
③ Compile locally into a .wasm file / executable
④ Sign locally (controller key, Ed25519)
⑤ Put it into the host's load directory, or submit it to the plugin store / POC store
⑥ See it in the GUI, trigger it, read the logs

Every chapter article covers: directory layout → build commands → every public function explained one by one (parameters / returns / scenarios / examples) → caveats → complete runnable examples → debugging methods.

How to Read Each Chapter Article (Uniform Structure)

All five chapter articles follow the same structure; reading them in the order below will keep you unstuck:

SectionWhat you get
1. What it is / when you should write itChoosing the right form; avoiding the wrong track
Where the entry point is: how the host loads and calls youWhere to put the file → how to sign / verify → when the host compiles / instantiates → when the entry function is called → how data goes in (stdin / host functions) and how results come out → how to reload
Function / hook / field walkthroughsOne section per public symbol: purpose → full signature → parameter table (what to pass, where it comes from, example values) → returns (field table + how to read the value + behavior on failure) → copy-ready code snippet → caveats
Built-in / host function referenceParameters, return values and ID cross-reference for the low-level env host functions and built-in tool functions
Complete examplesFrom minimal to advanced, ready to copy and adapt
Debugging handbookWhere to find logs → a 5-minute minimal verification flow → a "symptom → cause → fix" table
Caveats checklistEvery entry spells out "what happens if you get it wrong"
提示

When you wonder "what does this function return, and how do I get the return value", jump straight to that function's #### section and read the three-part set: parameter table + returns + code snippet. When "my plugin is never called at all", read the Where the entry point is chapter first (nine times out of ten, you forgot to export it / sign it / declare the capability).

4. Downloads: Documentation and SDK Packages

Every documentation page has download buttons in the top-right corner, and you can also use the fixed addresses below (they follow releases and always point to the version currently in effect):

What to downloadAddress
This page as Markdown (single article)"Download Markdown" in the page's top-right corner, or /api/v1/site/devdocs/download/<slug>
All documentation (packed .zip, with a README index)/api/v1/site/devdocs/archive.zip
Controller plugin SDK (ctl: Go/C/C++/Rust)/api/v1/site/devdocs/sdk/controller.zip
WASM POC template SDK (scan: Go/C/C++/Rust)/api/v1/site/devdocs/sdk/wasm-scan.zip
Application plugin SDK (app: Go/C/C++/Rust)/api/v1/site/devdocs/sdk/wasm-app.zip
Go hot-load POC reference package (scanapi.go + type definitions)/api/v1/site/devdocs/sdk/gopoc.zip
All SDKs in a single package/api/v1/site/devdocs/sdk/all.zip

Every SDK package contains its own README.md explaining how to wire it into your project (how to write the replace directive in go.mod), the build commands, and the caveats; after unzipping, copy the whole directory into your plugin project.

说明

The source code inside each SDK package is a snapshot (byte-for-byte identical to the SDKs in this platform's per-end projects, locked down by guardrail tests). Official updates are published through the backend (the download button shows the current version, e.g. v1.0.0); download again after an upgrade to get the latest SDK, and if you have already copied an older SDK into your project, compare and replace it.

5. Signing and Publishing (a Hard Security Gate)

All four kinds of TestSecScan extensions follow the same rule: no signature, no loading — and signature verification uses the public key held by the host, never a public key bundled inside the package:

  • Controller / scan node WASM: Ed25519 signature; inside sig.json, signStatus must be verified or official;
  • AiAgent external tool: the signature covers the whole-package digest (every file in the directory except sig.json, hashed with SHA-256 in ascending relative-path order), and verification runs once at load time and once before every invocation (TOCTOU protection);
  • The signing private key is held only by the controller; third-party developers sign through one-click signing in the GUI or through the official build service.
注意

Do not try to bypass verification with a self-signed key pair: the host only trusts the public key delivered by the controller, so a self-signed package is judged verify_failed and the model / scan engine cannot see it. This is not "it was seen but execution was refused" — it never enters the registry at all.

6. Documentation Maintenance Conventions (for Future SDK Evolution)

This documentation set and the SDK source code evolve together:

  1. After adding or modifying any public SDK function, you must update the corresponding chapter article and register it in the comparison tables on this page, such as "The Boundary Between the Two WASM SDKs";
  2. The repository ships an SDK coverage guardrail test that parses the SDK source of each end and makes two assertions: ① every public symbol appears in the documentation body; ② every public symbol has a #### section named after it, and that section contains a code snippet (in other words, "every function needs an example of how to call it and how to read its return value"). Omitting it, or writing only a one-line description, fails the test, which forces the documentation to stay in sync;
  3. The documentation body can be edited online in the backend under "Site Settings → Developer Docs"; edits are persisted as an override layer, while the built-in version is refreshed with each release and can be restored to the default with one click.
本文档随 SDK 源码同步更新;新增或修改公开接口后会同步到此页。