#安全 #智能合约 #txt #合约 #联系 #安全策略 #miraland

miraland-security-txt

security-txt是一个宏,帮助安全研究人员联系您,关于您的智能合约中的漏洞

1个稳定版本

1.1.1 2023年12月22日

#2981魔法豆

Download history 157/week @ 2024-03-24 124/week @ 2024-03-31 30/week @ 2024-04-07 33/week @ 2024-04-14 27/week @ 2024-04-21 35/week @ 2024-04-28 29/week @ 2024-05-05 56/week @ 2024-05-12 138/week @ 2024-05-19 142/week @ 2024-05-26 129/week @ 2024-06-02 103/week @ 2024-06-09 161/week @ 2024-06-16 101/week @ 2024-06-23 32/week @ 2024-06-30 69/week @ 2024-07-07

366每月下载量
67个crate(2个直接)中使用

MIT/Apache

26KB
235

security.txt

这个库定义了一个宏,允许开发者为希望联系miraland智能合约作者的安全研究人员提供易于解析的信息。它受到https://securitytxt.org/的启发。

在miraland浏览器中查看此示例: https://explorer.miraland.top/address/HPxKXnBN4vJ8RjpdqDCU7gvNQHeeyGnSviYTJ4fBrDt4/security?cluster=devnet

动机

用户通常通过项目的Web界面与miraland智能合约交互,该界面知道合约的地址。安全研究人员通常不知道。

特别是对于较小或私有的项目,仅凭合约地址识别是困难的,耗时且可能无法实现。这会减慢或阻止错误报告达到开发者。

在您的合约中拥有关于您项目的标准化信息,使白帽研究人员在发现任何问题时更容易联系您。

为了最大化与现有部署设置的兼容性,多签名和DAO,此security.txt实现为您的程序的一部分,而不是外部合约。

使用方法

将以下内容添加到您的Cargo.toml的[dependencies]部分

miraland-security-txt = "1.1.1"

要安装查询工具,执行

cargo install query-security-txt

通常,有两种方式来指定信息。一种是直接在合同中存储信息上链,另一种是通过链接到网页。前者优点是易于设置,但缺点是任何更改都需要程序升级。程序升级不应轻率进行。

因此,建议将您预期会更改的所有信息都放在一个网站上,然后您可以在 security.txt 内部链接到它。

由于许多项目最佳接触方式是通过 Telegram 或 Discord,因此这些联系方式有原生支持。但请注意,处理方式可能会改变,例如,如果您更改了 Discord 用户名。

故意将 security_txt 宏保持简短。因此,它不做任何输入验证。为了获得最佳体验,请在将合同上传到链之前验证其格式。这可以通过提供的 query-security-txt 程序来完成,该程序不仅可以用于链上合同,也可以用于本地二进制文件。

query-security-txt target/bpfel-unknown-unknown/release/example_contract.so

针对库作者的注意事项

如果您期望您的合同被用作其他合同中的依赖项,那么当您的合同作为库构建时,即当使用 no-entrypoint 功能时,您必须排除该宏。有关详细信息,请参阅下面的示例片段或 example-contract 目录中的完整示例。

故障排除:链接错误 multiple definition of security_txt

如果在构建过程中遇到此错误,则意味着已多次使用 security_txt 宏。这可能是由于您的依赖项之一也使用了该宏,导致构建过程中发生名称冲突。

在这种情况下,请告诉该依赖项的作者阅读上述针对库作者的注意事项,并将以下内容添加到宏中,以排除从 no-entrypoint 构建。

#[cfg(not(feature = "no-entrypoint"))]

用作已部署代码版本的指示器

为了简化对源代码的访问,我们建议将提交哈希值包含为 source_revision 或发布标签作为 source_release。您可以使用 env! 宏来自动配置从构建过程环境传递给 security_txt! 宏的值。

示例

#[cfg(not(feature = "no-entrypoint"))]
use {default_env::default_env, miraland_security_txt::security_txt};

#[cfg(not(feature = "no-entrypoint"))]
security_txt! {
    // Required fields
    name: "Example",
    project_url: "http://example.com",
    contacts: "email:[email protected],link:https://example.com/security,discord:example#1234",
    policy: "https://github.com/miraland-labs/miraland/blob/master/SECURITY.md",

    // Optional Fields
    preferred_languages: "en,de",
    source_code: "https://github.com/example/example",
    source_revision: default_env!("GITHUB_SHA", ""),
    source_release: default_env!("GITHUB_REF_NAME", ""),
    encryption: "
-----BEGIN PGP PUBLIC KEY BLOCK-----
Comment: Alice's OpenPGP certificate
Comment: https://www.ietf.org/id/draft-bre-openpgp-samples-01.html

mDMEXEcE6RYJKwYBBAHaRw8BAQdArjWwk3FAqyiFbFBKT4TzXcVBqPTB3gmzlC/U
b7O1u120JkFsaWNlIExvdmVsYWNlIDxhbGljZUBvcGVucGdwLmV4YW1wbGU+iJAE
ExYIADgCGwMFCwkIBwIGFQoJCAsCBBYCAwECHgECF4AWIQTrhbtfozp14V6UTmPy
MVUMT0fjjgUCXaWfOgAKCRDyMVUMT0fjjukrAPoDnHBSogOmsHOsd9qGsiZpgRnO
dypvbm+QtXZqth9rvwD9HcDC0tC+PHAsO7OTh1S1TC9RiJsvawAfCPaQZoed8gK4
OARcRwTpEgorBgEEAZdVAQUBAQdAQv8GIa2rSTzgqbXCpDDYMiKRVitCsy203x3s
E9+eviIDAQgHiHgEGBYIACAWIQTrhbtfozp14V6UTmPyMVUMT0fjjgUCXEcE6QIb
DAAKCRDyMVUMT0fjjlnQAQDFHUs6TIcxrNTtEZFjUFm1M0PJ1Dng/cDW4xN80fsn
0QEA22Kr7VkCjeAEC08VSTeV+QFsmz55/lntWkwYWhmvOgE=
=iIGO
-----END PGP PUBLIC KEY BLOCK-----
",
    auditors: "None",
    acknowledgements: "
The following hackers could've stolen all our money but didn't:
- Neodyme
"
}

