2025年6月9日
介绍
智能合约审计长期以来一直是 Web3 安全的重头戏。但是,当一个具有完美合约层的 dApp 通过其前端、受损的钱包集成或未经验证的预言机馈送被利用时会发生什么?这些不是假设的场景。它们是常见的现实。
现代 dApp 不再仅仅是部署在链上的 Solidity 合约。它们是由多个相互依赖的层组成的全栈应用程序,每一层都有其独特的攻击面。安全的 dApp 不仅仅是通过合约审计的 dApp。它是一个在所有层面上都经过彻底审查的 dApp:智能合约、dApp 前端、它集成的钱包、它依赖的链下组件以及它导入的库。
这篇博客分解了 Web3 应用程序的全栈安全要求,并概述了为什么智能合约审计仅仅是开始。
DApp 渗透测试:被遗忘的前线
虽然大多数项目都非常关注智能合约的安全性,但 dApp 前端(用户和区块链之间的桥梁)往往未经充分测试。这个 UI 层是用户与钱包交互、签署交易和批准 token 授权的地方。如果受到攻击,它可能与易受攻击的合约一样危险。事实上,在许多攻击中,合约从未被触及,攻击者会操纵前端或其集成,诱骗用户签署恶意 payload。
核心问题
dApp 本质上是在 Web3 上下文中运行的 Web2 应用程序。它涉及 HTML、JavaScript、APIS、CDN 托管的资产、浏览器钱包,有时还涉及后端服务。这些层中的每一层都将传统的 Web2 漏洞引入到去中心化的生态系统中。攻击者使用网络钓鱼模态框、恶意 JavaScript 注入、会话操纵和欺骗性钱包流程来劫持交易或窃取私钥。
危险在于,用户通常不了解他们签署的内容的含义。这为伪装成合法 dApp 交互的社会工程攻击创造了巨大的机会。
以下是 dApp 前端特有的关键风险的细分:
- 基于 DOM 的跨站脚本 (XSS) 对用户输入的不正确清理可能允许攻击者将任意 JavaScript 注入浏览器。在 Web3 中,这会迅速升级,攻击者可以hook到 window. ethereum,监听钱包连接,或注入恶意签名请求。
- 恶意签名流程 DApp 通常依赖于 eth_sign, personal_sign, 或 eth_signTypedData 等函数来请求用户签名。如果这些流程通过 UI 注入或逻辑错误被操纵,用户可能会被诱骗签署任意消息,这些消息授予 token 批准、所有权转移或允许链下授权。
- 过度依赖浏览器存储 许多 dApp 将敏感数据(如 JWT、auth token 甚至加密的 seed phrase)存储在 localStorage 或 sessionStorage 中。这些都可以被注入的脚本访问,这意味着一个 XSS 向量可能会危及整个会话或用户身份。
- 弱钱包交互控制 如果 dApp 不验证钱包来源(例如,在不验证其桥 URL 的情况下注入 walletconnect),它会为静默签署恶意交易的恶意钱包打开大门。
- 依赖注入和 NPM 域名抢注 现代 dApp 使用数十个 node 模块和前端库。攻击者已经利用域名抢注攻击(例如,发布 ether.js 而不是 ethers.js)或将恶意代码注入到流行的软件包中。
- 源映射和构建泄漏 DApp 经常在生产构建中泄漏源映射或 .env 文件,从而暴露内部路由逻辑、密钥或 API 端点。这些泄漏的工件可以大大减少攻击者的工作量。
- 与 IPFS/网关的不安全集成 在 IPFS 上托管前端应用程序或依赖第三方 IPFS 网关(如 Cloudflare 或 Infura)会带来完整性风险。未签名的内容可能会被替换或欺骗,尤其是当 dApp 没有pin并验证 CID 完整性时。
真正的渗透测试应该包括什么
真正的 dApp 渗透测试远不止静态扫描或 UI 测试。它包括:
攻击面枚举
- 识别暴露的文件、资产和路由
- 爬取隐藏的端点、调试控制台或开发者工具
- 分析源映射和前端逻辑以构建威胁模型
手动 XSS 和注入测试
- 在所有用户输入字段中注入 payload
- 分析 React/Vue/Next.js 应用程序中的渲染链
- 测试通过钱包连接模态框和链上数据渲染进行的脚本注入
Web3 上下文漏洞利用
- 使用虚假的 WalletConnect 桥模拟恶意 dApp
- 通过注入预先签名的 tx 来绕过钱包确认
- 测试 signMessage 和 signTypedData 流程是否存在逻辑缺陷或误导性提示
CDN 和依赖项审计
- 扫描所有第三方 JS 库中已知的 CVE
- 检查外部加载脚本的完整性哈希 (subresource integrity)
- 寻找依赖项混淆或恶意 NPM 包的迹象
网络钓鱼模拟和社会工程
- 重建 dApp 的网络钓鱼克隆,并测试用户被误导的容易程度
- 评估交易提示对最终用户的显示方式
- 测试应用程序是否阻止在其域外(尤其是在 iframe 上下文中)的签名请求
工具和技术
- 带有 DOM Invader 的 Burp Suite Pro,用于基于 JavaScript 的注入流程。
- BeEF (Browser Exploitation Framework) 用于模拟攻击者控制的浏览器。
- GraphQLmap 或 Postman 用于模糊测试暴露的 API。
- Wappalyzer 用于依赖项和框架指纹识别。
- Metasploit + ngrok 用于封闭测试网中的网络钓鱼模拟。
- 通过浏览器开发者工具和注入的脚本进行手动测试。
dApp 前端是用户做出关键决策的地方,他们通常盲目地签署数据,而不了解底层发生了什么。单个前端漏洞可以绕过最严格审计的智能合约。前端安全性不仅仅是 Web 卫生,而是保护实际资产。
如果你没有像你的合约一样严格地进行前端渗透测试,那么你就敞开了攻击面的一半。全栈安全始于浏览器,而不是区块链。
钱包安全:用户的网关是黑客的目标
Web3 生态系统中的钱包不仅仅是数字金库,它们还是用户与区块链网络交互的主要接口。因此,钱包的安全性至关重要。如果攻击者获得对用户钱包的访问权限,他们实际上就获得了对用户整个基于区块链的身份、资产和权限的访问权限。
不幸的是,钱包的安全性通常会被低估,因为许多用户没有意识到他们面临的风险。在许多攻击中,漏洞不在于智能合约或区块链基础设施,而在于用户与其钱包的交互。在这里,我们将讨论 Web3 空间中保护钱包的潜在风险、常见攻击媒介和最佳实践。
攻击面
- 网络钓鱼和伪造钱包扩展
钱包扩展(如 MetaMask 或 WalletConnect)是网络钓鱼攻击的常见目标。恶意的浏览器扩展或网站可能会提示用户连接他们的钱包,而攻击者只会窃取 seed phrase 或私钥。攻击者还可以创建伪造的钱包克隆应用程序,这些应用程序通常与真实的钱包无法区分,从而诱骗用户输入他们的私钥或 seed phrase。
- 中间人攻击
许多 Web3 应用程序要求用户通过他们的钱包签署交易,但如果钱包和 dApp 之间的连接被拦截(例如,通过公共 Wi-Fi),攻击者可以执行 MitM 攻击,操纵交易详细信息或提取签名消息以进行恶意使用。
- 通过不安全存储暴露私钥
私钥和恢复短语是钱包安全的核心。如果钱包将这些存储在不安全的位置(例如,设备上的纯文本或云存储中),攻击者可以轻松获得它们。即使是基于浏览器的钱包,有时也会遭受不安全存储实践的困扰(例如,将密钥存储在 localStorage 或 indexedDB 中)。
- 通过智能合约漏洞危害钱包
即使钱包本身是安全的,与易受攻击或恶意的智能合约交互也会使用户面临风险。例如,钱包可以签署一项批准无限 token 转账的交易,从而使攻击者可以自由支配用户的 token。这种类型的漏洞通常出现在设计不当的合约中,这些合约具有无限的 allowance 函数,或者出现在没有正确验证交易参数的合约中。
- 重入攻击和签名重放
攻击者可以利用钱包中的漏洞(例如,重入错误)来操纵基于钱包的交易。在典型的重入攻击中,攻击者诱骗钱包使用相同的请求签署多个交易。签名重放攻击还允许攻击者在不同的链上或不同的时间重放有效的交易。
强化建议
使用多重签名和多因素身份验证 (MFA):确保钱包需要多种形式的验证,无论是硬件钱包还是多重签名方法。
避免以纯文本形式存储敏感密钥:使用安全 enclave 技术或专用硬件钱包来存储私钥。
检查安全连接实践:确保所有钱包通信都通过 HTTPS 进行,并且在请求签名之前验证公钥。
进行定期安全审计:钱包应接受频繁的安全评估,重点关注加密安全、安全密钥管理和第三方库漏洞。
实施网络钓鱼保护:显示有关不受信任站点的明确警告,警告用户有关伪造钱包应用程序的风险,并在钱包连接中使用域验证。
预言机安全:无人质疑的信任假设
预言机在 Web3 生态系统中发挥着至关重要的作用。它们提供外部数据,例如资产价格、天气报告或链下事件,然后智能合约使用这些数据来做出决策。预言机通常是去中心化应用程序的关键,使真实世界的数据能够影响区块链事件。然而,预言机也引入了一个重要的攻击面,因为它们是可信实体,将去中心化的区块链与中心化的链下世界连接起来。
预言机的安全性至关重要,因为它们可能成为攻击者的目标,以操纵数据并导致去中心化金融 (DeFi) 系统,治理决策或智能合约功能的破坏。
攻击面
- 数据操纵或欺骗
预言机容易受到攻击,攻击者可以操纵或欺骗它们提供的数据。例如,攻击者可能会操纵预言机返回的数据,该数据将价格信息提供给 DeFi 协议,从而触发清算或不公平的交易。预言机操纵可能导致去中心化系统中的严重财务损失。
- 预言机提供商的中心化
许多预言机都是中心化实体,例如 Chainlink,它们提供外部数据馈送。虽然去中心化的预言机解决方案正在涌现,但中心化仍然存在重大风险。恶意行为者可能会损害中央预言机提供商并操纵数据馈送,甚至导致停机,从而可能破坏依赖于它的整个生态系统。
- 攻击预言机共识机制
去中心化预言机依赖于各种共识模型来确保数据是可信的。例如,Chainlink 使用一个去中心化的节点网络来验证输入到智能合约中的数据的准确性。但是,可以发起攻击来破坏此共识机制。通过损害足够的节点,攻击者可以操纵预言机数据。
- 时序攻击
在 DeFi 的上下文中,准确的时序至关重要。例如,预言机通常用于在特定时间触发智能合约中的操作(例如,在满足某些价格阈值时执行交易)。攻击者可以利用时序差异来操纵智能合约的行为,可能抢先交易或延迟操作。
- 预言机代码中的漏洞
预言机的代码本身可能存在可以被利用的漏洞。例如,糟糕的错误处理、不正确的加密密钥管理或未能验证数据来源都可能导致安全漏洞。此外,许多预言机系统依赖于链下代码,如果链下组件没有得到充分保护,这可能会引入漏洞。
建议
- 去中心化预言机网络:使用多个独立的预言机或聚合的预言机解决方案,以确保不存在单点故障。
- 验证数据输入:实施强大的外部数据验证,以确保它来自可信赖的来源。
- 使用加密签名:预言机提供的所有数据都应进行加密签名,以确保其真实性。
- 采用冗余:让多个独立的预言机提供相同的数据,以减少操纵信息泄露的机会。
- 定期审查和更新预言机代码:不断监控和审计 Oracle 代码,以确保尽早发现和缓解漏洞。
链下组件:隐藏的后端
你的后端可能不在链上,但它仍然存在于互联网上。互联网是一个充满敌意的环境。
Relayer 服务、机器人、cron 作业和管理 API:这些链下部分通常持有签名密钥、处理交易构建或充当 Web2 和 Web3 之间的粘合剂。而且它们经常在没有适当安全实践的情况下部署。
我们审计过这样的系统:机器人的私钥在日志中暴露,后端 API 缺乏速率限制并成为 DDoS 攻击的目标,webhook URL 公开暴露并且容易受到重放攻击。
如果你的链下代码签署交易、与合约交互或管理资金,那么它需要与你的智能合约一样多的审查。有时甚至更多。
- 后端 API、relayer、机器人、数据库服务:在审计中经常被跳过
- API 密钥泄露、速率限制不足以及私有端点泄露
- 通过 webhook 监听器或 relayer 服务(例如,MEV 机器人)进行利用
- 导致资金错误分配的服务器端逻辑错误
- 使用身份验证、白名单列list和异常检测来保护 API
外部库:继承的漏洞
没有人从头开始构建一切。我们都依赖于前端、后端甚至链上的第三方库。
域名抢注的 npm 包。对鲜为人知的库的恶意更新。ethers.js, axios 甚至简单实用程序等流行工具中的漏洞。这些是越来越常见的入口点。
聪明的攻击者并不总是利用你的代码。他们利用你信任的代码。曾经发生过这样的事件:单个更新将钱包耗尽逻辑引入到广泛使用的前端依赖项中。这悄无声息地进入了多个 DApp,没有人注意到。
你不需要偏执,但你需要可见性。锁定你的依赖项。固定版本。定期运行依赖项审计。假设每个包都可能受到威胁,除非另有证明。
智能合约审计是不够的
智能合约审计只是你的安全旅程的开始,而不是结束。
Web3 产品是全栈系统。安全的产品需要跨所有层的安全性:
- 前端 (DApp)
- 后端和 API
- 钱包交互
- 预言机
- 外部依赖项
- 当然,还有智能合约
攻击者不在乎漏洞是否存在于后端、前端还是合约中。他们关心的是在哪里可以获得访问权限或转移资产。你应该以同样的方式思考。
结论
如果你只审计智能合约,那么你只保护了你产品的一半。另一半仍然暴露、脆弱且容易被忽视。我们已经走过了合约中的单个错误可能扼杀项目的时代。现在,配置错误的服务器或恶意 npm 更新可能会以更少的噪音造成同样的损害。
现在是我们规范全范围 Web3 审计的时候了。DApp 的渗透测试。安全的钱包流程。预言机完整性检查。后端强化。库审查。安全不是复选框。它是一个持续的过程和一种心态。不要只审计你的代码。审计你的整个产品。
- 原文链接: blog.immunebytes.com/202...
- 登链社区 AI 助手,为大家转译优秀英文文章,如有翻译不通的地方,还请包涵~