尧图网络科技YAOTU DIGITAL 获取报价
获取报价
首页 / 资讯中心 / 文章详情

Deepsec 工作区扩展实战:以 webapp 样例为蓝本编写手写 Matcher 插件与 per-project 覆盖配置

发布时间:2026/9/27 8:09:18

资讯中心
01
ARTICLE

Deepsec 工作区扩展实战:以 webapp 样例为蓝本编写手写 Matcher 插件与 per-project 覆盖配置

Deepsec 工作区扩展实战:以 webapp 样例为蓝本编写手写 Matcher 插件与 per-project 覆盖配置
应用安全漏洞扫描人工智能AI Agent【免费下载链接】deepsecDeepsec is a security harness for finding vulnerabilities in your codebase powered by coding agents项目地址https://gitcode.com/gh_mirrors/deeps/deepsec点击查看免费下载本篇文章围绕 Deepsec 仓库中的 samples/README.md 展开讲解官方提供的samples/参考材料——尤其是samples/webapp/这个虚构的 Acme 库存 Web 应用示例——在一次性初始化one-shot setup之后如何进一步扩展扫描工作区。读完本文你将掌握三类核心实战能力其一为INFO.md编写面向 AI 的仓库上下文认证模型、威胁模型、误报来源其二在generated-matchers.ts之外手写需要可执行逻辑的MatcherPlugin如带负面条件的无鉴权路由规则其三通过deepsec.config.ts与config.json两种途径为单个项目叠加priorityPaths、promptAppend、ignorePaths等覆盖配置并理解这些配置在扫描与处理管线中的实际生效机制。Samples 目录的定位setup 之后的扩展参考层先看 samples/README.md 对整套示例的定性它是一份扩展工作区extending a workspace的参考材料起点永远是npx deepsec init不要把某个样例复制过来当作初始化器使用。这背后是 Deepsec 的分层设计一次性 setup 已经完成了初始化的大部分工作——安装工作区、链接并验证 Vercel/Sandbox 与模型访问、写入INFO.md、评估结构化的 surface inventory并在覆盖存在缺口时向generated-matchers.ts追加安全的声明式 matcher见 samples/webapp/README.md。而samples/展示的是下一层声明式规则表达不了、需要可执行 matcher 逻辑的规则形态。# 从仓库根目录开始并完成一次完整 setup npx deepsec init # 之后当一个 true-positive 需要比声明式 matcher 更丰富的逻辑时 # 参考本样例的 matchers/*.ts 形态并阅读 docs/writing-matchers.md。 # 将插件注册在 generatedMatchersPlugin 旁边而不是替换它。每个样例对仓库测试而言都是自洽完整的但在真实工作区中只应复制你需要的 matcher/plugin 思路同时保留 setup 创建的项目链接、ai路由、生成式 matcher 插件和项目注册。samples/目前只包含一个条目条目内容定位samples/webapp/一个虚构的 Acme 库存 Web 应用包含手写 matcher 插件、INFO.md与 per-project 覆盖配置补充 setup 生成的generated-matchers.ts展示需要可执行 matcher 逻辑的规则webapp 样例解剖五份文件一条阅读主线webapp/被 samples/webapp/README.md 称为rich reference——一个被认真打磨过的扫描工作区长什么样。它对应一个 Next.js 15 单体仓库内部库存 采购应用约 15 万行后端 API 在src/api/、服务端库在src/lib/、管理工具在src/api/admin/与src/app/admin/、计费在src/api/billing/数据库用 Postgres Drizzle订阅用 Stripe认证用 Auth.jsNextAuth v5。建议按以下顺序阅读这五份文件samples/webapp/package.json —— 把deepsec声明为依赖deepsec: ^0.1.0type: module这是样例即工作区的基础。samples/webapp/deepsec.config.ts —— 内联加载INFO.md、通过一个 inline plugin 注册两个自定义 matcher、声明项目级覆盖。samples/webapp/matchers/webapp-debug-flag.ts 与 samples/webapp/matchers/webapp-route-no-rate-limit.ts —— 两个针对该代码库辅助函数调优的手写 matcher。samples/webapp/INFO.md —— 注入 AI prompt 的上下文认证模型、威胁模型、误报来源、值得知道的约定。samples/webapp/config.json —— 可选的 per-project 配置priorityPaths、promptAppend、ignorePaths。运行样例# 从样例目录运行monorepo 为测试把 deepsec 符号链接了进来 pnpm deepsec scan --project-id webapp --root ./your-app pnpm deepsec process --project-id webappdeepsec会从当前工作目录向上查找deepsec.config.ts所以任意子目录下运行同样有效。INFO.md注入 AI 的仓库心智模型INFO.md 的本质是一份给扫描 Agent 看的仓库安全手册它会被注入到 AI prompt 中作为仓库上下文。在 packages/core/src/config.ts 中ProjectDeclaration.infoMarkdown字段的注释明确说明它注入 Markdown 作为 repo context取代data/id/INFO.md。样例里的INFO.md展示了四个必备板块认证与授权形态Auth shape——明确每个 API handler 必须调用auth.has(req.session.user, action, resource)之后才能读写敏感数据并直接点名代码味道绝不直接req.session.user.role admin。同时记录公共 handler 必须包裹withRateLimit(handler, { window: 1m, max: 60 })而src/api/_internal/与 webhook receiver 各自例外前者走私有 VPC后者靠签名校验。威胁模型Threat model——按攻击吸引力排序跨租户访问IDOR每条记录都有companyId/userId按id读写却不按req.session.user.companyId过滤就是 IDOR权限提升在src/api/admin/users/promote.ts之外给role字段赋值Stripe webhook 重放/伪造未调用verifyStripeSignature(req)就处理 Stripe 事件供应商凭据外泄vault.encrypt(value, { context })加密解密点若省略 context、记录解密值或在 API 响应中返回解密值即为严重问题Debug-flag 绕过NODE_ENV ! production解锁/api/_dev/dump-cache等端点。误报来源False-positive sources to ignore——直接给扫描器划红线src/scripts/migrations/**一次性迁移管理员运行、src/lib/seed/**仅开发用、所有__tests__/与*.test.ts/*.spec.ts、src/api/_internal/health.ts私有 VPC 内有意不做鉴权。值得知道的约定Conventions——Drizzle 查询必须用db.query.table.findFirst({ where, with })构建器lint 禁止db.execute(sql\...)自定义safeRedirect(targetUrl)通过ALLOWED_HOSTS防开放重定向server actions 位于src/actions/以use server开头且与 API 路由一样必须调用auth.has(...)。编写INFO.md的经验它决定了 Agent 的先验知识一份写清认证边界、高价值攻击面与已知误报的INFO.md能让后续扫描与再验证revalidate阶段的判断质量显著提升。手写 Matcher 插件两个可运行样例的逐行拆解INFO.md回答仓库长什么样matcher 则回答扫描器要盯哪些语法形态。样例中的两个 matcher 都实现了 packages/core/src/plugin.ts 定义的MatcherPlugin接口export interface MatcherPlugin { slug: string; description: string; noiseTier: NoiseTier; // precise | normal | noisy filePatterns: string[]; requires?: MatcherGate; // 可选tech / sentinelFiles 门控 examples?: string[]; // 可选开发期测试契约每条必须产生候选 match(content: string, filePath: string): CandidateMatch[]; }webapp-debug-flag纯正则 环境变量门控webapp-debug-flag.ts 专门捕获仅靠环境变量旗标门控的调试表面。它的业务前提很现实生产环境偶尔会泄漏NODE_ENV ! production预览部署、env 不严格的 staging、容器默认值所以这类门控不是真正的授权边界——Agent 的任务是确认被门控的表面是否敏感、是否还有别的守卫。实现要点export const webappDebugFlag: MatcherPlugin { slug: webapp-debug-flag, description: Routes/handlers gated only by env-var debug flags, noiseTier: normal, filePatterns: [src/api/**/*.ts, src/server/**/*.ts], match(content, filePath): CandidateMatch[] { if (/\.(test|spec)\.(ts|tsx)$/.test(filePath)) return []; return regexMatcher(webapp-debug-flag, [ { regex: /process\.env\.NODE_ENV\s*!\s*[]production[]/, label: NODE_ENV ! production guard }, { regex: /process\.env\.NODE_ENV\s*\s*[]/, label: NODE_ENV development guard }, { regex: /process\.env\.DEBUG_API\b/, label: DEBUG_API env flag }, { regex: /process\.env\.ENABLE_INTERNAL_TOOLS\b/, label: ENABLE_INTERNAL_TOOLS env flag }, ], content); }, };值得注意的细节match内部自行排除测试文件/\.(test|spec)\.(ts|tsx)$/因为测试代码里到处是环境变量门控却并非漏洞noiseTier: normal表明模式选出有用的审查候选由 AI 做最终判别对应 writing-matchers.md 的噪声分层表。webapp-route-no-rate-limit负面条件与跨行上下文webapp-route-no-rate-limit.ts 是声明式 matcher 做不了的典型它需要文件里没有某个辅助函数这种负面判断以及多正则、逐行上下文窗口。业务前提该代码库的约定是每个公共 handlersrc/api/**都用withRateLimit(handler, { window, max })包裹导出或调用rateLimiter.check(...)跳过包裹的 handler 是滥用/成本放大cost amplification的候选。export const webappRouteNoRateLimit: MatcherPlugin { slug: webapp-route-no-rate-limit, description: Public API handler not wrapped in withRateLimit / rateLimiter.check, noiseTier: normal, filePatterns: [src/api/**/route.ts, src/api/**/handler.ts], match(content, filePath): CandidateMatch[] { if (/\.(test|spec)\.(ts|tsx)$/.test(filePath)) return []; if (/\/_internal\//.test(filePath)) return []; if (/\/webhooks?\//.test(filePath)) return []; const HAS_RATE_LIMIT /\bwithRateLimit\s*\(|\brateLimiter\s*\.\s*check\s*\(|\bratelimit\s*\.\s*limit\s*\(/; if (HAS_RATE_LIMIT.test(content)) return []; // 逐行扫描找出导出的 HTTP 方法/handler 声明 // 并以 i±1 到 i6 为窗口生成带行号与片段的候选 ... }, };三个关键设计路径级排除先于内容判断_internal/私有 VPC有意不加限流与webhooks?/靠签名校验代替限流直接在文件路径上排除这与INFO.md的约定一一对应负面条件先探测整份文件是否出现了限流辅助函数出现则整体返回空没有出现才逐行找export ... GET|POST|PUT|DELETE|PATCH|handler声明上下文窗口为每个匹配行构造start i-1、end i6的片段让 AI 在审查候选时能看到导出签名附近的代码matchedPattern字段则注明文件内导出的 handler 没有限流包裹。为什么这类 matcher 必须手写writing-matchers.md 明确列出了声明式 matcher 的边界它被刻意限制为安全的正则扫掠。当规则需要负面条件无鉴权辅助函数的路由声明、对同一文件的多组相关搜索、语法感知的预处理或上下文窗口、组织特有的语义以代码形式评审或准备把规则贡献回公共框架时就应该写 TypeScriptMatcherPlugin。插件注册与命名空间两个 matcher 通过 deepsec.config.ts 中一个 inline 插件注册const webappPlugin: DeepsecPlugin { name: webapp-internal, matchers: [webappDebugFlag, webappRouteNoRateLimit], }; export default defineConfig({ ai: { mode: gateway, provider: vercel }, projects: [/* ... */], plugins: [webappPlugin], });这与你发布一个 npm 插件是完全相同的形态只是定义在用户自己的配置文件里docs/plugins.md 称之为 inline-plugin。需要留意两点命名约束slug 全局唯一setup 生成器会拒绝与 built-in、插件及同次响应内部的碰撞手写变体应使用独立 slug不要依赖替换顺序slug 冲突时插件胜出——插件注册在 built-in 之后同名覆盖可用于把内置 matcher 换成更紧的组织特有版本。Per-project 覆盖配置两条路径与一条优先级规则样例展示了两种给单个项目加覆盖的途径这是为特定代码库调优扫描的最后一环。路径一deepsec.config.ts的 ProjectDeclarationProjectDeclaration在 packages/core/src/config.ts 中定义export interface ProjectDeclaration { id: string; root: string; githubUrl?: string; // https://github.com/owner/repo/blob/branch infoMarkdown?: string; // 注入 prompt 的 Markdown取代 data/id/INFO.md promptAppend?: string; // 追加到该项目 AI prompt 的自由文本 priorityPaths?: string[]; // 应优先处理的路径前缀 }样例配置projects: [ { id: webapp, root: ./your-app, githubUrl: https://github.com/acme/webapp/blob/main, infoMarkdown: fs.readFileSync(path.join(here, INFO.md), utf-8), promptAppend: Pay extra attention to /api/admin/* and /api/billing/* surfaces., priorityPaths: [src/api/admin/, src/api/billing/, src/lib/auth/], }, ],路径二config.json的运行时覆盖config.json 是可选的每项目 JSON 配置运行时落在data/webapp/config.json在 packages/core/src/paths.ts 中dataDir(projectId)与projectConfigPath(projectId)把每个项目的配置隔离在data/projectId/目录下扫描器在 packages/deepsec/src/commands/scan.ts 通过projectConfigPath(opts.projectId)读取sandbox 分区器在 packages/deepsec/src/sandbox/partitioner.ts 同样解析这份 JSON{ _comment: 可选。运行时写入 data/webapp/config.json。等价字段也可在 deepsec.config.ts 的 ProjectDeclaration 上设置priorityPaths、promptAppend两者同时存在时本文件胜出。, priorityPaths: [ src/api/admin/, src/api/billing/, src/api/auth/, src/lib/auth/, src/lib/vault/ ], promptAppend: Cross-tenant access via missing companyId scoping is the highest-impact bug shape in this codebase. Always check that DB queries filter by req.session.user.companyId., ignorePaths: [**/legacy/**, **/migrations/**, **/seed/**] }三个字段的语义值得逐一对齐到扫描管线priorityPaths路径前缀列表处理process阶段优先扫描这些前缀下的文件。样例里把admin、billing、auth、vault列为优先——这正好对应INFO.md威胁模型中的高价值攻击面权限提升、凭据外泄、跨租户。promptAppend以自由文本追加到该项目 AI prompt。样例给出了一条极强的提示跨租户访问缺失 companyId 作用域是本代码库影响最大的 bug 形态始终检查 DB 查询是否按req.session.user.companyId过滤——这是在把INFO.md里的威胁模型再次强化成 Agent 的即时指令。ignorePaths忽略的 glob 列表与INFO.md的误报来源清单migrations、seed、legacy形成双重保险。优先级规则文件覆盖声明关键规则写在 config.json 的_comment里等价字段如果同时出现在ProjectDeclaration与config.json本文件config.json胜出。这给了你两个使用层次把稳定的、跨环境不变的覆盖写进deepsec.config.ts随配置版本化把可能按环境/时间变化的覆盖放进data/projectId/config.json运行时生成、不随仓库走。与 one-shot setup 的分工什么归生成器什么归手写最后回到 samples/README.md 反复强调的分层把它与 writing-matchers.md 的规则对照就得到一份清晰的决策清单setup 生成器负责的交给generated-matchers.tssetup agent 盘点仓库入口表面、运行内置 matcher、执行确定性覆盖策略只为具体缺口未覆盖的内部 RPC 注册表、队列消费家族、框架路由原语生成 matcher 提案。这些提案以严格数据形式存在经compileDeclarativeMatchers编译模型写的 TypeScript 永远不被执行并受安全契约约束唯一 kebab-case slug、受限的相对 glob、有界的正则仅i/m/im旗标、每条必须真实命中的 examples、以及声称关闭的 surface ID。校验会拒绝未知字段、遍历性/全捕获 glob、重复 slug、空正则、反向引用、lookbehind、指数回溯形态与超大重复。编译后还会执行爆炸策略覆盖过广的 matcher 会被移除。这份文件要 review 并提交但 setup 清单与 setup-state 文件是可再生的应 gitignore。什么时候保留或编辑一个生成的 matcherwriting-matchers.md当它的文件作用域和正则描述的是稳定的仓库原语、且候选数与对应入口点数量接近时保留当 glob 跟随生成代码而非真实入口家族、正则命中的是偶然标识符而非框架形态、examples 不代表真实语法、它声称覆盖实际没覆盖到的表面、或手写 matcher 能更精确表达条件时编辑或删除它。改完跑一遍聚焦检查再全量对账pnpm deepsec scan --matchers slug pnpm deepsec setup手写层负责的本样例的matchers/上述所有需要逻辑的规则——负面条件、多组相关搜索、上下文窗口、组织特有语义。此外writing-matchers.md 建议一个被再验证为 true-positive 的发现若显示出稳定的兄弟模式sibling pattern而 setup 的入口点覆盖没有建模它也值得手写一个 matcher。规范的放置位置是放在生成插件旁边.deepsec/ ├── deepsec.config.ts ├── generated-matchers.ts └── matchers/ ├── my-route-no-auth.ts └── my-internal-rpc.ts用additiveinline plugin 注册plugins: [generatedMatchersPlugin, projectMatchers]绝不删除generatedMatchersPlugin。手写 matcher 的examples字段是可执行文档扫描器的 matcher 示例套件packages/scanner/src/tests/matcher-examples.test.ts 会迭代注册表里每个 matcher 并断言每个 example 都能产生候选会把你的每个子正则都变成一条 CI 检查因此要为每个子模式覆盖语法变体。噪声层级按 writing-matchers.md 的表选择precise命中语法本身就是强漏洞信号、normal选出有用候选、AI 判别、noisy紧边界入口家族内每个文件都值得审。提交与演进建议提交deepsec.config.ts、generated-matchers.ts和matchers/不要提交生成出来的data/id/setup/证据可再生。从样例复制思路时只拿需要的 matcher/plugin 形态保留 setup 创建的项目链接、ai路由、生成 matcher 插件与项目注册samples/README.md 的原话。若你的规则属于公共框架或通用弱点形态优先把它贡献给 Deepsec 内置 matcher 注册表而不是留在组织私有副本里writing-matchers.md 的贡献指南注册表位于 packages/scanner/src/matchers/index.ts。完整的插件契约matchers / notifiers / ownership / people / executor 五个槽位、last-wins 与 additive 的解析规则可进一步阅读 docs/plugins.md 与 packages/core/src/plugin.ts。一句话总结这套样例的用途INFO.md教 Agent 理解代码库matchers/教扫描器盯住代码形态config.json与ProjectDeclaration教管线把火力集中到高价值攻击面——三者都建立在npx deepsec init生成的工作区之上而不是替代它。赞分享应用安全漏洞扫描人工智能AI Agent【免费下载链接】deepsecDeepsec is a security harness for finding vulnerabilities in your codebase powered by coding agents项目地址https://gitcode.com/gh_mirrors/deeps/deepsec点击查看免费下载相关推荐ncmdumpGUI网易云音乐NCM格式转换完全指南解锁音乐播放自由ncmdumpGUI网易云音乐NCM格式转换完全指南解锁音乐播放自由 你是否曾在网易云音乐下载了心爱的歌曲却发现在其他播放器或设备上无法播放这种格式限制应用安全漏洞扫描人工智能AI AgentDeepsec Matcher 编写实战从 setup 自动生成的声明式 Matcher 到手写 MatcherPluginDeepsec Matcher 编写实战从 setup 自动生成的声明式 Matcher 到手写 MatcherPlugin Deepsec 的扫描覆盖能力由应用安全漏洞扫描人工智能AI Agent从零编写自己的安全规则Deepsec 自定义 Matcher 插件开发实战从零编写自己的安全规则Deepsec 自定义 Matcher 插件开发实战 Deepsec 是一款由 AI 编码智能体驱动的安全漏洞扫描工具能在你的代码库中应用安全漏洞扫描人工智能AI Agent上一篇终极指南用AB Download Manager实现高效文件下载与智能管理下一篇README.md 安装说明创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
02
RELATED NEWS

相关资讯

更多网站建设与数字化升级内容

03
WHY YAOTU

想打造同款高转化官网?

懂行业、懂生意,从建站到增长一站式陪跑

◈

场景化定制

不做模板站,围绕你的业务场景量身设计,小众不撞款。

◐

营销型架构

以转化目标组织内容与路径,让官网真正带来询盘。

▲

全周期服务

设计、开发、运营、运维一体,上线只是开始。

免费获取你的建站方案

留下需求,专属顾问 24 小时内为你输出方案建议。