news 2026/9/16 15:32:23

Local Deep Research(LDR)Semgrep 自定义安全规则完全指南:从 12 类漏洞检测到 SSRF 防护的源码级剖析

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
Local Deep Research(LDR)Semgrep 自定义安全规则完全指南:从 12 类漏洞检测到 SSRF 防护的源码级剖析

Local Deep Research(LDR)Semgrep 自定义安全规则完全指南:从 12 类漏洞检测到 SSRF 防护的源码级剖析

【免费下载链接】local-deep-research~95% on SimpleQA (e.g. Qwen3.6-27B on a 3090). Supports all local and cloud LLMs (llama.cpp, Ollama, Google, ...). 10+ search engines - arXiv, PubMed, your private documents. Everything Local & Encrypted.项目地址: https://gitcode.com/GitHub_Trending/lo/local-deep-research

本指南以仓库 .semgrep/rules/README.md 为核心,系统讲解 Local Deep Research(LDR)项目为自身代码库定制的 Semgrep 安全规则集:覆盖硬编码密钥、SQL/命令/代码注入、路径穿越、反序列化、SSRF、XSS、CSRF 等 12+ 类漏洞,并结合 .semgrep/rules/ldr-security.yaml、.semgrep/rules/check-safe-requests.yaml 两个规则文件的真实内容,以及 src/local_deep_research/security/safe_requests.py 的安全请求封装实现与 .github/workflows/semgrep.yml 的 CI/CD 集成,深入讲解每条规则的检测原理、适用场景、本地运行方法与扩展方式。读完本文,你将掌握如何在本仓库内运行、验证、扩展这套 LDR 专属安全规则,并理解规则如何与项目源码中的 SSRF 防护层相互印证。

LDR(Local Deep Research)是一个支持本地与云端 LLM、聚合 arXiv/PubMed 等 10+ 搜索引擎的深度研究工具。由于它天然需要发起大量外部 HTTP 请求、处理用户提供的文档与搜索词、并可能暴露 Web 端点,其安全面覆盖了经典的注入类漏洞与 LLM 应用特有的 SSRF(服务端请求伪造)风险。.semgrep/rules/目录下的自定义规则,正是为这道安全面量身定制的"门禁"。

一、为什么 LDR 需要一套自定义 Semgrep 规则

Semgrep 是静态分析工具,通过 YAML 规则文件定义代码模式,无需执行代码即可扫描语法树。官方规则库(如p/security-audit)覆盖面广,但存在两个问题:一是规则过于通用,无法体现 LDR 的架构约定(例如必须走safe_requests封装而非直接调用requests);二是官方规则缺少对项目特有 API(如 SQLAlchemy 的session.execute、Flask 的render_template_string)的精准约束。

LDR 的解决方案是双轨并行,这一点可从 .github/workflows/semgrep.yml 看出:

  1. 通用规则:运行p/security-auditp/secrets两个官方规则包;
  2. 项目自定义规则:运行--config=.semgrep/rules/指向本目录。

自定义规则与通用规则互补:官方包负责"广撒网",自定义规则负责"精准打击"——把 LDR 开发者约定的安全编码规范(禁用os.system、禁用yaml.load、禁用直接requests.get、必须参数化 SQL 等)固化成可自动执行的规则。

二、规则全景:ldr-security.yaml 的 12+ 类漏洞检测

.semgrep/rules/ldr-security.yaml 是核心规则文件。README 中列出了 12 类规则,而实际文件内实现了16 条规则(README 之外还包含 SQL 字符串格式化执行、SSL 校验关闭、危险文件权限 3 类额外检测,以及独立的 SSRF URL 抓取提醒)。下表按 README 分类整理,并标注实际 severity 与 CWE 映射:

