Help us shape the future of Go! Take the 2026 Go Developer Survey

toolparse

package
v0.5.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Oct 22, 2026 License: Apache-2.0 Imports: 10 Imported by: 0

README

toolparse

Structured output parsers for security CLIs, ported from 4zreco.

Supported tools (registry key):

httpx, ffuf, katana, nuclei, nmap, sqlmap, dirsearch, dalfox, arjun, wpscan, wafw00f, nikto, whatweb, fscan, hashcat, john.

Each parser turns raw stdout/stderr into:

  • Fields: scalar key facts (counts, DBMS, ports, technology, ...)
  • Facts: normalized candidates (finding/..., target/..., infra/..., auth/...) with confidence and links
  • RawRef: caller-provided raw evidence path

No database or host dependency: the host decides whether/how to persist facts. Parsers are fail-closed: malformed/truncated input yields no facts.

Documentation

Overview

Package toolparse 提供外部 CLI 工具的结构化输出解析与事实黑板自动落库。

设计见 docs/工具结构化输出与事实黑板打通-改造档案.md §四:

  • 输出层:executor 挂钩层把平台独占输出标志注入 argv(模型不可覆盖), 纯 stdout 模式直接产出结构化内容,落文件模式(-o/-of/--log-xml)由 挂钩层把结构化文件内容并入 stdout 后再交给解析器(§4.3 runner 契约)。
  • 解析层:按工具名分发到注册的 Parser,产出 Result(关键字段 + 事实候选 + raw_ref)。
  • 落库层:store.go 把事实候选写入 project_facts / assets(同步、失败不阻断、fail-closed)。

解析失败一律回退现状(原文 + 截断 + spill),不落任何事实(§4.7)。

Index

Constants

View Source
const ConcludeMaxFacts = 20

ConcludeMaxFacts 解析层硬顶(提示词限 12 条,此处放余量防灌库)。

View Source
const MaxFactsIndexEntries = 12

MaxFactsIndexEntries facts_index 展示条数上限(超限截断 + 计数兜底,§5.5 双写率口径依赖它存在)。

View Source
const MaxReceiptBytes = 2048

MaxReceiptBytes 回执硬上限(§4.6:2KB)。

View Source
const TmpDirPlaceholder = "<TMPDIR>"

注入目录模板占位符(挂钩层执行前替换为实际 tmpdir)。

Variables

View Source
var ValidCategories = map[string]bool{
	"finding":  true,
	"chain":    true,
	"exploit":  true,
	"poc":      true,
	"target":   true,
	"auth":     true,
	"infra":    true,
	"business": true,
}

ValidCategories 既有 fact_key category 前缀白名单(禁止新增,见档案 §十)。

Functions

func InjectedTools

func InjectedTools() []string

InjectedTools 注入表覆盖的工具名集合(供挂钩层判断"是否需要走结构化通道")。

func Manifest

func Manifest() core.Manifest

Manifest declares the parser tools.

func NewCapability

func NewCapability(core.Deps) (core.Capability, error)

NewCapability builds the parser capability.

func Register

func Register(p Parser)

Register 注册解析器(工具名 → 解析器,同名覆盖取最后一次)。

func RegisteredTools

func RegisteredTools() []string

RegisteredTools 已注册解析器的工具名集合(调试/门禁自检用)。

func RenderParseError

func RenderParseError(tool string) string

RenderParseError 解析失败回退时的回执(§4.7:标 parse_error,模型据此知道该次未落库)。

func RenderReceipt

func RenderReceipt(res *Result, recorded int) string

RenderReceipt 渲染模型可见回执文本(Content[0].Text 用)。 规则:超出 MaxReceiptBytes 时先裁 facts_index,再整体截断加尾注。

func Sluggify

func Sluggify(s string) string

Sluggify 把 host/路径等转成 fact_key slug:全小写、保留 :/.、空格→-、去 URL scheme。

func ValidateFactKey

func ValidateFactKey(factKey string) error

ValidateFactKey 校验 fact_key 前缀与整体形态(与既有 ValidateFactKey 同口径, 见 internal/database/project_fact_edges.go;此处为 toolparse 侧前置校验,落库前还会再过一次 DB 层)。

Types

type Capability

type Capability struct{}

Capability exposes the structured-output parsers as a tool. It turns one external CLI tool's raw stdout into key fields and fact candidates, so the agent reads structure instead of scraping text.

func (*Capability) Call

func (c *Capability) Call(ctx context.Context, call core.Call) (core.Result, error)

Call dispatches the parser tools.

func (*Capability) Manifest

func (c *Capability) Manifest() core.Manifest

Manifest implements core.Capability.

type ConcludeEnvelope

