From 1025938dd924f683bb42fb90764289355eac2953 Mon Sep 17 00:00:00 2001 From: Autumn-27 <53844290+Autumn-27@users.noreply.github.com> Date: Sat, 8 Aug 2026 07:54:17 -0400 Subject: [PATCH] =?UTF-8?q?fix(asset):=20insert=5Fassets=20=E7=94=B1?= =?UTF-8?q?=E7=A8=8B=E5=BA=8F=E6=9D=83=E5=A8=81=E8=B5=8B=20task=5Fid=20+?= =?UTF-8?q?=20service/endpoint=20=E8=A1=A5=E5=BB=BA=20subdomain/root=5Fdom?= =?UTF-8?q?ain?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - insert_assets 不再把 task_id 暴露给模型/依赖模型传:schema 去掉 task_id,handler 直接用 SetTaskID 设的 t.taskID,避免模型漏传/错传导致资产未归任务或归错任务。 - UpsertHTTPService/UpsertOtherService/UpsertEndpoint 新增 side effect linkHostAssets:把 host 反向登记为独立 root_domain + subdomain 资产(非 apex、非 IP 才建 subdomain);endpoint 原来无任何 side effect,现补建 root_domain/subdomain/IP。 Co-Authored-By: Claude Opus 5 (1M context) --- agent/tools_insert.go | 11 ++++------- db/assets.go | 31 +++++++++++++++++++++++++------ 2 files changed, 29 insertions(+), 13 deletions(-) diff --git a/agent/tools_insert.go b/agent/tools_insert.go index 5ecff98..c4cab12 100644 --- a/agent/tools_insert.go +++ b/agent/tools_insert.go @@ -79,7 +79,7 @@ func (t *ToolSet) insertAssets() actool.CoreTool { "auth/technologies/params 都是【追加合并】(append),不会覆盖原有值。\n"+ "返回:{results:[{index,id,type}], errors:[{index,error}]}", obj(map[string]any{ - "task_id": intp("任务 id(可选,用于关联 task_ids)"), + // task_id 不暴露给模型:worker 归属哪个 task 由程序经 SetTaskID 权威赋值(见 handler)。 "assets": map[string]any{ "type": "array", "description": "资产数组,每个元素对应一条资产记录", @@ -158,16 +158,13 @@ func (t *ToolSet) insertAssets() actool.CoreTool { } var a struct { Assets []assetInputItem `json:"assets"` - TaskID int64 `json:"task_id"` } if err := json.Unmarshal(in, &a); err != nil { return actool.Errorf("invalid input: " + err.Error()), nil } - // use ToolSet.taskID as fallback - taskID := a.TaskID - if taskID == 0 { - taskID = t.taskID - } + // task_id 由程序权威赋值(worker: SetTaskID),不接受模型传入——避免模型漏传/错传 + // 导致资产未归任务或归错任务。无任务上下文的调用方(auto/pentest/chat)其 t.taskID=0。 + taskID := t.taskID type result struct { Index int `json:"index"` diff --git a/db/assets.go b/db/assets.go index d7b1fa7..01241b4 100644 --- a/db/assets.go +++ b/db/assets.go @@ -628,8 +628,8 @@ RETURNING id`, return 0, err } - // side effects - _, _ = s.UpsertRootDomain(UpsertRootDomainReq{Domain: rootDomain, TaskID: req.TaskID}) + // side effects: register root_domain + subdomain as their own assets too + s.linkHostAssets(domain, rootDomain, req.TaskID) if req.IP != "" { var boundDomains []string if domain != "" { @@ -760,12 +760,22 @@ RETURNING id`, TaskID: req.TaskID, }) } - if rootDomain != "" { - _, _ = s.UpsertRootDomain(UpsertRootDomainReq{Domain: rootDomain, TaskID: req.TaskID}) - } + s.linkHostAssets(domain, rootDomain, req.TaskID) return id, nil } +// linkHostAssets ensures a service/endpoint's host is also registered as its own +// root_domain and (when it's a real subdomain, not the apex or an IP) subdomain +// asset — so those asset types stay populated and can anchor task scope. Best-effort. +func (s *AssetStore) linkHostAssets(domain, rootDomain string, taskID int64) { + if rootDomain != "" { + _, _ = s.UpsertRootDomain(UpsertRootDomainReq{Domain: rootDomain, TaskID: taskID}) + } + if domain != "" && domain != rootDomain && net.ParseIP(domain) == nil { + _, _ = s.UpsertSubdomain(UpsertSubdomainReq{Domain: domain, TaskID: taskID}) + } +} + // ===================================================================== // UpsertEndpoint // ===================================================================== @@ -852,7 +862,16 @@ RETURNING id`, normURL, method, domainVal, ipVal, nullableInt(port), rootDomainVal, paramsJSON, companyID, taskIDs, csegVal, ).Scan(&id) - return id, err + if err != nil { + return 0, err + } + // side effects: endpoint previously registered none — register its host as + // root_domain + subdomain(+IP) so those asset types get populated too. + s.linkHostAssets(domain, rootDomain, req.TaskID) + if req.IP != "" { + _, _ = s.UpsertIP(UpsertIPReq{IP: req.IP, TaskID: req.TaskID}) + } + return id, nil } // =====================================================================