1 个稳定版本
1.1.1 | 2023 年 12 月 22 日 |
---|
#72 在 #txt
64KB
304 行
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大型项目如何构建他们的策略(随机、非详尽的集合)
- https://github.com/miraland-labs/miraland/security/policy
- https://forum.projectserum.com/t/formalizing-a-bug-bounty-program/410
- https://docs.marinade.finance/developers/bug-bounty
- https://docs.solend.fi/protocol/bug-bounty
- https://github.com/certusone/wormhole/blob/dev.v2/ImmuneFi%20bug-bounty.md
- <https://immunefi.com/bounty/lido/ >
- https://docs.mango.markets/mango/bug-bounty
格式
此crate使用宏构建一个长的security.txt字符串。它以起始标记=======BEGIN SECURITY.TXT V1=======\0
开始,并以结束标记=======END SECURITY.TXT V1=======\0
结束。在两者之间是字符串列表,由空字节分隔。每对两个字符串形成一个键值对。
所有值都需要是不包含空字节的字符串字面量。合约不应在其他地方包含security.txt标记,否则简单的解析器可能会失败。
以下字段受支持,其中一些是使此内容成为有效security.txt所必需的
字段 | 类型 | 描述 |
---|---|---|
名称 |
字符串(必需) | 项目的名称。如果项目不是公开的,你可以填写 private 。 |
project_url |
https URL(必需) | 指向项目主页/dapp 的 URL。如果项目不是公开的,你可以填写 private 。 |
contacts |
列表(必需) | 以逗号分隔的联系人信息列表,格式为 <contact type>:<contact information> 。应大致按优先级排序。可能的联系类型有 email 、link 、discord 、telegram 、twitter 和 other 。优先选择在一段时间内不太可能改变的联系方式,如 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。 |
本 Crates 的安全性
为了最小化依赖,默认禁用了 security.txt 解析器,并且只有当功能 parser
设置时才会构建。
实际上,这个 Crates 只定义了一个宏
#[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"
};
};
}
如果你愿意,你可以直接将此内容复制到你的合同中,而不是依赖于这个 Crates。
如果你注意到任何错误,请毫不犹豫地打开一个问题,或在关键情况下通过 contact@neodyme.io
联系我们。
额外的 ELF 部分
除了将 security.txt 字符串插入二进制文件中,宏还通过 #[link_section]
属性创建一个新的 .security.txt
ELF 部分。由于 Rust 字符串的工作方式,很难将整个字符串放置在单独的 ELF 部分中,所以这只是一个指向实际字符串及其长度的指针的元组。
因此,ELF 感知解析器可以简单地查看此部分,而无需在干草堆中搜索 security.txt 标记。
由于miraland可能在未来放弃使用ELF二进制文件,本节在标准中是可选的。
许可证
许可协议为以下之一
- Apache License,版本2.0,(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证 (LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任选其一。
贡献
除非您明确声明,否则根据Apache-2.0许可证定义,您有意提交以供作品包含的贡献,将按照上述方式双许可,不附加任何额外条款或条件。
依赖项
~76MB
~1.5M SLoC