type ConcludeEnvelope struct {
	Facts    []FactCandidate `json:"facts"`
	Residual string          `json:"residual"`
}

ConcludeEnvelope 收尾轮回执信封。category 不在信封字段里——由 fact_key 前缀推导 (键即分类的单一事实源,与 ValidCategories 白名单同口径)。

func ParseConcludeOutput

func ParseConcludeOutput(text string) (*ConcludeEnvelope, error)

ParseConcludeOutput 从收尾轮回复文本解析增量事实信封(fail-closed)。 候选 JSON 依次尝试:``` 围栏块 → 顶层平衡对象 → 整段文本;候选必须含 "facts" 字段 (防把无关 JSON/工具回显误收为信封)。全部失败返回 error,不落任何事实; 单条事实不合格只丢弃该条(NormalizeFact 同口径),不影响其余条目。

type FactCandidate

type FactCandidate struct {
	FactKey    string     `json:"fact_key"`   // 必须符合既有约定:<category>/<slug>(§4.5 规则 1)
	Category   string     `json:"category"`   // finding|target|infra|auth|...(既有枚举,禁止新增)
	Summary    string     `json:"summary"`    // 「什么+在哪+如何验证」
	Body       string     `json:"body"`       // 复现细节(命令/证据摘录;原始输出不写入,只挂 raw_ref)
	Confidence string     `json:"confidence"` // tentative|confirmed(解析器不得直接写升级判定)
	Links      []FactLink `json:"links,omitempty"`
}

FactCandidate 结构化 → 事实黑板的一条候选(落库层消费)。 字段口径与 upsert_project_fact 工具一致(见 internal/app/project_fact_tools.go)。

func NormalizeFact

func NormalizeFact(f FactCandidate) (FactCandidate, error)

NormalizeFact 落库前规范化:校验 fact_key/category/confidence 合法值,裁剪异常字段。 返回规范化后的候选;不合格返回 error(fail-closed:宁可不落,不错落)。

type FactLink struct {
	From string `json:"from"`
	Type string `json:"type"`
}

FactLink 事实关系边(from → 当前 fact_key)。

type Injection

type Injection struct {
	Tool string
	// Args 追加进 argv 的平台独占标志(filterDangerousFlags 之后、exec 之前,模型不可覆盖)。
	Args []string
	// ResultFileRel 相对注入目录的结果文件(目录由挂钩层生成:<workspace>/toolparse/<executionID>/)。
	// 该文件内容由挂钩层并入 stdout 供解析器消费;空 = 无落盘文件(纯 stdout 模式)。
	ResultFileRel string
}

Injection 描述一次工具调用的平台注入:追加 argv 与执行后需并入 stdout 的文件。

func InjectionFor

func InjectionFor(tool string) *Injection

InjectionFor 返回某工具的注入描述(未注册 → nil,保持现状零行为变化)。

func (*Injection) ResolveArgs

func (inj *Injection) ResolveArgs(tmpdir string) []string

ResolveArgs 把注入 argv 里的目录占位符替换为实际 tmpdir(幂等)。

func (*Injection) ResolveResultPath

func (inj *Injection) ResolveResultPath(tmpdir string) string

ResolveResultPath 返回结果文件的绝对路径(无 ResultFileRel 返回 "")。

type Parser

type Parser interface {
	// Match 判定该解析器是否处理这次调用(按工具名 + 已注入的输出标志)。
	Match(tool string, argv []string) bool
	// Parse 解析原始输出(runner 契约见 §4.3:stdout 已含该模式最完整的结构化内容)。
	Parse(stdout, stderr string, rawRef string) (*Result, error)
}

Parser 解析器接口。实现须对畸形/截断输入安全(fail-closed):解析失败返回 OK=false 且 Facts 为空,不得从半截文本猜事实。

func Lookup

func Lookup(tool string, argv []string) Parser

Lookup 按工具名 + argv 找匹配解析器;未注册/未注入输出标志 → 保持现状(nil)。

type Result

type Result struct {
	Tool   string          `json:"tool"`
	OK     bool            `json:"ok"`
	Fields map[string]any  `json:"fields"`  // 关键字段(端口/状态码/技术栈…),只放标量与计数
	Facts  []FactCandidate `json:"facts"`   // 事实候选
	RawRef string          `json:"raw_ref"` // 原始证据落盘路径(read_file 可回读)
	Err    string          `json:"err,omitempty"`
}

Result 一个工具的解析结果。

type TargetAware

type TargetAware interface {
	NeedsTarget() bool
}

TargetAware 需要目标 URL 才能生成事实键的解析器(arjun/sqlmap 等结构化内容里无 host)。 executor 挂钩层会把注入 argv 中的目标 URL 以 "TARGET: <url>\n" 前缀并入 stdout。

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL