OSS-Fuzz 接入 JavaScript / Node.js 项目实战指南从 project.yaml 到 Jazzer.js Fuzz Target 的完整落地【免费下载链接】oss-fuzzOSS-Fuzz - continuous fuzzing for open source software.项目地址: https://gitcode.com/gh_mirrors/os/oss-fuzz本文以 OSS-Fuzz 官方文档 docs/getting-started/new-project-guide/javascript_lang.md 为主线系统讲解如何在 OSS-Fuzz 中为 JavaScriptNode.js及可转译为 JavaScript 的项目如 TypeScript搭建持续模糊测试fuzzing工程。你将掌握project.yaml、Dockerfile、build.sh、fuzz target 编写与FuzzedDataProvider使用的完整流程并了解 Jazzer.js 在底层如何驱动 libFuzzer 执行模糊测试。读完即可参照 projects/javascript-example 与 projects/typescript-example 两个官方示例项目把自有 JS 项目接入 OSS-Fuzz。JavaScript 项目接入 OSS-Fuzz 的整体流程将 JavaScriptNode.js项目集成进 OSS-Fuzz 的过程与通用的 Setting up a new project 流程高度相似同样需要提供project.yaml项目元数据、Dockerfile构建环境、build.sh构建脚本以及若干 fuzz target模糊测试入口。JavaScript 项目的关键差异集中体现在三处语言与引擎选择language必须声明为javascriptfuzzing engine 仅支持libFuzzersanitizer 使用none基础镜像Dockerfile 以gcr.io/oss-fuzz-base/base-builder-javascript为起点镜像内预装 Node.js 与npm模糊测试引擎JS 模糊测试由 Jazzer.js 驱动它工作在 JavaScript 源码层面因此对任何可转译为 JavaScript 的语言如 TypeScript都适用。下文将按照 环境 → 配置 → 编写 fuzz target → 构建 → 数据提供器 的顺序逐步展开。Jazzer.jsJavaScript 模糊测试引擎OSS-Fuzz 中的 JavaScript 模糊测试由 Jazzer.js 提供能力该引擎在构建阶段由基础镜像自动安装。与基于 JVM 的 JazzerJava不同Jazzer.js 直接作用于JavaScript 源码层面source-code level这意味着它不需要把被测代码编译成特殊格式普通 Node.js 模块即可被 fuzz任何能转译为 JavaScript 的语言典型如 TypeScript都能复用同一套 fuzz 流程fuzz target 以普通 Node.js 模块形式存在导出名为fuzz的函数即可fuzz target 的具体形态可参考 Jazzer.js 官方的 Usage 文档。Jazzer.js 在底层依赖 libFuzzer 的 native addon 完成覆盖率引导coverage-guided的变异与反馈同时负责将命令行参数转发给该 addon——这正是compile_javascript_fuzzer生成的包装脚本能无缝替换 libFuzzer的原因详见下文 build.sh 一节。官方示例项目从零理解文件组织仓库内提供了两个可直接对照学习的示例项目示例路径说明JavaScript 示例projects/javascript-example最简单的 JS 模糊测试工程包含 3 个 fuzz target 与完整构建脚本TypeScript 示例projects/typescript-example展示 TS 项目的接入方式并演示了FuzzedDataProvider的用法javascript-example的完整文件清单如下project.yaml项目元数据语言、引擎、sanitizerDockerfile基于base-builder-javascript镜像把 fuzz target 拷贝进$SRC/examplepackage.jsonnpm 依赖描述fuzz_string_compare.js、fuzz_promise.js、fuzz_value_profiling.js三个不同风格的 fuzz targetbuild.sh依赖安装与 fuzzer 构建脚本。typescript-example则额外包含tsconfig.json、target.ts与fuzz_explore_me.ts展示 TypeScript 源码经编译后进入 fuzz 流程的标准做法。project.yaml语言、引擎与 Sanitizer 声明JavaScript 项目的project.yaml中language属性必须声明为language: javascript引擎与 sanitizer 的约束如下fuzzing engine 仅支持 libFuzzerlibfuzzer目前没有其他可选项原生 sanitizer如 AddressSanitizeraddress、UndefinedBehaviorSanitizerundefined暂不支持。这类 sanitizer 只在项目包含原生插件native addons时才需要而这对 JavaScript 项目来说属于较少见的情况。如果你确实需要 ASan 或 UBSan官方建议在 Jazzer.js 仓库提交 issue 提出需求none是 JavaScript 项目的默认 sanitizer因此在project.yaml中显式书写是可选的但建议显式声明以增强可读性。一个完整的project.yaml配置如下取自 projects/javascript-example/project.yamltypescript-example 与之相同homepage: https://github.com/CodeIntelligenceTesting/jazzer.js language: javascript main_repo: https://github.com/CodeIntelligenceTesting/jazzer.js fuzzing_engines: - libfuzzer sanitizers: - none vendor_ccs: - yakdancode-intelligence.com - norbert.schneidercode-intelligence.com - peter.samarincode-intelligence.com其中vendor_ccs用于声明该项目模糊测试的维护联系人本项目为 Jazzer.js 团队实际接入你自己的项目时应替换为对应的维护者邮箱。Dockerfile基于 base-builder-javascript 搭建构建环境JavaScript 项目的Dockerfile必须以基础镜像开头FROM gcr.io/oss-fuzz-base/base-builder-javascript该 OSS-Fuzz 基础镜像已预装 Node.js 19 与npm因此通常无需再安装 Node 运行时。镜像内还预装了compile_javascript_fuzzer构建脚本详见下文。Dockerfile 中通常只需要克隆目标项目源码或像示例那样把 fuzz target 直接拷贝进镜像设置WORKDIR按需安装项目特定依赖、拷贝必要文件。以 projects/javascript-example/Dockerfile 为模板FROM gcr.io/oss-fuzz-base/base-builder-javascript COPY build.sh $SRC/ # For real projects, you would clone your repo in the next step. RUN mkdir -p $SRC/example # Ideally, you have already configured fuzz tests in your repo so that they # run (in Jazzer.js regression mode) as part of unit testing. Keeping the fuzz # tests in sync with the source code ensures that they are adjusted continue # to work after code changes. Here, we copy them into the example project directory. COPY fuzz_string_compare.js fuzz_promise.js fuzz_value_profiling.js package.json $SRC/example/ WORKDIR $SRC/example注意示例注释中强调的最佳实践建议把 fuzz test 与源码放在同一仓库中并让它们在单元测试阶段以 Jazzer.js 回归模式regression mode运行这样当源码变更导致 fuzz target 失效时能被及时发现保持 fuzz 测试与代码同步演进。Fuzz Target最简单的形态是导出一个 fuzz 函数在最简单的情况下每个 fuzzer 就是一个导出了名为fuzz的函数的单个 JavaScript 文件该函数接收一个参数类型为 Node.js 的 Buffer。以下是一个名为fuzz_string_compare.js的示例 fuzz target与 projects/javascript-example/fuzz_string_compare.js 内容一致/** * param { Buffer } data */ module.exports.fuzz function (data) { const s data.toString(); if (s.length ! 16) { return; } if ( s.slice(0, 8) Awesome s.slice(8, 15) Fuzzing s[15] ! ) { throw Error(Welcome to Awesome Fuzzing!); } };这个 target 演示了模糊测试的核心机制fuzzer 不断生成随机输入并调用fuzz(data)一旦输入恰好满足s Awesome Fuzzing!这一串条件代码就会抛出Error。Jazzer.js 基于 libFuzzer 的覆盖率反馈会逐步引导变异方向最终发现这条路径从而触发一个可被报告的崩溃crash。异步 fuzz target基于 Promise 的写法JavaScript 生态大量使用异步 API因此 fuzz target 也可以返回 Promise。示例 projects/javascript-example/fuzz_promise.js 展示了这一点它在setTimeout回调中读取三个字节若满足one two three 42则 reject 一个 Error并额外校验了异步调用的执行顺序let lastInvocationCount 0; let invocationCount lastInvocationCount 1; /** * param { Buffer } data */ module.exports.fuzz function (data) { return new Promise((resolve, reject) { if (data.length 3) { resolve(invocationCount); return; } setTimeout(() { let one data.readInt8(0); let two data.readInt8(1); let three data.readInt8(2); if (one two three 42) { reject( new Error( ${one} ${two} ${three} 42 (invocation ${invocationCount}) ) ); } else { resolve(invocationCount); } }, 10); }).then((value) { if (value ! lastInvocationCount 1) { throw new Error( Invalid invocation order, received ${value} but last invocation was ${lastInvocationCount}. ); } lastInvocationCount value; }); };使用 Buffer 原生方法的数值解析 targetprojects/javascript-example/fuzz_value_profiling.js 展示了直接用data.readInt32BE()从 Buffer 中读取大端 32 位整数并对结果做 XOR 校验后抛错的模式/** * param {number} n */ function encrypt(n) { return n ^ 0x11223344; } /** * param { Buffer } data */ module.exports.fuzz function (data) { if (data.length 16) { return; } if ( encrypt(data.readInt32BE(0)) 0x50555637 encrypt(data.readInt32BE(4)) 0x7e4f5664 encrypt(data.readInt32BE(8)) 0x5757493e encrypt(data.readInt32BE(12)) 0x784c5465 ) { throw Error(XOR with a constant is not a secure encryption method ;-)); } };该 target 还带有--sync构建参数的使用场景同步模式详见下文 build.sh。build.sh借助 compile_javascript_fuzzer 一键构建OSS-Fuzz 的 JavaScript 基础镜像预装了compile_javascript_fuzzer脚本。在build.sh中你需要安装项目依赖如有必要把 TypeScript 等语言编译为 JavaScript调用compile_javascript_fuzzer构建各个 fuzzer。compile_javascript_fuzzer脚本承担两项关键职责确保jazzer.js/core已安装从而可以使用其 CLI 执行 fuzz 测试生成一个 libFuzzer 的即插即用包装脚本——生成的脚本接受与 libFuzzer 相同的命令行参数底层只是把这些参数转发给 Jazzer.js 所用的 libFuzzer native addon。以 javascript-example 的 projects/javascript-example/build.sh 为例#!/bin/bash -eu # Install dependencies. npm install # Install Jazzer.js npm install --save-dev jazzer.js/core # Build Fuzzers. compile_javascript_fuzzer example fuzz_promise.js compile_javascript_fuzzer example fuzz_string_compare.js --sync compile_javascript_fuzzer example fuzz_value_profiling.js --sync其中compile_javascript_fuzzer的参数含义如下参数含义第 1 个参数项目在$SRC目录下的相对路径如example第 2 个参数项目内 fuzz test 文件的相对路径如fuzz_string_compare.js其余参数原样转发给 Jazzer.js CLI如--sync表示同步模式执行--sync标志指示 Jazzer.js 以同步方式执行 fuzz target适用于不依赖异步操作的简单 target对于返回 Promise 的异步 target如fuzz_promise.js则不加该标志让 Jazzer.js 处理异步完成。构建完成后OSS-Fuzz 的回归regression与持续模糊测试阶段会直接运行这些生成的 libFuzzer 包装脚本。FuzzedDataProvider把原始字节翻译成 JS 原生类型Jazzer.js 提供了FuzzedDataProvider它的作用是把 fuzzer 输入的原始字节流翻译成便于使用的 JavaScript 原始类型从而显著简化 fuzz target 的编写。其功能与 Java、C 等其他语言中的FuzzedDataProvider类似C 侧的通用思路可参考 Google 的 split-inputs 文档。使用FuzzedDataProvider的 fuzz target 写法如下const { FuzzedDataProvider } require(jazzer.js/core); /** * param { Buffer } fuzzerInputData */ module.exports.fuzz function (fuzzerInputData) { const data new FuzzedDataProvider(fuzzerInputData); const i data.consumeIntegral(4); const s data.consumeRemainingAsString(); exploreMe(i, s); };代码要点从jazzer.js/core中解构引入FuzzedDataProvider用 fuzzer 传入的 Buffer 构造 provider 实例consumeIntegral(4)从输入中消费一个 4 字节整数consumeRemainingAsString()把剩余输入整体消费为字符串随后用这两个有意义的值调用被测函数exploreMe(i, s)。这正是 projects/typescript-example 中fuzz_explore_me.ts所演示的模式TypeScript 项目把 fuzz target 写成.ts文件构建时编译为 JavaScript 后同样通过compile_javascript_fuzzer构建。该示例也证明了所有可转译为 JavaScript 的语言都能无缝复用这套 fuzz 流程。实战自查清单完成 JavaScript 项目接入后可用以下清单快速自查project.yaml中language: javascript、fuzzing_engines: [libfuzzer]、sanitizers: [none]是否齐全Dockerfile是否以FROM gcr.io/oss-fuzz-base/base-builder-javascript开头fuzz target 是否导出了module.exports.fuzz function (data) { ... }且参数类型为 Bufferbuild.sh是否依次完成npm install、安装jazzer.js/core、调用compile_javascript_fuzzer是否按 target 的同步/异步特性正确使用--sync标志复杂输入解析是否优先考虑FuzzedDataProviderconsumeIntegral、consumeRemainingAsString等以提升命中率。将上述文件放入projects/your-project/目录并提交后即可按 OSS-Fuzz 的通用项目提交流程申请接入由 OSS-Fuzz 基础设施持续运行模糊测试并报告崩溃。【免费下载链接】oss-fuzzOSS-Fuzz - continuous fuzzing for open source software.项目地址: https://gitcode.com/gh_mirrors/os/oss-fuzz创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
企业数字化 ERP 产品动态
相关推荐
1738张图片70.9%识别率:成人和小孩检测数据集实战指南 简介:本资源为面向计算机视觉初学者与目标检测开发者的成人和小孩识别数据集,适用于行人属性分析、人群计数、智能安防等场景的模型训练与验证。包内共2000个文件,以1738个txt标注文件、261张jpg原始图片及1个yaml配置文件为主,标… · 2026/9/23 4:21:28
Agent技能库实战:从描述设计到运行评估的完整方法论 做了大半年 Agent 项目,交过不少学费,要说最值的一笔,就是下定决心把"agent-skills"当成一个正经工程来做。一开始我也不觉得技能库算什么大事,代码里塞几个函数、系统提示词里堆几段描述,能跑就行。可等场景… · 2026/9/23 4:21:22
5个步骤拆解IT营源码,解决项目搭建难 5个步骤拆解IT营源码,解决项目搭建难 学会语法却不知怎么搭项目,是无数开发者卡在入门与实战之间的最大鸿沟。你背熟了 import 和 class… · 2026/9/23 4:21:22
ETF基金量化分析:3个高频面试题拆解源码 ETF基金量化分析:3个高频面试题拆解源码 刚接手一个量化交易项目,配置环境就卡半天。Python环境冲突、依赖库版本打架,折腾一下午没跑通。更坑的是,面试官直接甩出三个关于ETF基金数据处理的 高频面试题… · 2026/9/23 4:57:34
列式存储优化实战:深入Parquet与ORC的存储结构、压缩编码和查询性能调优 上周有个同事跟我倒苦水:同样的查询,在测试环境跑只要几秒,到生产环境就要十几分钟,明明加了那么多节点,为什么还是慢?我说你先别急着加机器,把数据文件打开看一眼,问题多半出在存储… · 2026/9/23 4:57:22
BERT模型架构解析与工业实践指南 1. BERT架构的核心设计理念2018年诞生的BERT模型彻底改变了自然语言处理领域的游戏规则。作为首个真正实现双向上下文理解的预训练模型,它的核心突破在于抛弃了传统的单向语言模型训练方式。我在实际项目中发现,这种双向特性让BERT在理解"银行"… · 2026/9/23 4:57:22
搞懂更省底层逻辑,源码解析帮你避开90%的坑 搞懂更省底层逻辑,源码解析帮你避开90%的坑 你是不是也陷入过这样的死循环?教程刷了不下百遍,语法记得滚瓜烂熟,可一旦动手写项目,脑子就一片空白。不是代码写不出来,是不知道哪块该放哪,逻辑链条断了。这种“看懂了但不会写”的无力感,往往源于你… · 2026/9/23 4:57:21
iOS音视频开发:AVPlayer本地与在线播放实战指南 1. 从录制到回放:AVPlayer 在音视频链路中的真实定位做 iOS 音视频录制功能时,很多人会把注意力全放在采集、编码、写文件上,等录制完成才发现一个尴尬的问题:录完的视频怎么在 App 里顺畅地播出来?这时候 AVPlayer 就… · 2026/9/23 4:57:15
2025年VR/AR技术突破与应用全景分析 1. 虚拟与增强现实行业现状全景扫描2025年的虚拟现实(VR)和增强现实(AR)技术正在经历从"技术演示"到"生产力工具"的关键转型期。根据最新行业数据,全球VR/AR设备出货量已突破1.2亿台,其… · 2026/9/23 4:57:15
3招搞定手机怎么下载微信面试难题实战项目解析 3招搞定手机怎么下载微信面试难题实战项目解析 面试被问“手机怎么下载微信”背后的原理,90%的人答不上来。别笑,这看似弱智的问题,实则是考察你对移动应用分发机制、安全校验及网络协议理解的试金石。我带过不少校招新人,他们背了八股文,却连一个A… · 2026/9/23 0:00:03
你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 你有新短消息请注意查收:3个新手避坑指南搞定消息系统选型 面试被问“高并发下如何保证消息不丢失”,你张口就是“用Redis”,结果面试官追问“如果Redis宕机了怎么办”,你瞬间卡壳。这种场景太常见了,很多新手在背八股文时,只记住了技术名词… · 2026/9/23 0:00:29