规则 ID检测目标SeverityCWEOWASP 2021
hardcoded-secret-detection硬编码 API Key/密码/TokenERRORCWE-798A07 身份认证失效
sql-string-concatenationSQL 字符串拼接注入ERRORCWE-89A03 注入
sql-execute-with-string-formatsession.execute(f"...")等格式化执行ERRORCWE-89A03 注入
dangerous-eval-usageeval/exec/compile动态执行ERRORCWE-95A03 注入
os-system-command-injectionos.systemshell=TrueERRORCWE-78A03 注入
path-traversal-risk用户输入拼入文件路径WARNINGCWE-22A01 失效访问控制
unsafe-yaml-loadyaml.load反序列化ERRORCWE-502A08 软件与数据完整性失效
unsafe-pickle-loadpickle.load(s)/cPickle.loadERRORCWE-502A08 软件与数据完整性失效
weak-random-generationrandom模块用于安全场景WARNINGCWE-338A02 加密失败
flask-debug-mode-enabledFlaskdebug=TrueERRORCWE-489A05 安全配置错误
insecure-ssl-verification-disabledverify=False关闭证书校验ERRORCWE-295A02 加密失败
dangerous-file-permissionschmod 0o777/0o666WARNINGCWE-732A01 失效访问控制
ldr-url-fetching-ssrfrequests.get/posturlopen抓取 URLWARNINGCWE-918A10 SSRF
ldr-user-input-in-html用户输入进入 HTML 上下文WARNINGCWE-79A03 注入
ldr-missing-csrf-protectionPOST 端点缺少 CSRF 提醒INFOCWE-352A01 失效访问控制
ldr-password-in-logs密码写入日志/printERRORCWE-532A09 安全日志与监控失败

三、逐类规则深度解析:模式、原理与修复建议

3.1 硬编码密钥检测(CWE-798,ERROR)

规则hardcoded-secret-detection使用pattern-either匹配四种赋值形态:

- pattern: $VAR = "sk-..." - pattern: $VAR = 'sk-...' - pattern: password = "..." - pattern: api_key = "..." - pattern: secret = "..." - pattern: token = "..."

其中sk-...模式专门针对 OpenAI 风格的 API Key 前缀(LDR 支持 OpenAI 兼容的本地/云端模型,这类密钥形态在项目中高度相关)。触发后规则要求改用环境变量或安全配置存储凭据。这与项目中 .github/workflows/gitleaks.yml 等密钥泄露防线形成互补:Semgrep 在代码库内查"写死的密钥",Gitleaks 在 git 历史中查"已泄露的密钥"。

3.2 SQL 注入防护(CWE-89,ERROR)

LDR 的存储层基于 SQLAlchemy,因此规则聚焦 SQLAlchemy 的注入面。sql-string-concatenation匹配三类字符串拼 SQL 的写法:

- pattern: | $QUERY = "..." + $USER_INPUT + "..." - pattern: | $QUERY = f"...{$USER_INPUT}..." - pattern: | $QUERY = "..." % ($USER_INPUT)

sql-execute-with-string-format更进一步,直接拦截执行层的危险调用:

- pattern: $SESSION.execute(f"...") - pattern: $SESSION.execute("..." + ...) - pattern: $ENGINE.execute(f"...")

规则消息明确要求使用 SQLAlchemy 的参数化写法text()with parameters。两条规则双保险:无论拼接发生在查询构造阶段还是执行阶段都会被捕获。

3.3 代码注入与命令注入(CWE-95 / CWE-78,ERROR)

dangerous-eval-usage匹配eval($X)exec($X)compile($X, ...)三个动态执行入口,防止任意代码执行。os-system-command-injection则覆盖 Python 中最常见的命令注入面:

- pattern: os.system($CMD) - pattern: subprocess.call($CMD, shell=True) - pattern: subprocess.Popen($CMD, shell=True) - pattern: subprocess.run($CMD, shell=True)

修复方向是改用subprocess的参数列表形式(subprocess.run(["ls", "-l"], ...)),避免 shell 解释用户输入。对于 LDR 这类需要调用本地工具链(如向量化、PDF 解析)的项目,这类规则能有效阻止"命令拼接"反模式混入代码库。

3.4 路径穿越(CWE-22,WARNING)

path-traversal-risk匹配四类将用户输入拼入文件路径的写法:

- pattern: open($PATH + $USER_INPUT, ...) - pattern: open(f"{$PATH}/{$USER_INPUT}", ...) - pattern: Path($USER_INPUT) - pattern: os.path.join($PATH, $USER_INPUT)

注意此类规则设为 WARNING 而非 ERROR,因为部分场景(如用户明确指定输出路径)属于合理使用,仅需提示开发者校验与净化。这与仓库中 src/local_deep_research/security/path_validator.py、src/local_deep_research/security/filename_sanitizer.py 等运行时校验模块形成呼应:静态规则负责"提醒",运行时模块负责"拦截"。

3.5 不安全反序列化(CWE-502,ERROR)

两条规则分别针对 YAML 与 pickle:

