- 网络安全
- 渗透测试
- 漏洞扫描
【免费下载链接】faraday
Open-source and AI-powered cybersecurity tools for offensive security, vulnerability management, and autonomous pentesting. Built by hackers in Latin America, used worldwide.
本文以 Faraday 项目 5.14.1 版本的社区变更日志(CHANGELOG/5.14.1/community.md)为主体,逐一拆解该版本两项核心修复——CSV 导出的内存占用问题(#7981)与重复上传同一报告导致漏洞重复(#7983)。读完本文,你将理解 Faraday 的 CSV 导出两种模式的取舍逻辑、PostgreSQL ON CONFLICT 去重原理、漏洞状态合并规则,以及配套的测试与迁移证据,可直接用于排查和验证同类问题。
版本背景:5.14.1 的发布定位
根据 CHANGELOG/5.14.1/date.md,5.14.1 发布于 2025 年 6 月 4 日。社区版(community)变更日志共两条,均为 FIX 类型,集中在两个用户可感知的痛点:
- CSV 导出时的内存问题(#7981)
- 重复上传同一份报告时出现重复漏洞(#7983)
两条修复分别落在「数据导出」与「报告导入/批量写入」两条核心链路上。前者关乎大工作区导出的稳定性,后者关乎漏洞数据的唯一性,都属于安全运营日常中高频触碰的能力。下文结合当前仓库源码逐条展开。
修复一(#7981):CSV 导出的内存问题与"受限导出"模式
问题表象与根因方向
Faraday 的漏洞列表导出到 CSV 时,需要把查询结果序列化、拼装成表头与行数据。若工作区内漏洞数量巨大、且每条漏洞携带request、response、description、data等大字段,一次性在内存中构建完整 CSV 会占用可观内存,甚至拖垮服务进程。5.14.1 的修复目标是降低这条路径的内存压力。
两条导出路径:export_csv 与 export_csv_limited
从 API 层看,漏洞过滤/查询端点同时支持两种 CSV 导出参数(faraday/server/api/modules/vulns_base.py):
| 参数 | 含义 | 默认输出文件名 |
|---|---|---|
export_csv=true | 全量导出,包含完整列集合与主机/服务关联信息 | Faraday-SR-Context.csv(工作区模式下为Faraday-SR-<workspace_name>.csv) |
export_csv_limited=true | 受限导出,仅输出精简字段,降低内存占用 | Faraday-SR-Limited.csv |
两个参数是互斥的:当两者同时为true时,API 直接返回 400"export_csv and export_csv_limited are mutually exclusive"。
全量导出在 faraday/server/utils/export.py 的export_vulns_to_csv中实现,列集合非常宽——包含漏洞自身的confirmed/id/date/name/severity/service/target/desc/status/hostnames/comments/owner/os/resolution/refs/easeofresolution/web_vulnerability/data/website/path/status_code/request/response/method/params/pname/query/cve/cvss2~cvss4/cwe/policyviolations/external_id/impact 系列/update_date,再拼接主机侧host_id/host_description/mac/host_owned/host_creator_id/host_date/host_update_date与服务侧service_id/service_name/.../service_parent_id等字段。测试 tests/test_api_vulns.py(test_export_vuln_csv_empty_instance)对这份表头集合做了完整断言,可作为列结构的权威清单。
受限导出的内存优化手段
与全量导出不同,export_vulns_to_csv_limited(faraday/server/utils/export.py)从源头削减数据量:
- 源码注释明确写到"Limit fields to essential ones to reduce memory usage"(缩减到必要字段以降低内存使用);
- 默认只保留
id/_id/name/severity/status/confirmed/target/hostnames/service/type/owner/tags/metadata/external_id/cve/cwe/cvss2/cvss3/cvss4/risk/impact/easeofresolution/custom_fields等"轻量"字段; description/desc/request/response/data/resolution/refs/policyviolations/_attachments这类大字段被列入large_fields集合,默认剔除;- 若调用方在
q参数中显式指定columns列表,则按所选列输出,并配合 API 层缩小exclude_list(仅排除_attachments),让用户按需取回大字段(faraday/server/api/modules/vulns_base.py); - 写入时通过
extrasaction='ignore'忽略未选字段,逐行csv_escape后再输出,避免整表先物化再裁剪。
这条"默认精简 + 按需选列"的机制,正是针对 #7981 内存问题给出的工程化答案:将"导什么"的决定权从服务端固定全量,下放到用户可控的有限集合。
顺带的安全加固:CSV 公式注入防护
与导出相关的另一处实现细节是csv_escape(faraday/server/utils/export.py):凡值以=、+、-、@开头的单元格,都会前置单引号',避免导出文件被 Excel 等表格软件当作公式执行——这是导出能力中不可省略的安全防线。
修复二(#7983):重复上传同一报告不再产生重复漏洞
问题链路:上传 → 插件解析 → 批量写入
报告的导入链路为:upload_reportAPI 接收文件 → 存入磁盘 → 由 Celery 任务调用process_report(faraday/server/utils/reports_processor.py)→ 插件解析生成vulns_data→ 经send_report_data走BulkCreateSchema校验后进入bulk_create。也就是说,重复上传同一报告,本质上是把同一批漏洞数据重复提交给批量创建流程。若无幂等保护,同一漏洞会以多条记录的形式反复插入。
去重核心:PostgreSQL ON CONFLICT 复合唯一键
批量写入的核心实现在 faraday/server/api/modules/bulk_create.py 的insert_vulnerabilities。它使用 SQLAlchemy 的 PostgreSQL 方言insert(...).on_conflict_do_update(...),冲突判定基于一组复合冲突键:
md5(name), md5(description), type, COALESCE(host_id, -1), COALESCE(service_id, -1), COALESCE(md5(method), ''), COALESCE(md5(parameter_name), ''), COALESCE(md5(path), ''), COALESCE(md5(website), ''), workspace_id, COALESCE(source_code_id, -1)对名字、描述、HTTP 方法、参数名、路径、网站等文本字段做md5归一化,再用COALESCE把空值折叠为占位值,保证NULL也能参与冲突比较。同一工作区内,只要上述签名一致的漏洞再次到来,就会命中冲突分支而不会新增记录——这正是 #7983 修复的落点。
命中冲突后的状态合并规则
冲突命中时(on_conflict_do_update的set_部分),Faraday 不是简单覆盖,而是按语义合并:
- 状态流转:若新传入状态为
closed而库中为open/re-opened,则关闭它;若新传入为open而库中为closed,则置为re-opened;否则保留原状态; last_detected与update_date:仅在传入状态属于open/re-opened(即"再次检测到")时刷新为导入时刻,避免纯更新操作误改检测时间;- 自定义字段:以新传入的
custom_fields覆盖。
测试 tests/test_api_bulk_create.py(test_bulk_create_on_closed_vuln)验证了"库中 closed + 传入 open"场景最终状态为re-opened;tests/test_api_bulk_create.py(test_create_existing_host_vuln)则断言重复写入后漏洞总数仍为 1,且旧 references 被保留——两条用例分别锁死了"不重复"与"状态/关联正确合并"两个行为。
辅助机制:_tmp_id列
为了让冲突更新后的关系数据(references、credentials、CWE/CWE 关联等)能正确挂回旧记录,迁移 faraday/migrations/versions/33094e577642_add__tmp_id_for_on_conflict_inserts.py 早在 2023 年 9 月就为vulnerability表新增了可空的_tmp_id列。冲突更新时把新插入行的 id 写入_tmp_id("_tmp_id": stmt.excluded.id),随后manage_relationships(faraday/server/api/modules/bulk_create.py)依据returning(Vulnerability.id, Vulnerability._tmp_id)的结果判断每行是"新建"(created)还是"冲突更新"(updated),再决定关系数据挂到哪个真实 id 上。
历史设计脉络:模型层的去重字段
从更早的迁移 faraday/migrations/versions/526aa91cac98_vulnerability_merge_model.py(2019 年)可以看到,vulnerability表还保留过vulnerability_duplicate_id、disassociated_manually等字段,配合knowledge_base表做知识库级的重复判定与手动解除关联。可以推断:Faraday 的"防重复"能力经历了从知识库模板合并(早期迁移)到 PostgreSQL 冲突键(当前批量写入)的演进,5.14.1 的 #7983 是在后者这条主链路上的收敛修复。
后续演进视角:5.25.0 的相关完善
把 5.14.1 的两项修复放在时间轴上,可以看到后续版本仍在持续打磨同一块能力(CHANGELOG/5.25.0/community.md):
- 重新导入 open/re-opened 漏洞时刷新
last_detected与update_date(#8518); - 导出含 Last Detected 列的 CSV 不再返回 400(#8460)。
这与 5.14.1 修复的"导入去重 + 导出稳定性"主题一脉相承,也从侧面说明:去重并非简单的"不再插入",而是要精确回答"何时算再次检出、何时刷新时间戳、何时合并状态",这正是insert_vulnerabilities中那段case表达式的职责所在。
实操验证建议
若你正在使用或部署 Faraday,可以按以下方式验证本文所述行为:
- 验证 CSV 导出:对漏洞列表端点分别请求
export_csv=true与export_csv_limited=true(例如GET /v3/ws/<workspace>/vulns?export_csv_limited=true),对比输出列数与内存/响应体大小;在同一请求中同时带上两个参数,应得到 400 响应,印证互斥逻辑; - 验证去重:对同一份扫描报告(如 tests/data/nmap_plugin_with_api.xml)连续上传两次,观察
vulns表记录数不增长、且已有漏洞的status/last_detected/update_date按规则变化; - 核对列结构:以 tests/test_api_vulns.py 断言的全量表头清单为基准,检查导出文件的列顺序与内容是否一致。
小结
5.14.1 的两条 FIX 分别命中「导出的资源效率」与「导入的数据一致性」:export_csv_limited用精简字段集换内存空间,on_conflict_do_update用复合签名换记录唯一性。二者都以「用户操作高频、失败代价高」的场景为靶点,是读懂 Faraday 数据管线的两个极好切面——阅读 faraday/server/utils/export.py 与 faraday/server/api/modules/bulk_create.py 即可掌握完整实现。
- 网络安全
- 渗透测试
- 漏洞扫描
【免费下载链接】faraday
Open-source and AI-powered cybersecurity tools for offensive security, vulnerability management, and autonomous pentesting. Built by hackers in Latin America, used worldwide.
相关推荐
高效URL去重与内存优化:猫抓cat-catch防重复机制深度解析
高效URL去重与内存优化:猫抓cat catch防重复机制深度解析 你是否遇到过浏览器扩展因重复资源检测导致的性能问题?作为一款Chrome资源嗅探工具,猫抓(
音视频Readest 重复导入修复解析:calibre 随机 UUID 与 EPUB 去重元数据哈希机制
Readest 重复导入修复解析:calibre 随机 UUID 与 EPUB 去重元数据哈希机制 导读 本文基于 Readest 仓库中的 issue 记录与
桌面应用跨平台前端MaxKB去重策略:重复内容过滤机制
MaxKB去重策略:重复内容过滤机制 重复内容处理的挑战与重要性 在企业级知识库系统中,重复内容是一个普遍存在且严重影响系统性能的问题。当用户上传大量文档、网页
人工智能大模型AI AgentRAG后端前端流程编排
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考