代码检查器

代码检查器与 Github 无缝集成,通过由机器学习智能和我们的安全专家开发的最先进的工具驱动的自动代码分析,在开发过程的每一步最大限度地提高安全性。

对于每次代码推送,OpenZeppelin 代码检查器都会深入进行详细检查,识别潜在的漏洞并提出改进建议,以提高代码质量。它会生成一份简洁的报告,可以在 PR 评论中进行总结,以便快速直接访问,同时在 Defender 上提供更详细的报告。

用例

  • 自动对拉取请求进行安全分析,识别漏洞并提出改进建议。

  • 在拉取请求中使用摘要报告,以便立即了解代码的健康状况和安全性。

  • 访问 Defender 上的全面、详细的报告,以便深入了解潜在的漏洞和代码优化领域。

  • 使用 OpenZeppelin 的依赖项检查器来识别重用的合约,并将其与已知漏洞数据库进行匹配。

  • 将静态分析规则应用于 Solidity 文件,识别潜在问题及其严重程度,以实现高质量的代码维护。

功能

代码检查器发现的某些问题是由我们的 AI 模型检测到的。请记住,虽然我们提供了置信度,但这些模型有时可能会生成不正确或具有误导性的信息。请务必相应地验证这些信息,我们很乐意听到您的反馈。

代码检查器具有广泛的功能,旨在提高安全性、效率和代码质量。这些过程由机器学习模型和我们的安全专家开发的最先进的工具提供支持。

  • 重用代码:通过为每个合约生成唯一的指纹并将其与已知问题数据库进行匹配,来识别重用智能合约代码中的漏洞。

  • 易受攻击的依赖项:当使用具有已知漏洞的 OpenZeppelin Contracts 依赖项时发出通知,为您提供解决该问题所需的信息。

  • 测试建议:有机会对函数应用模糊测试,为您提供进一步测试可能被证明有益的领域。

  • 外部调用安全性:外部调用的安全性,突出显示任何可能构成严重问题的实例。

  • 标准兼容性:您的合约与已建立标准的兼容性,标记潜在的兼容性问题。

  • 重入攻击向量:文件和函数级别的潜在重入攻击向量,为这些威胁分配高严重性标签。

  • 代码可读性:函数中缺少文档字符串以及整个代码库中的拼写错误,确保您的代码尽可能清晰易懂。

  • 代码效率和安全实践:代码中可以进行改进以获得更好性能的领域,并突出显示潜在的安全风险,使您能够更有效地优化和保护您的合约。

安装

必须从 Defender 启动安装。直接从 GitHub 安装应用程序将无法正确设置集成。

安装过程会将您的 Defender 帐户和您的 GitHub 存储库连接起来。请按照以下步骤操作:

  1. 导航到 Defender 上的 代码检查器页面

  2. 单击“安装代码检查器”按钮,该按钮会将您重定向到 Github。

  3. 选择并批准要安装应用程序的存储库。

  4. 通过在安装了应用程序的存储库上创建或更新拉取请求来生成您的第一个报告。

安装目前仅通过 Defender 完成,确保报告的无缝连接。安装完成后,无需进行其他设置。如果您遇到安装问题,请参阅我们的 故障排除 部分以获取指导。

用法

代码检查器旨在简化您的代码分析工作流程。安装完成后,每当在您的 GitHub 存储库中打开拉取请求 (PR) 或将新提交推送到现有 PR 时,该应用程序就会被触发。为避免跳过报告,PR 必须至少包含对任何 Solidity 文件或 package.json 文件的修改。

该应用程序会自动为每个新提交生成摘要报告,该报告作为评论发布在您的 PR 中。此摘要报告会不断更新为最新提交中发现的最新问题,并且提交哈希可以直接在报告中查看。

除了 PR 评论中的摘要报告外,还会为每个提交创建一个详细报告,可以在 Defender 上访问,其中提供了有关已识别问题以及如何修复它们的深入信息。

如果您希望停止接收特定存储库的报告,只需导航到代码检查器设置并从列表中删除相应的存储库即可。