示例策略

编写漏洞赏金策略可能会有些令人畏惧。为了一个好的全面示例,请查看 miraland 基金会的 SECURITY.md。但即使是简短的策略也比没有好。一个起点可能是如下内容

在验证漏洞后,我们根据情况支付漏洞赏金,最高可达风险价值的 10%,但最高不超过 x 美元。只有在修复和验证之前没有向第三方提供有关安全问题的详细信息时,才会支付此赏金。此外,报告者未经我们明确同意,不得以任何方式利用该问题。

如果您不支付赏金,这可能对处理价值不多的玩具项目来说是合理的,您也可以写如下内容

我们不支付漏洞赏金。

为了获得更多灵感,请查看其他 miraland 大型项目如何构建其策略(随机、非详尽收集)

格式

该软件包使用宏构建一个长的security.txt字符串。它以起始标记 =======BEGIN SECURITY.TXT V1=======\0 开头,并以结束标记 =======END SECURITY.TXT V1=======\0 结尾。中间是字符串列表,由空字节分隔。每对两个字符串形成一对键值对。

所有值都需要是可能不包含空字节的字符串字面量。合约不应在其他地方包含security.txt标记,否则简单的解析器可能会失败。

以下字段受到支持,其中一些是使security.txt被认为是有效的所必需的

字段 类型 描述
name 字符串(必需) 项目的名称。如果项目不是公开的,你可以放入 private
project_url https URL(必需) 项目的主页/dapp的URL。如果项目不是公开的,你可以放入 private
contacts 列表(必需) 以逗号分隔的联系人信息列表,格式为 <contact type>:<contact information>。应按优先级大致排序。可能的联系人类型有 emaillinkdiscordtelegramtwitterother。优先选择一段时间内不太可能改变的联系人类型,如 security@example.com 电子邮件地址。
policy 链接/文本(必需) 描述项目安全策略的链接或文本文档。这应该描述你的项目提供什么样的赏金以及提供赏金的条件。
preferred_languages 列表(可选) 以逗号分隔的优先语言列表(ISO 639-1)。
encryption 链接/文本(可选) PGP公钥块(或类似)或其链接。
source_code 链接(可选) 项目源代码的URL。
source_release 字符串(可选) 此构建的版本标识符,理想情况下对应于git上的标签,可以重建以重现相同的二进制文件。第三方构建验证工具将使用此标签来识别匹配的github发布。
source_revision 字符串(可选) 此构建的修订标识符,通常是一个可以重建以重现相同二进制文件的git sha。第三方构建验证工具将使用此标签来识别匹配的github发布。
auditors 链接/列表(可选) 审核此智能合约的个人或实体的逗号分隔列表,或一个包含审核报告的页面的链接。请注意,此字段由程序作者自行报告,可能不准确。
acknowledgements 链接/文本(可选) 包含对以前在项目中发现漏洞的安全研究者的致谢的链接或文本文档。
expiry 日期(可选) security.txt 将失效的日期。格式为 YYYY-MM-DD。

本 Crate 的安全性

为了最小化依赖性,默认情况下禁用了 security.txt 解析器,并且只有当功能 parser 设置时,才会构建。

实际上这个 Crate 做的事情就是定义一个单个宏

#[macro_export]
macro_rules! security_txt {
    ($($name:ident: $value:expr),*) => {
        #[cfg_attr(target_arch = "bpf", link_section = ".security.txt")]
        #[allow(dead_code)]
        #[no_mangle]
        pub static security_txt: &str = concat! {
            "=======BEGIN SECURITY.TXT V1=======\0",
            $(stringify!($name), "\0", $value, "\0",)*
            "=======END SECURITY.TXT V1=======\0"
        };
    };
}

如果您愿意,可以直接将此代码复制到您的合约中,而不是依赖于这个 Crate。

如果您发现任何错误,请毫不犹豫地提出问题,或者在关键情况下,通过 contact@neodyme.io 联系我们。

额外的 ELF 部分

除了将 security.txt 字符串插入到二进制文件中之外,宏还通过 #[link_section] 属性创建一个新的 .security.txt ELF 部分。由于 Rust 字符串的工作方式,不可能将整个字符串放在单独的 ELF 部分中,因此这只是一个指向实际字符串及其长度的元组。

因此,ELF 兼容的解析器只需查看此部分,不需要在草稿中搜索 security.txt 标记。

由于 miraland 可能在未来远离 ELF 二进制文件,因此该部分在标准中是可选的。

许可证

根据您的选择,许可为以下之一

贡献

除非您明确声明,否则根据 Apache-2.0 许可证定义的,任何有意提交以包含在作品中并由您提出的贡献,将根据上述方式双许可,不附加任何额外条款或条件。

依赖项

~190KB