9 个版本 (4 个稳定版本)
1.1.1 | 2023年5月22日 |
---|---|
1.1.0 | 2022年12月23日 |
1.0.1 | 2022年4月5日 |
0.1.5 | 2022年3月29日 |
#2370 in 魔法豆
每月26次 下载
60KB
304 行
security.txt
这个库定义了一个宏,允许开发者为希望联系 Solana 智能合约作者的网络安全研究人员提供易于解析的信息。它受到了 https://securitytxt.org/ 的启发。
在 Solana 探索器中查看此示例: https://explorer.solana.com/address/HPxKXnBN4vJ8RjpdqDCU7gvNQHeeyGnSviYTJ4fBrDt4/security?cluster=devnet
动机
用户通常通过项目的网络界面与 Solana 智能合约交互,该界面知道合约的地址。网络安全研究人员通常不知道。
特别是对于较小或私有的项目,仅凭合约的地址进行识别既困难又耗时,甚至可能不可能。这会减缓或阻止漏洞报告到达开发者。
在您的合约中包含有关您项目的标准化信息,使白帽研究人员在发现任何问题后更容易联系您。
为了最大限度地与现有的部署设置、多重签名和 DAO 兼容,此 security.txt 被实现为程序的一部分,而不是外部合约。
用法
将以下内容添加到 Cargo.toml 的 [dependencies]
部分
solana-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, solana_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/solana-labs/solana/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
"
}
示例策略
漏洞赏金政策可能难以编写。作为一个良好且详尽的示例,请参阅 Solana 基金会的 SECURITY.md。但即使是简短的政策也比没有好。一个起点可能如下所示
在验证漏洞后,我们将根据我们的判断支付漏洞赏金,最高可达风险价值的 10%,但不超过 x 美元。只有当安全问题的详细信息在修复和验证之前未提供给第三方时,才会支付此赏金。此外,报告者不得未经我们明确同意就利用该问题。
如果您不支付赏金,这对于处理价值不多的玩具项目可能是合理的,您也可以写一些类似的内容
我们不支付漏洞赏金。
为了获得更多灵感,请查看其他大型 Solana 项目的政策结构(随机,非详尽集合)
- https://github.com/solana-labs/solana/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
格式
该软件包使用宏来构建一个长的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> 。应大致按优先顺序排列。可能的联系类型包括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。 |
此软件包的安全性
为了最小化依赖项,默认禁用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。
如果您发现任何错误,请不要犹豫,请随时提出问题,或者在紧急情况下,通过以下方式联系我们:@neodyme.io
。
额外的ELF段
除了将security.txt字符串插入到二进制文件中,这个宏还通过#[link_section]
属性创建了一个新的.security.txt
ELF段。由于Rust字符串的工作方式,将整个字符串放置在单独的ELF段中并不容易,因此这只是一个指向实际字符串及其长度的指针的元组。
因此,ELF感知解析器可以直接查看此段,无需在haystack中搜索security.txt标记。
由于Solana未来可能放弃使用ELF二进制文件,此段在标准中是可选的。
许可证
在以下任一许可证下授权:
- Apache许可证第2版(LICENSE-APACHE 或 http://www.apache.org/licenses/LICENSE-2.0)
- MIT许可证(LICENSE-MIT 或 http://opensource.org/licenses/MIT)
任您选择。
贡献
除非您明确表示,否则根据Apache-2.0许可证定义的,您提交的任何旨在包含在作品中的有意贡献,都应按上述方式双重许可,不附加任何额外条款或条件。
依赖项
~77MB
~1.5M SLoC