拓冰建站拓冰建站
首页 / 资讯中心 / 正文

Activepieces 安全公告分类实践:从 GitHub 私密漏洞积压到可评审报告的完整流水线

Activepieces 安全公告分类实践从 GitHub 私密漏洞积压到可评审报告的完整流水线【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces导读本文讲解 Activepieces 仓库中用于分类TriageGitHub 私密上报漏洞的完整自动化流程覆盖从ghCLI 拉取仓库安全公告、按 SECURITY.md 做范围审查、逐条深度验证定位入口点到 sink 的完整调用链、SLA 期限计算到产出每条公告的评审报告与汇总仪表盘的六个步骤。读完你不仅能手动复现这套流水线还能掌握 Activepieces 特有的高收益漏洞模式清单如grantAccess空权限放行、TypeORM.where()二次调用覆盖租户隔离等可直接用于漏洞挖掘与代码审计。该技能的定义位于 .agents/skills/triage-security-advisories/SKILL.md它自动化的是人工流程手册 docs/handbook/engineering/playbooks/security-advisory-response.mdx与处理 Dependabot 依赖告警的triage-dependabot-alerts技能共享同一.security-triage/工作区、隐私规则与 SLA 脚本。技能定位两类安全积压的不同分工Activepieces 的安全积压分两类由两个技能分别处理技能处理对象数据来源triage-security-advisories仓库安全公告repository security advisoriesGitHub Security 标签页的私密漏洞上报triage-dependabot-alerts依赖告警dependency alertsDependabot两者共享.security-triage/工作区、硬性隐私规则与 SLA 脚本npm run security:sla但数据源与处理重点不同。本文聚焦前者每个公告产出 review-ready 报告 SLA 仪表盘 修复方案建议最终由用户逐条裁决批准修复 / 判定超范围关闭 / 升级处理。硬性隐私规则公共仓库的第一道红线Activepieces 仓库是公开的私密/禁运中的embargoed公告内容绝不能提交进版本库所有产物拉取的 JSON、逐条公告报告、仪表盘一律写入.security-triage/该目录已被 gitignore严禁把公告内容写进任何被跟踪的文件。每次运行后需确认git status在被跟踪路径下没有新增内容。修复必须走私有 fork 的security/ghsa-id分支按 playbook 执行禁运期结束前绝不打开公开 PR。这条规则贯穿全流程是后面每一步操作的约束前提。一次性设置ghToken 需要 security 权限仓库安全公告 API 需要带安全范围的 token否则第一步拉取会返回 403。若遇到 403让用户执行gh auth refresh -s security_events,repo刷新后重新运行即可。Step 1 — 拉取公告确定性步骤mkdir -p .security-triage gh api /repos/activepieces/activepieces/security-advisories --paginate .security-triage/advisories.json两个高频注意点分页拼接的 JSON 数组gh api --paginate可能输出多个拼接的顶层数组例如先看到长度100、再5。此时需合并为单数组jq -s add。SLA 脚本自身也内置了字符串感知的顶层值扫描见下文源码分析能直接处理这种拼接格式。zsh JSON 陷阱每次都会踩绝不把公告行通过echo/printf管道给jq——echo $row | jq …会破坏内嵌的控制字符/反斜杠报Invalid string: control characters … must be escaped。正确做法是循环 id每次都让jq直接读源文件避免 shell 字符串中转mkdir -p .security-triage/input .security-triage/reports for id in $(jq -r .[] | select(.statetriage or .statedraft) | .ghsa_id .security-triage/advisories.json); do jq --arg id $id .[] | select(.ghsa_id$id) | {ghsa_id, cve_id, summary, severity, state, created_at, cvss: .cvss_severities, cwes: .cwe_ids, description} \ .security-triage/advisories.json .security-triage/input/${id}.json done然后给每个子代理subagent各自的input/ghsa.json路径去读——把私密、禁运中的公告正文隔离在编排器的上下文和子代理提示词之外。状态过滤无需手工SLA 脚本Step 4默认排除已解决公告closed/published/withdrawn。可操作积压的状态是triage新上报、未评估 → 走完整流水线draft已接受、修复进行中 → 仅做 SLA 跟踪使用--state triage只看未评估--state all则包含已解决。当用户只要triage 状态时传--state triage并且把上面 input 文件循环也过滤为select(.statetriage)。Step 2 — 范围审查对照 SECURITY.md 的 Out of Scope 清单对每条公告对照 SECURITY.md 的Out of scope清单检查无敏感操作页面上的点击劫持Clickjacking未认证/登出/登录 CSRF需要 MITM 或物理接触设备的攻击任何会导致服务中断的活动DoS无攻击向量/无法修改 HTML/CSS 的内容伪造与文本注入邮件伪造Email spoofing缺少 DNSSEC、CAA、CSP 头非敏感 cookie 缺少 Secure 或 HTTP only 标志死链DeadlinksUNSANDBOXED执行模式面向可信运维部署、EE/Cloud 生产环境已阻止接受特殊字符但无可利用 sink 的输入字段能力令牌端点resume URL、webhook URL、签名文件 URL令牌即授权报告必须展示泄露路径日志、Referer泄露、弱熵才在范围内唯一攻击路径是猜测高熵标识符如 nanoid且无已证实的泄露来源的发现若报告命中任一 out-of-scope 项标记为OUT_OF_SCOPE并注明 SECURITY.md 的确切条款与推理。Step 3 — 深度验证入口点到 sink 的完整取证不要停在报告提到了 X。对每条 in-scope 公告追踪从入口点到 sink 的完整路径收集用户能同意或推翻的证据把报告者的file:line和所陈述机制当作线索而非事实。这个代码库产生的每条公告几乎都有漂移引用——重构移动了代码packages/shared→packages/core/shared重写换掉了 sinkaxios → 原生fetch、worker → sandbox行号偏移。要在当前main上按符号/字符串重新定位 sink。漏洞可能是真的但引用位置已过时报告的根因也可能是错的——即使附近确实有 bug例如报告的绕过机制其实无关紧要真正的缺陷在路径别处。验证的是机制而不只是那里看起来不对劲。**定位真实 sinkfile:line**以及每个可达它的路由/调用方。检查中间的防护判断漏洞对攻击者是否真正可达而不只是在源码中存在认证端点上的securityAccess配置每个端点都必须有。租户隔离查询必须按projectId/platformId过滤数据隔离规则connections 使用ArrayContains([projectId])。输入校验zod schema、版本门控platformMustHaveFeatureEnabled、仅 EE 路径。SSRF出站 HTTP 应走safeHttp对用户输入使用裸fetch/axios.create是真实可达 sink。默认开启 vs 可选开启、以及哪个版本——这决定真实严重级别(a) 检查模块在哪个版本注册app.ts的版本开关——很多 sink 仅 Cloud 或仅 EE(b) 漏洞路径是否默认启用或躲在环境变量标志后admin/debug UI 常见(c) 保护模式是否可选开启例如只在非默认网络模式运行的 SSRF 防护。仅在非默认/可选或单一版本配置下可达的真实 bug严重级别实质性更低——要如实说明。确认受影响版本范围与当前main的对比——已修复重构是否移除了 sink用git log -Ssink string/git blame找修复提交。若ALREADY_MITIGATED记录修复提交 SHA 日期并与公告created_at对比本仓库中修复落地之后才上报的报告很常见曾有一个 critical 在修复约 5 周后才被上报。修复日期驱动关闭消息并证明仪表盘上的 BREACHED 已过时。按 playbook 交叉核对 CVSS 4.0 评分输入攻击向量、权限、用户交互、影响范围、CIA 影响。分档0.1–3.9 低4.0–6.9 中7.0–8.9 高9.0–10 严重。给出具体的 PoC 草图 / 失败测试大纲或精确说明为何无法触发。每条公告必须且仅产出一个 VerdictVerdict含义CONFIRMED_EXPLOITABLE按描述可达且可利用。THEORETICALsink 存在但不可达有防护 / 未接线。ALREADY_MITIGATED已有防护或既有修复阻止。FALSE_POSITIVE不是真实漏洞。OUT_OF_SCOPE被 SECURITY.md 排除。同时标记重复项同一 sink/根因和系统性模式一个修复覆盖多个。大积压时按每条公告一个子代理并行扇出再汇总子代理只读写报告文件reports/ghsa.md并返回紧凑 verdict 行绝不改代码。只有用户明确选择多代理编排时才用 Workflow 工具否则用并行Agent调用。扇出实战经验按根因聚类分组公告给每个子代理其兄弟清单很可能与 X 同一 sink交叉核对只验证你自己的——这是发现重复项与系统性模式的诀窍对兄弟项无感知的子代理无法去重。运行时极不均匀一次深度历史追踪约 30 分钟而典型约 3 分钟子代理还可能为 git 考古再派生子代理。要求代理优先给出当前main的 verdict把穷尽历史当作次要任务。不要用sleep轮询harness 会拦截。等待全部报告时挂一个后台until [ $(ls .security-triage/reports/*.md | wc -l) -ge N ]; do sleep 3; done让它在完成时通知同时收集流式返回的 verdict 通知。源码佐证grantAccess的空权限放行SKILL.md 把securityAccess.project(..., undefined, ...)列为头号 sink pattern——传undefined作为必需权限时grantAccess()对 nil 权限返回true。该行为可在 rbac-service.ts 中直接验证const grantAccess async ({ principalRoleId, routePermission }: GrantAccessArgs): Promiseboolean { if (isNil(routePermission)) { return true } // ...否则检查 principalRole.permissions?.includes(routePermission) }routePermission为undefined时直接放行路由退化为仅成员资格——任何项目成员包括 VIEWER都能通过。分类时要确认是存在专门权限却被故意遗漏路由是 bug还是设计上就是仅成员可读例如 piece-metadata 读取并对比正确接线了权限的兄弟模块。Activepieces 高收益 sink 模式看似有防护实则没有优先 grep这是本代码库反复出现的典型 footgun每个都曾以确认公告的形式出现全库 grep 能抓到系统性簇而不只是上报的那一条securityAccess.project(..., undefined, ...)见上文源码佐证路由坍缩为仅成员资格。securityAccess.publicPlatform([PrincipalType.USER])用在需要platformAdminOnly的状态变更或平台级路由上——publicPlatform设置adminOnly:false管理员断言永不执行任何已认证成员都能触达。对比 audit-events / api-keys / signing-keys / global-connections它们都用platformAdminOnly。TypeORM.where()调用两次第二次.where()替换第一次应使用.andWhere。projectId过滤后接.where({ appName })会静默丢弃租户隔离。projectIds []::jsonbPostgres 中空数组 JSONB 包含对每一行都为 TRUE缺失/为空的projectIds会把租户过滤坍缩成匹配所有行。PLATFORM 认证下信任request.projectId它只在AuthorizationType.PROJECT下被填充publicPlatform/PLATFORM 下为undefined下游把它当 scope 键读取时fail open。无逐事件 RBAC 的 Websocket 处理器分发器只校验握手projectId单个addListener处理器信任客户端提供的resourceId/flowVersionId无逐事件权限或资源→项目归属检查。出站不走safeHttpAI-provider/piece 出站调用使用pieces-common的httpClient原生fetch/undici而非safeHttp用户可控的baseUrl/host/resourceName插值进 URL SSRF。进程内 dns/socket 防护是可选开启非默认网络模式且 best-effort——要验证它们是否真的覆盖了实际使用的传输。任意位置设置NODE_TLS_REJECT_UNAUTHORIZED0进程级、持久的 TLS 校验关闭无论上报漏洞是什么本身就是一个 CWE-295 缺陷。window.opener.postMessage(payload, *)通配 targetOrigin 把 payloadOAuth code泄露给任意 opener 源接收侧 origin 检查无法缓解发送侧。仅凭 email 匹配身份联邦登录getIdentityByEmail/仅以 email 为键的全局user_identity没有 provider/sub/NameID 绑定 跨租户账户接管面。Step 4 — 评分 SLA确定性步骤npm run security:sla -- --source advisory # 默认排除已解决 npm run security:sla -- --source advisory --state triage # 只看未评估积压 npm run security:sla -- --source advisory --state all # 包含 closed/published命令定义于 package.jsonsecurity:sla: npx ts-node --project tools/tsconfig.tools.json tools/scripts/security/sla-report.ts脚本读取.security-triage/advisories.json计算截止日期与状态写出.security-triage/sla.json与.security-triage/dashboard.md。默认丢弃closed/published/withdrawn公告--state csv覆盖。SLA 时钟从公告创建日期起算严重级别修复期限DUE_SOON 阈值Critical7 天剩余 ≤ 2 天High30 天剩余 ≤ 7 天Medium90 天剩余 ≤ 14 天Lowbest-effort无硬性期限—状态桶BREACHED→DUE_SOON→ON_TRACK→BEST_EFFORT→NEEDS_TRIAGE未评分按最紧急优先排序。源码剖析sla-report.ts 的实现细节实现位于 tools/scripts/security/sla-report.ts几个关键点值得注意SLA 常量第 4–16 行SLA_DAYS为{critical: 7, high: 30, medium: 90, low: null}DUE_SOON_DAYS为{critical: 2, high: 7, medium: 14, low: 0}与 SKILL.md 表格一一对应low的 SLA 为null直接落BEST_EFFORT。已解决状态集合第 26 行closed/published/withdrawn/fixed/dismissed/auto_dismissed——比 SKILL.md 描述的四种更多默认状态下被过滤。分页拼接 JSON 的健壮解析第 117–145 行脚本自带字符串感知的顶层值扫描器能直接处理gh api --paginate产生的[...]\n[...]拼接格式无需手工jq -s add。状态计算第 222–230 行daysLeft 0→BREACHEDdaysLeft DUE_SOON_DAYS[severity]→DUE_SOON否则ON_TRACK。排序按STATUS_ORDER再按剩余天数升序最紧急在前。未评分/缺日期兜底第 203–214 行severity 无法解析或创建日期缺失时归入NEEDS_TRIAGE--now参数支持用固定时间点复现计算。CLI 参数第 71–110 行支持--advisories/--dependabot/--out/--now/--source/--state默认源为advisory与dependabot两个 JSON 文件输出目录默认.security-triage。Step 5 — 报告先在.security-triage/reports/ghsa.md写每条公告的 review-ready Markdown范围 verdict、有效性 verdict file:line证据、sink、PoC 草图、上报严重级 vs 评估严重级深度验证改变严重级别时注明SLA 仪表盘按 GitHub 上报严重级分桶、SLA 截止日期 状态、建议。然后写汇总的.security-triage/TRIAGE-SUMMARY.md——这才是用户真正评审的产物必须包含Verdict 统计CONFIRMED_EXPLOITABLE / THEORETICAL / ALREADY_MITIGATED / FALSE_POSITIVE / OUT_OF_SCOPE 各多少。按严重级/SLA 状态分组的表格GHSA、SLA 状态、verdict、sinkfile:line、一行备注。重复项点名同一 sink/根因 → 修一次。系统性模式——一个修复覆盖多条公告例如共享的损坏防护。深度验证带来的严重级下调/上调。在聊天中展示 SLA 仪表盘与摘要的头条 verdict 时要先报CONFIRMED_EXPLOITABLE 且 main 上未修复的计数而不是裸的 BREACHED 数——仪表盘按 GitHub 上报严重级分桶并把已修复公告混在一起24 BREACHED会严重高估真实积压一次运行可能有 24 条 BREACHED但实际可操作的只有约 15 条。要明确说明 BREACHED 基于上报严重级且包含已缓解项然后给出按紧急度排序的可操作清单。Step 6 — 批准后修复未经用户批准绝不开始用户选定要修的公告后按 playbook 的私有流程执行起草补丁 一个回归测试修复前失败 / 修复后通过。在security/ghsa-id分支私有 fork上暂存只做 patch 级版本号提升——绝不捆绑功能。禁运期结束前不打开公开 PR。关闭 / 回复上报者仓库安全公告 REST API 暴露state可通过PATCH /repos/activepieces/activepieces/security-advisories/ghsa-id -f stateclosed关闭但没有评论端点——对话线程仅存在于 UI。要带理由回复时先起草消息让用户粘贴到公告页面然后再关闭让上报者看到理由而不是一条光秃秃的关闭通知。输出回顾所有产物都落在.security-triage/已 gitignoreadvisories.json、sla.json、dashboard.md以及每条公告一份报告。私密内容从不提交。整个流水线把 Activepieces 的人工安全响应 playbookdocs/handbook/engineering/playbooks/security-advisory-response.mdx自动化成了可重复、可审计、可并行的确定性流程确定性步骤拉取、范围审查、SLA 计算交给脚本深度验证交给只读子代理最终裁决权始终保留给用户——这正是处理公共仓库私密漏洞积压的安全姿势。【免费下载链接】activepiecesAI Agents MCPs AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows AI Agents • MCPs for AI Agents项目地址: https://gitcode.com/GitHub_Trending/ac/activepieces创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
分享:

看完干货,该让你的企业上线了

免费需求沟通 · 48 小时内出具建站方案 · 河南本地可上门