利用Git Hooks捕获API密钥泄露

本文介绍如何使用Git的pre-commit钩子脚本,通过正则表达式匹配检测代码中可能泄露的API密钥,防止敏感信息误提交到Git仓库,并讨论其局限性和绕过方法。

利用Git Hooks捕获API密钥

这里有一个小技巧,可以帮助防止API密钥等敏感信息意外进入Git仓库。尽管许多Git爱好者开发者声称这很常见,但GitHub上仍经常发现密钥泄露,这说明知与行之间存在差距。

Git Hooks简介

Git提供了一套钩子(hooks)系统,允许在关键事件(如代码提交或推送到远程仓库)时运行脚本。这些脚本可用于检查文件内容或提交消息,必要时可阻止操作。钩子可在本地或远程运行,只需将可执行文件放入指定目录即可。更多详情参见Customizing Git - Git Hooks

防御方案:pre-commit检查

建议在文件提交到仓库前检查不良内容,这类检查由.git/hooks/pre-commit脚本执行。该脚本在提交操作时运行,但文件尚未进入仓库。脚本可访问所有待提交文件的列表,只需用grep搜索不良内容(如API密钥或其他不希望进入仓库的信息)。脚本通过标准输出向用户发送消息,若脚本以零退出,则允许提交;否则拒绝。

以下脚本使用两个正则表达式检查Amazon和Google私钥。它对每个待提交文件调用grep,如果找到匹配,则打印消息并增加不良文件计数。最后,脚本以不良计数退出:零表示无匹配,允许提交;非零则拒绝。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
#!/usr/bin/env ruby

# 使用--no-verify参数可绕过此脚本

files_modified = `git diff-index --cached --name-only HEAD`
files_modified_arr = files_modified.split("\n")

# puts "Checking files: #{files_modified_arr.inspect}"

bad_files = 0

# 构建不希望提交的密钥哈希
# 注意反斜杠引号前的双反斜杠,确保字符串中嵌入反斜杠引号

regexs = {
    "AWS Key" => "['\\\"][a-z0-9\/+]{40}['\\\"]",
    "Google Key" => "['\\\"][a-z0-9_]{39}['\\\"]",
}

files_modified_arr.each do |file|
    regexs.each_pair do |key_name, regex|
        grep_command = "grep -iE \"#{regex}\" #{file}"
        # puts grep_command
        res = `#{grep_command}`
        # puts res.inspect
        unless res == ""
            bad_files += 1
            puts "Match rule for #{key_name} on file: #{file}"
        end
    end
end

exit bad_files

第一个示例展示了API密钥的安全用法:密钥在使用前从文件加载。

文件正常通过Git提交过程。

第二个示例将API密钥直接存储在文件中,钩子检测到并阻止提交。

最后,与任何模式匹配规则一样,偶尔可能出现误报。如果想覆盖钩子及其检查,可以在提交时使用--no-verify参数。

结论

该技术可用于检测任何类型的内容并防止其进入仓库。显然,如果正则表达式编写不当,仍有可能漏检;同样,糟糕的正则表达式可能导致误报,因此需要努力确保正则表达式列表尽可能精确。

此外,如所示,检查可以轻松绕过,因此仍建议定期进行源代码审计,查找开发人员强制通过的密钥或其他信息。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计