- id: unsafe-yaml-load pattern: yaml.load($X, ...) - id: unsafe-pickle-load pattern-either: - pattern: pickle.load($X) - pattern: pickle.loads($X) - pattern: cPickle.load($X)

yaml.load在旧版本 PyYAML 中可执行任意对象构造,pickle系列更是公认的任意代码执行入口。规则强制改用yaml.safe_load(),pickle 则建议替换为 JSON 等安全格式。

3.6 弱随机数(CWE-338,WARNING)

weak-random-generation匹配random.random()random.randint(...)random.choice(...),提示安全敏感操作(Token 生成、会话 ID 等)必须使用secrets模块。LDR 作为涉及用户会话与 API 凭据的应用,这一约束能防止开发者顺手用random生成可预测的凭据。

3.7 生产环境调试模式(CWE-489,ERROR)

- pattern: app.run(debug=True) - pattern: app.config["DEBUG"] = True

Flask 调试模式会暴露 Werkzeug 调试器(可远程执行代码)与敏感堆栈信息,属于信息泄露风险,规则以 ERROR 级别硬性禁止。

3.8 SSRF 提醒(CWE-918,WARNING)

ldr-url-fetching-ssrf匹配requests.get($URL)requests.post($URL)urllib.request.urlopen($URL),提醒开发者校验 URL 防止对内网资源的 SSRF 攻击。这条 WARNING 规则是 LDR 安全体系中最有特色的部分——项目不仅有静态提醒,还有配套的强制规则与运行时实现,详见第四节。

3.9 XSS 与 CSRF(CWE-79 / CWE-352)

ldr-user-input-in-html匹配两类把用户输入注入 HTML 上下文的写法:

- pattern: | render_template_string($TEMPLATE, user_input=$INPUT) - pattern: | f"<html>...{$USER_INPUT}...</html>"

要求使用 Jinja2 自动转义。ldr-missing-csrf-protection则以 INFO 级别提醒 POST 端点(模式为@app.route($PATH, methods=["POST"])的函数体)必须启用 CSRF 保护——INFO 级别说明它属于"开发提醒"而非"阻断错误",避免误报干扰正常开发流程。

3.10 凭据日志泄露(CWE-532,ERROR)

- pattern: logger.info(..., password=...) - pattern: logger.debug(..., password=...) - pattern: logger.error(..., password=...) - pattern: print(..., password=...)

禁止将密码写入任何日志级别或标准输出。LDR 项目在运行时侧还提供了 src/local_deep_research/security/log_sanitizer.py 与 src/local_deep_research/security/secure_logging.py 作为纵深防御——即使开发者在日志调用中意外传入敏感参数,运行时也会在落盘前净化。

四、SSRF 防护的完整闭环:强制规则 + 运行时实现

4.1 check-safe-requests.yaml:把"必须走封装"变成 ERROR

.semgrep/rules/check-safe-requests.yaml 是第二份规则文件,包含 6 条规则,全部针对SSRF 防护的"架构强制"——禁止绕过安全封装直接调用requests库:

规则 ID匹配模式要求
unsafe-requests-getrequests.get(...)改用safe_get()
unsafe-requests-postrequests.post(...)改用safe_post()
unsafe-requests-sessionrequests.Session()改用SafeSession()
unsafe-requests-putrequests.put(...)改用SafeSession()
unsafe-requests-deleterequests.delete(...)改用SafeSession()
unsafe-requests-patchrequests.patch(...)改用SafeSession()

这 6 条规则的 severity 全部为 ERROR,且通过paths.exclude精准放行例外区域:

paths: exclude: - "**/security/safe_requests.py" # 封装自身 - "**/tests/**" # 测试用例 - "**/*_test.py" - "**/test_*.py" - "**/examples/**" # 示例代码

规则消息直接给出修复指引:from ...security import safe_get,访问 localhost 服务时用safe_get(url, allow_localhost=True)。这意味着 LDR 代码库中任何新增的、未经过 SSRF 校验的 HTTP 调用都会在 CI 阶段被 ERROR 拦截——把安全架构约定从"文档建议"升级为"硬性门禁"。

4.2 运行时实现:safe_requests.py 的六重防护

