我们秘密扫描器中连金丝雀都没发现的 bug
配送
在我们出售的每个套件打包之前,一道关卡会扫描其中是否含有我们自己的秘密实际值。每次扫描都会先植入金丝雀,每种类型各一个,除非全部捕获,否则拒绝运行。它总能捕获它们。但它仍然有一个 bug。
关卡如何读取秘密
关卡不仅查找形似密钥的内容。它会读取存放秘密的文件(env 文件、JSON 配置、密钥文件),提取所有名称表明其为秘密的值,然后在即将发布的内容中搜索这些确切的值,包括原样和 base64 编码的形式。
这个 bug
对于像这样的一行:
DB_PASSWORD='Tr0ub4dor-and-3' # 5月已轮换
读取器只有在值以引号字符开头且结尾时才剥离周围的引号。如果值后面有注释,该行以字母结尾,因此引号保留了下来。随后注释被截断,关卡继续搜索 'Tr0ub4dor-and-3',包括引号。一个包含不带这些引号的密码的套件本会通过。
为什么金丝雀从未察觉
金丝雀测试的是检测网:植入一个扫描器已知的值,检查它是否被找到。我们的金丝雀值是直接交给扫描器的,因此从未经过读取配置行的代码。每个检测网都经过了测试,而它们前面的解析器却没有。
我们是如何发现的
我们正将关卡打造成一个独立产品,并编写了一个测试,向其输入人们实际编写的各种格式的配置:export、引号、行尾注释。测试在带注释的引号行上失败。修复方案是读取带引号的值直到其闭合引号,并忽略其后的任何内容。
这重要吗?
我们在更改任何内容之前进行了检查。在我们的构建机上,关卡从给定的 59 个文件中读取 133 个秘密值,在另一台机器上读取 499 个;没有一个具有这种格式。之前的判定结果不变:我们发布的每个套件都针对现在会扫描的相同值进行了扫描。尽管如此,我们还是在所有三台机器上修复了关卡。
要点
如果扫描器能提取出它搜索的内容,请用真实输入测试提取功能,而不要只用预设值测试搜索功能。金丝雀测试只能证明网是好的,却无法说明正确的鱼是否真的进了网。Secret Gate 的测试现已覆盖这两方面,并且在其发布前,我们已确认它能读取与我们构建门禁完全相同的 133 个值。