状态

以下是报告的可能状态:

  • 运行中:报告已触发,正在运行。

  • 成功:报告已成功生成,可在 Defender 和 Github 中找到。

  • 失败:报告失败。请确保您的存储库包含有效的 Solidity 文件。如果此问题仍然存在,请联系我们。

  • 已限制:由于您的租户超出代码检查器配额限制,报告已受到限制。如果您想增加配额,请联系我们。

  • 已跳过:报告已跳过。检查 PR 和/或提交是否至少包含对 Solidity 文件或 package.json 文件的修改。

报告

摘要报告

摘要报告清楚地概述了在审查过程中检测到的代码中存在的潜在漏洞。该报告方便地按流程和严重程度进行分类,从而更容易识别需要关注的区域。您可以通过提供的链接导航到 Defender 上的完整报告。每个报告都与特定的提交相关联,从而确保准确跟踪随时间的变化和问题。

摘要报告

在此示例中,您可以看到代码检查器检测到的问题数量以及它们各自的严重程度。通过单击报告底部的链接,您可以在 Defender 上查看这些漏洞的完整详细信息。

问题

完整报告使用广泛的规则识别您的智能合约中的问题。这些规则涵盖许多方面,例如已知漏洞、最佳实践、代码效率和安全编码原则。

完整报告 1

每个问题都根据对合约功能和潜在影响的安全程度分配一个严重级别。每当标记一个问题,都会有相应的解释,阐明引起关注的原因。

每个问题都有一个建议的解决方案,旨在提高您的代码质量和整体安全性。这可能包括改进代码、修改可见性范围、应用必要的数学检查、增强文档或遵守特定 Ethereum 标准的建议。

下面描述了一个在依赖项中检测到的漏洞的示例,其中简要描述了其潜在影响。其中概述了特定依赖项及其版本,从而可以查明问题所在。

依赖项检查器报告

为了帮助您解决这些问题,我们提供了有关可以解决漏洞的更新或补丁的建议,以及相关的咨询链接,以便更详细地了解该问题。

通过查看和应用此报告中提出的解决方案,您可以增强智能合约的稳健性和可靠性,确保遵守最佳实践和行业标准。这使得审计过程更加顺利,并提高了您的合约为成功部署所做的准备。

标准

此功能在报告中引入了一个名为 标准 的新部分。本节提供了对您的合约的见解,这些合约实现了来自 OpenZeppelin Contracts 库的接口。例如,如果您使用的是 IERC20,代码检查器将检查实现细节和属性,以确保您正确使用此 ERC。

详细检查

对于接口中定义的每个函数和事件,代码检查器都会执行全面的检查,以验证是否符合标准。这些检查包括:

  • 签名: 确保函数或事件签名与标准的规范匹配。例如:transfer(address,uint256)

  • 可见性: 检查函数和事件的可见性是否符合标准的要求。例如:externalpublic

  • 可变性: 对于函数,确保可变性已根据标准正确指定。例如:viewpure

  • 返回类型: 验证函数的返回类型是否与标准中定义的预期类型一致。例如:returns (bool)

  • 参数名称: 确认参数名称与标准中定义的名称一致,从而提高代码的可读性和可维护性。例如:transfer(address recipient, uint256 amount)

  • 返回名称: 确保返回变量名称(如果使用)与标准一致。例如:returns (bool success)

如果函数或事件的任何属性失败,则整个函数或事件都将标记为失败。此外,如果实现中的任何函数或事件失败,则整个实现都被认为是不合规的。

配置

您可以使用根目录中名为 defender.config.json 的文件为代码检查器配置特定于存储库的参数。该文件的结构被划分为由代码检查器运行的流程。每个流程都有一个参数列表,您可以根据需要进行调整。例如,您可以指定要扫描的目录,这对于防止代码检查器分析用 Solidity 编写的测试或脚本文件非常有用。

合约检查器