被规则"强制使用"的封装位于 src/local_deep_research/security/safe_requests.py,提供safe_get(L202)、safe_post(L353)、SafeSession(L512)、safe_get_with_retries(L699)四个入口。其防护机制可拆解为六层:

  1. URL 预校验:每次请求前调用ssrf_validator.validate_url(),拒绝命中内网/元数据地址的 URL(校验逻辑在 src/local_deep_research/security/ssrf_validator.py)。allow_localhostallow_private_ips参数用于放行可信的自托管服务(如 SearXNG、Ollama),但云端元数据端点(AWS/Azure/OCI 等)始终被封锁。
  2. DNS 固定(DNS Pinning):通过dns_pinning.pinned_request()将"解析并校验过的 IP"固定为实际连接地址(src/local_deep_research/security/dns_pinning.py),堵住"解析-连接"间隙中的 DNS 重绑定攻击(TOCTOU)。
  3. 逐跳重定向校验safe_get/safe_post关闭requests原生重定向,手动跟随每个 301/302/303/307/308 跳转,对每个目标 URL 重新执行 SSRF 校验,最多跟随_MAX_REDIRECTS = 10次(L31-L34)。
  4. 凭据隔离_headers_for_redirect()SafeSession.rebuild_auth()在跳转离开凭据作用域时剥离authorizationcookie以及*key/*token/*secret后缀的请求头,防止 API Key 泄露给重定向目标(L168-L199、L567-L585)。
  5. 响应大小护栏MAX_RESPONSE_SIZE = 1GB(L28),_check_response_size()校验Content-Length,缺失或可疑时安装有界读取器(body guard)防止内存耗尽(L95-L148)。
  6. 超时与重试:默认DEFAULT_TIMEOUT = 30秒(L23);safe_get_with_retries对连接错误、超时、429/5xx 状态码执行指数退避重试(_RETRY_BACKOFF_SECONDS = (1, 2, 4)),并解析Retry-After头(上限 300 秒,L662-L696)。

上述行为在 tests/security/test_check_response_size.py 等测试中得到验证(例如SafeSession.send()的中间重定向分支测试),形成"规则强制使用封装 → 封装实现防护 → 测试验证防护"的完整闭环。

五、本地运行与 CI/CD 集成

5.1 本地命令行使用

README 给出的两条核心命令,第一条仅运行 LDR 自定义规则,第二条叠加官方审计规则包:

# 仅运行 LDR 自定义规则扫描 src/ 目录 semgrep --config=.semgrep/rules/ src/ # 官方安全审计规则 + LDR 自定义规则 semgrep --config=p/security-audit --config=.semgrep/rules/ src/

可结合 severity 过滤(如--severity=WARNING)或输出 JSON(--json)用于脚本消费。注意:p/security-auditp/secrets需要网络访问 Semgrep Registry 下载规则包。

5.2 CI/CD 工作流:semgrep.yml 的完整流程

规则由 .github/workflows/semgrep.yml 驱动的 Semgrep 扫描工作流自动执行,该工作流可被 release-gate.yml 等发布门禁调用(workflow_call)。关键设计:

  • 扫描分两阶段:第一阶段运行p/security-audit+p/secrets--severity=INFO全量收集),第二阶段运行.semgrep/rules/自定义规则,各产出独立 JSON;
  • 崩溃检测:扫描命令以|| true兜底,随后检查 JSON 文件是否生成——若 Semgrep 崩溃未产出文件,则输出::error::并失败退出,避免"静默跳过扫描";
  • 结果合并与 SARIF 转换:Python 脚本合并两个 JSON 为semgrep-combined-results.json,再转换为 SARIF 2.1.0 格式;
  • 上报 GitHub Security 标签页:通过github/codeql-action/upload-sarif上传,category: semgrep-security。工作流注释特别强调:绝不能伪造空的 SARIF 文件,否则会把所有已修复的历史告警误标为"已修复"(L177-L182);
  • 门槛汇总:在 GitHub Actions Summary 中统计 ERROR/WARNING/INFO 数量,ERROR 或 WARNING 大于 0 时标注"需要处理"。

环境中还需注意 Python 3.12 的兼容细节:工作流固定setuptools<82(82.0 移除了pkg_resources),并固定semgrep==1.87.0(L35-L40)。

六、扩展规则:新增规则三步走与模板

README 给出了向.semgrep/rules/添加新规则的流程,结合本仓库实践可细化为:

  1. 创建规则文件:在.semgrep/rules/下新建 YAML 文件(如my-rule.yaml),参考 .semgrep/rules/ldr-security.yaml 的既有写法(pattern-eithermetadatapaths.exclude等);
  2. 本地验证semgrep --config=.semgrep/rules/your-rule.yaml src/单独测试该规则,确认命中率与误报率;必要时用--validate校验规则语法;
  3. 文档同步:在 .semgrep/rules/README.md 的规则清单中登记新规则(ID、检测目标、Severity、CWE)。

项目规定的规则模板如下(含 metadata 规范):

rules: - id: your-rule-id pattern: | # Your pattern here message: Description of the security issue languages: [python] severity: ERROR # or WARNING, INFO metadata: category: security cwe: "CWE-XXX: Description" owasp: "AXX:2021 - Category"

实践要点:metadata中的cweowasp字段会被 CI 工作流的 SARIF 转换读取(.github/workflows/semgrep.yml),直接影响 Security 标签页的告警信息完整性;多模式规则优先使用pattern-either(参见 ldr-security.yaml 中hardcoded-secret-detection的写法);需要排除测试或封装自身时,用paths.exclude精确放行(参见 check-safe-requests.yaml)。

七、参考与延伸

本仓库相关文件索引:

  • 规则文档:.semgrep/rules/README.md
  • 通用安全规则集:.semgrep/rules/ldr-security.yaml
  • SSRF 强制规则集:.semgrep/rules/check-safe-requests.yaml
  • SSRF 运行时封装:src/local_deep_research/security/safe_requests.py
  • URL 校验器:src/local_deep_research/security/ssrf_validator.py
  • DNS 固定实现:src/local_deep_research/security/dns_pinning.py
  • 运行时日志净化:src/local_deep_research/security/log_sanitizer.py
  • CI/CD 集成:.github/workflows/semgrep.yml
  • 安全封装测试:tests/security/test_check_response_size.py

规则所映射的行业标准(OWASP Top 10 2021、CWE Top 25、Semgrep 官方 Registry 规则包)均可在公开标准文档中查阅;本仓库通过metadata.cwemetadata.owasp字段在每条规则上建立了到这两套标准的追踪链,这也是静态分析结果可审计、可整改、可追溯的关键。

【免费下载链接】local-deep-research~95% on SimpleQA (e.g. Qwen3.6-27B on a 3090). Supports all local and cloud LLMs (llama.cpp, Ollama, Google, ...). 10+ search engines - arXiv, PubMed, your private documents. Everything Local & Encrypted.项目地址: https://gitcode.com/GitHub_Trending/lo/local-deep-research

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/16 15:31:47

Agent-Skills:面向AI原生应用的可插拔能力工程化实践

1. 项目概述&#xff1a;一个被严重低估的“技能容器”设计范式“agent-skills”这个标题乍看像某个开源库的包名&#xff0c;但真正把它拆开来看——agent是智能体的行为主体&#xff0c;skills是可插拔、可组合、可验证的能力单元——它本质上定义了一种现代软件工程中正在快…

作者头像 李华
网站建设 2026/9/16 15:31:45

Django学生信息管理系统开发实战:从数据库设计到部署答辩

简介&#xff1a;这套基于Python与Django框架实现的学生信息管理系统源码&#xff0c;是针对计算机专业毕业设计需求整理的完整项目包&#xff0c;尤其适合需要快速搭建Web管理系统演示环境的本科生。资源压缩包体积仅3.67MB&#xff0c;内部包含1108个文件&#xff0c;其中Pyt…

作者头像 李华
网站建设 2026/9/16 15:31:10

C语言通讯录管理系统进阶:结构体、文件读写与内存管理实战

简介&#xff1a;面向初学C语言及课程设计的学生&#xff0c;这份DevC通讯录管理系统项目完整覆盖通讯录的录入、显示、排序、查找、插入、删除与修改等核心功能&#xff1b;通讯录字段涵盖姓名、单位、手机、分类、EMAIL、QQ等&#xff0c;排序支持按姓名、单位、城市等多种方…

作者头像 李华
网站建设 2026/9/16 15:30:32

Java Web基础实战:Servlet+JSP校园二手交易系统

简介&#xff1a;本资源是一套面向计算机专业本科生的毕业设计级校园二手交易平台完整实现&#xff0c;采用JSPServletMySQL经典Java Web技术栈&#xff0c;覆盖用户管理、商品发布与浏览、交易流程、消息通知及基础安全防护等核心模块&#xff0c;适用于课程设计、毕设参考与W…

作者头像 李华