合约检查器运行一组 规则来检测代码中的潜在问题。您可以配置以下参数:

  • enabled:能够关闭合约检查器。False 表示不运行,true 表示运行。(默认值:true

  • scan_directories:要扫描的目录列表,路径从根目录开始。默认值:["."]

  • include_rules:要运行的规则列表。默认值:所有规则

  • exclude_rules:不运行的规则列表。默认值:无。

依赖项检查器

依赖项检查器验证您的依赖项是否容易受到已知问题的影响。您可以配置以下参数:

  • enabled:能够关闭依赖项检查器。False 表示不运行,true 表示运行。(默认值:true

示例

以下 defender.config.json 配置文件将禁用依赖项检查器,并在 src/contracts1src/contracts2 目录上运行合约检查器,并排除两个规则(naming-conventionunused-state)。

{
    "contract_inspector": {
        "enabled": true,
        "scan_directories": ["src/contracts1", "src/contracts2"],
        "exclude_rules": ["naming-convention", "unusued-state"]
    },
    "dependency_checker": {
        "enabled": false
    }
}

资产

“资产”页面允许您管理代码检查器资产,支持两种类型:智能合约和 GitHub 存储库。当您安装代码检查器 GitHub 应用程序并选择存储库后,它们将显示在此页面上。此外,您可以从地址簿中的地址创建智能合约资产。请注意,智能合约资产必须在 Etherscan 上进行验证,此功能才能正常工作。

可以在报告页面上手动触发智能合约资产以生成报告。可以从新的拉取请求 (PR) 和提交上手动和自动触发 GitHub 资产。

代码资产

设置

“资产设置”页面提供了两个主要设置来管理 Defender 如何处理资产安全:自动生成报告和漏洞检测。

自动触发拉取请求的报告

“自动生成报告”专门用于 GitHub 存储库。启用后,此设置通过在每次打开新的拉取请求 (PR) 或将新提交推送到 PR 时自动生成新报告来确保持续监控。

主动漏洞检测和通知

“主动漏洞检测和通知”通过自动扫描您的资产是否存在新漏洞来提供强大的安全措施。 此设置适用于 GitHub 存储库和智能合约。要为 Github 存储库资产启用此功能,您必须激活该设置并选择要监控的特定分支。

  • 自动扫描:利用 Defender 的高级智能合约扫描功能,当我们的团队意识到新的漏洞(无论是已公开还是未公开)时,我们会立即更新我们的扫描算法以检测它。然后,我们会扫描所有配置为受监控的资产

  • 自动通知:自动扫描完成后,将发送一封自动系统通知电子邮件,告知您是否在受监控的资产中检测到该漏洞。如果检测到,通知将包括根据漏洞性质量身定制的相关信息。

  • 风险缓解:当检测到时,为了帮助解决和缓解检测到的漏洞,通知可能包括风险缓解建议,从而为管理员提供可操作的步骤来保护其智能合约和关联资产。

通过为您的资产启用“主动漏洞检测和通知”,您可以受益于持续的自动扫描和及时的通知,从而使您能够快速响应新的威胁并维护智能合约和 GitHub 存储库的安全性。这种主动方法可确保您能够领先于潜在的漏洞并有效地保护您的代码。

设置

“设置”页面允许您管理代码检查器的权限和访问级别。如果您需要更改应用程序有权访问的存储库,一个便捷的链接会将您直接带到应用程序的 GitHub 设置页面,从而简化存储库管理。

在“Github”选项卡中,您可以全局暂停或卸载应用程序,从而完全控制其在项目中的运行。

代码检查器 Github

故障排除

安装问题

  • 在 Defender 之外安装应用程序:必须通过 Defender 安装代码检查器。如果您尝试从其他位置安装它,安装将不会成功。确保您已登录到您的 OpenZeppelin 帐户,然后从 Defender 导航到代码检查器以进行成功安装。

  • 代码检查器访问权限:成功安装需要访问代码检查器。如果您发现您没有访问权限并且认为这是一个错误,请联系 OpenZeppelin 支持以获取必要的权限。

存储库大小问题

与分析超时相关的错误通常是由大型代码库引起的。为了缓解此问题,建议使用 defender 配置文件中的 scan_directories 选项将分析范围仅限定于相关文件。通过指定要包含在扫描中的目录,配置文件可以显着减少处理时间并防止超时。有关设置配置文件的详细说明,请参阅 配置 部分。

规则

ID 描述 严重程度

alert-uniswap-v2-router-liquidity-considerations

识别 Uniswap Router V2 addLiquidity 调用的任何实例。

注意

array-length-to-stack

识别何时可以将数组的长度写入堆栈以节省 Gas。

注意

call-with-arbitrary-address-bytes

识别一个可能不安全的外部调用。

chainlink-deprecated-functions

识别 Chainlink 的已弃用函数的使用。

check-consistent-usage-of-msgsender-msgdata

当存在 _msgSender() 或/和 _msgData() 时,识别 msg.sendermsg.data 的使用

注意

check-effect-interact

识别检查、效果和交互模式的可能违规。

ethtrust

check-erc4337-compatibility

识别合约是否可能与 ERC-4337 不兼容。

注意

check-return-data-from-external-call

识别缺少外部调用返回数据检查的时间。

注意

constants-not-using-proper-format

识别常量未使用正确格式的时间。

注意

dangerous-strict-equality

识别可能导致僵局的严格相等的使用。

default-values-assigned

识别初始化为其默认值的变量的实例。

注意

delegatecall-to-arbitrary-address

识别何时存在到任意地址的 delegatecall 或调用代码。

delegatecall-usage

识别 delegatecall 的实例。

ethtrust

different-pragma-directives

识别是否使用不同的 Solidity 版本。

disableinitializers-not-called-in-implementation-constructor

识别是否未在 Initializable 合约的构造函数中调用 _disableInitializers()

注意

doc-code-mismatch-model

识别可能的文档字符串和代码不匹配。

duplicated-import

识别重复的导入。

注意

exact-balance

识别是否将余额与确切值进行比较。

ethtrust

external-call-reentrancy-attack-vector

将外部调用识别为重入攻击的可能向量。

注意

fallback-with-return-value

识别是否存在具有返回值的回退函数。

注意

floating-pragma

识别未指定特定、固定 Solidity 版本的 pragma 指令。

function-init-state-variable

识别何时由函数初始化状态变量。

注意

function-level-access-control-model

识别函数上可能的访问控制攻击向量。

function-level-reentrancy-model

识别函数上可能的重入攻击向量。

function-visibility-too-broad

识别函数可见性是否不必要地广泛。

注意

gas-limit-on-call

识别外部调用何时具有硬编码的 Gas 限制。

hashing-dynamic-values

识别压缩编码动态值的哈希。

ethtrust

identify-hardhat-console-import

识别 Hardhat 控制台导入。

注意

identify-to-do-comments

识别代码中的 todo 注释。

注意

inconsistent-order-contract

识别合约的顺序不一致的时间。

注意

inconsistent-use-named-returns

识别代码库中命名返回的不一致使用。

注意

incorrect-format-onERC721Received

识别当合约包含 onERC721Received 函数且格式不正确时。

注意

incorrect-modifier

识别修饰符的错误定义。

incremental-update-optimization

识别在 for 循环标头中使用 i`(而不是 `i)以节省 Gas。

注意

indecisive-license

识别何时文件具有多个 SPDX 许可证。

注意

int-negative-evaluation-overflow

识别何时评估 int 变量的加法逆。

注意

lack-of-gap-variable

识别可升级合约何时没有间隙变量。

lack-of-indexed-event-parameters

识别何时缺少索引事件参数。

注意

lack-of-security-contact

识别合约何时没有安全联系人。

注意

lack-of-spdx-license-identifier

识别何时缺少 SPDX 许可证标识符。

注意

lock-ether

识别合约中锁定的 ETH 的任何实例。

memory-side-effect-assembly

识别某些代码何时可能容易受到 Solidity 编译器漏洞的影响。

missing-docstrings

识别何时函数缺少文档字符串。

missing-initializer-modifier

识别何时函数缺少初始化器修饰符。

missing-mapping-named-parameters

识别何时映射缺少命名参数

注意

missing-return

识别何时函数缺少返回语句。

misuse-boolean-literal

检测布尔字面量的误用(用于复杂表达式或作为条件)。

msg-value-loop

识别循环内部 msg.value 的使用。

注意

multiple-contracts-per-file

识别每个文件的多个合约声明。

注意

name-reused

识别在代码库中何时有两个或多个合约具有相同的名称。

注意

non-explicit-imports

识别非显式导入。

注意

not-operator-assembly

识别组合代码中使用 not 运算符,因为它与其他语言中的功能不同。

注意

outdated-solidity-version

识别具有过时 Solidity 版本的 Solidity 文件。

注意

overriding-state-values-in-constructor

识别状态变量在合约中显式设置为值但被构造函数覆盖的情况。

注意

possible-incorrect-abi-decode

识别可能的不正确的 ABI 解码。

注意

possible-return-bomb

识别返回 Bomb 攻击的可能向量。

注意

pragma-spans-breaking-changes

识别具有跨越 Solidity 版本(其中可能引入了重大更改)的 pragma 的 Solidity 文件。

precision-loss-div-before-mul

识别由于乘法之前的除法可能导致的精度损失

注意

redundant-safemath-library

识别 SafeMath 库的冗余使用。

注意

replace-revert-strings-custom-errors

识别何时可以用自定义错误替换 revert 字符串。

注意

require-instead-of-revert

识别 require 语句何时不检查任何条件。

require-missing-message

识别 require 语句中何时缺少错误消息。

require-multiple-conditions

识别具有多个条件的 require 语句。

revert-missing-message

识别 revert 语句何时缺少错误消息。

selfdestruct-usage

识别 selfdestruct 的实例。

ethtrust

state-updated-without-event

识别函数是否在更新状态而没有事件发出。

注意

state-var-visibility-not-explicitly-declared

识别何时未明确声明状态变量的可见性。

注意

sushiswap-callback-attack

识别 sushiswap 回调上可能的攻击,其中虚假池地址可以传递授权检查。

注意

swapped-arguments-function-call

识别何时交换了函数调用的参数。

注意

too-many-digits

识别具有许多数字的文字数字。

注意

transferfrom-dangerous-from

识别使用 transferFrom,其中 from 参数不是 msg.sender

unchecked-call-success

识别何时缺少外部调用失败检查。

ethtrust

unchecked-increment

识别增量更新未包装在未经检查的块中。

注意

unchecked-keyword

识别函数内部未经检查的代码。

注意

unchecked-math

识别可能不安全的未经检查的数学运算使用。

unicode-direction-control

识别 Unicode 方向控制字符的使用。

ethtrust

unnecessary-assignment

识别变量的不必要的赋值。

注意

unnecessary-cast

识别不必要的类型转换。

注意

unsafe-abi-encoding

识别不安全的 ABI 编码的任何使用。

unsafe-mint-ERC721

识别在 ERC721 上下文中是否使用 _mint 函数而不是 _safeMint

注意

unused-arguments

识别未使用的函数参数。

注意

unused-enum

识别未使用的枚举。

注意

unused-error

识别未使用的错误。

注意

unused-event

识别未使用的事件。

注意

unused-function

识别具有内部或专用可见性的未使用的函数。

注意

unused-imports

识别未使用的导入。

注意

unused-named-returns

识别未使用的命名返回变量。

注意

unused-state-variable

识别未使用的状态变量。

注意

unused-struct

识别未使用的结构体。

注意

use-of-transfer-send

识别传输或发送的实例。

use-of-uint-instead-of-uint256

识别是否使用 int/uint 而不是 int256/uint256

注意

variable-could-be-constant

识别可以声明为 constant 的变量。

注意

variable-could-be-immutable

识别仅在构造函数中设置的变量,并且可以是 immutable

注意

void-constructor-call

识别对未实现的构造函数的调用。