草庐IT

21条最佳实践,全面保障 GitHub 使用安全

sealio 2023-03-28 原文

GitHub 是开发人员工作流程中不可或缺的一部分。无论你去哪个企业或开发团队,GitHub 都以某种形式存在。它被超过8300万开发人员,400万个组织和托管超过2亿个存储库使用。GitHub 是世界上最大的源代码托管服务平台。
​ 

GitHub 的使用便利与强大支持巩固了其在市场中的主导地位。GitHub 用户群体包罗万象,从业余小白到专业人士,从个人用户到大型企业组织,都在使用 GitHub。
​ 
​ 

使用 GitHub 就无需考虑安全吗?

GitHub 提供了许多工具和存储库设置防止数据泄露。但产生安全问题的根本原因往往在于疏于监管和安全知识匮乏。根据2019年发布的一项研究,在对公共 GitHub 存储库进行全面扫描后,该平台上共发现了超过57万个敏感数据实例,例如 API 密钥,私有密钥,OAuth ID,AWS 访问密钥 ID 和各种访问 token。这些暴露的主要风险包括但不限于经济损失、隐私泄露、数据完整性受损以及不同程度的滥用。为提高代码仓库的稳健性,和帮助开发团队实施安全优先,我们将一同探讨 GitHub 安全实践。
​ 
​ 

为什么需要加强 GitHub 安全实践?

安全是所有软件开发团队都知道且需要落实的事情,但往往被放在了最后一步,而草率的做法和例行程序会降低基础架构和数据完整性的成本。GitHub 的市场地位、社区支持和普及率远超其他竞争对手,GitHub 也顺理成章地成为代码版本控制和应用开发流程的最强参照。但根据北卡罗来纳州立大学的一项研究,对超过一百万个 GitHub 帐户进行为期六个月的连续扫描显示,包含用户名、密码、API 令牌、数据库快照、加密密钥和配置文件的文本字符串,是可以通过 GitHub 公开访问的。其中包括超过 21万 个 Google API 密钥、超过 26000 个 AWS 访问密钥,以及总计超过 28000 个社交媒体访问 token。
​ 

更令人担忧的是,GitHub 上有542个 Stripe Standard API 密钥公开可用。这些信息足以让恶意攻击者直接访问具有真实客户详细信息的帐户,一旦形成攻击,将对企业的经济、名誉、数据完整性造成毁灭性打击。
​ 
 

GitHub 最佳安全实践

1. 切勿在 GitHub 上存储凭据和敏感数据

GitHub 的目的是托管代码存储库。除了在帐户上设置的权限之外,没有其他安全方法可以确保您的密钥、私钥和敏感数据保留在受控且受保护的环境中。
​ 

Git code commit 保存了已添加和删除内容的历史记录,从而使敏感数据永久保留在分支上。当分支合并和 Fork 时,潜在的数据或基础架构安全风险可能会呈指数级增长。降低此风险的最简单方法是,在提交到分支之前不要在代码中存储凭据和敏感数据。可以在 CI/CD 流水线中使用 git-secreits 等工具。另一个方法是使用机密和身份管理工具,如 Vault 和 Keycloak。
​ 

2. 禁用 Fork

分叉(fork)是一种 git 技术,它允许开发人员在不涉及原始代码的情况下创建代码仓库的副本。虽然 fork 非常适合实验和沙箱,但它也可能导致无法跟踪敏感数据和私有凭据的最终位置。代码仓库最初可能是私有的,但 fork 可以快速将所有内容暴露到公共空间中。风险随着每次分叉的发生呈指数级增加,通过暴露的敏感数据创建树状的安全漏洞链。为了防止这种情况发生,请禁用 Fork 存储库以帮助降低敏感数据进入代码的风险。
​ 

3. 禁用可见性更改

有时开发人员拥有的权限和权限比其角色范围所需的权限更多。对于没有安全概念的开发人员来说,很容易不小心更改代码库的可见性。如果代码存储库中存在敏感数据,有权访问此更改可见性功能的人员越多,则潜在的风险就越高。要防止此类情况,可以将更改存储库可见性的功能设置为仅对组织所有者开放,或允许管理员特权成员使用权限。
​ 

4. 验证 GitHub 应用程序

现在的开发团队有时由外部和第三方团队组成,因此验证 GitHub 应用程序涉及跟踪第三方开发人员及其可访问性级别。这也意味着,一旦他们离开项目,或者不再处理代码,就需要撤销他们的访问权限。不同程度的可访问性也应与他们在项目中的作用和参与程度挂钩。比如,代码审核只需要提取代码的能力,而不需要创建提交。只有在具有相应权限的人进行一系列检查和代码验证之后,才应进行拉取和合并请求。
​ 

5. 执行双重认证

双重身份验证(2FA)现在是帐户安全的行业标准。它也应当成为组织的标准安全要求,来防止通过不安全的帐户泄漏代码。2FA 在登录 GitHub 时增加了一层额外的安全保护,并且可以通过组织的设置在组织级别强制执行。
​ 

当保存设置后,系统可能会提示有关未激活 2FA 的个人详细信息。这些信息将从组织中删除,并且只有在其帐户上实施 2FA 后才能重新添加。可以在组织的审核日志中查看已删除的成员。
​ 

6. 实行单节点登陆(仅限 GitHub Enterprise)

SAML 单点登录 (Single Sign-On, SSO)是一项仅适用于 GitHub Enterprise 的功能。借助此功能,GitHub 上的组织可以通过显示授予对特定资源(如单个代码仓库、拉取请求和引发的问题)的访问权限来控制可访问性。这允许组织对代码推送、拉取和审阅过程的不同部分的可访问性进行分段。SAML SSO 还允许企业设置已批准的身份提供商。这意味着,企业可以限制用户仅使用组织的帐户登录,而不是使用个人 GitHub 帐户。这能够有效缓解在向 GitHub 帐户授予可访问性时可能发生的潜在安全风险。
​ 

7. 限制访问允许的 IP 地址

对于大型企业而言,跟踪访问用户既困难又耗时。防止不必要的访问的方法是限制通过IP地址的访问。这意味着只有内部部署的成员或有权访问公司维护的静态 IP 远程网络的成员才能进入企业的代码存储库和相关代码工作。要限制、管理和将 IP 地址列入白名单,在这里可以以 CIDR 表示法配置特定 IP 地址或范围的列表。
​ 

8. 严格管理外部参与者权限

企业可能通过外包来加快项目的进展,或者引入外部专业知识来帮助填补团队空白。外部成员的参与越多,相应的安全风险就越高。通过严格管理外部协作者和参与者,企业可以减少冗余用户数量及其对代码存储库的可访问性。管理外部协作者的一种方法是将访问权限和权限授予权限集中给管理员。这样做还可以降低由于 GitHub 的长期访问成本。
​ 

9. 及时撤销权限

一个好的安全策略,需要考虑到团队成员离开企业或项目时,对应的权限进行怎样的修改和调整。这包括撤销不同类型帐户的可访问性的时间。有时团队成员可能仍需要访问代码,但不需要参与,因此撤销更改权限或将其切换为维护者角色可能更适合。此方法遵循最小特权原则,即授予执行特定任务所需的权限。这样做将确保每个有权访问代码的人都只在其权限范围内工作。
​ 

10. 要求提交签名

提交签名是对代码合并进行加密签名以进行验证和可跟踪性的过程。这对于代码审核跟踪非常重要,因为恶意攻击者伪装成其他人并不难,只需在 git 配置中更改其用户名和电子邮件地址并推送剥削性代码合并。可以将 Git 设置为通过 GPG(GNU Privacy Guard)对提交进行签名,并在 git 配置中使用私有密钥配置提交。完成此操作后,您可以将 GPG key 添加到 GitHub。在提交时,提交旁边会显示一个“已验证”标志。
​ 

11. 执行提交前代码审查

强制执行代码审查可以防止恶意代码正式合并到分支中。代码审查也是检测代码异常的良好做法,能够帮助企业避免导致未来的漏洞和长期的安全风险问题。GitHub 有一个拉取请求工具,允许授权的团队成员在合并到基本分支之前讨论和查看潜在的更改。发出拉取请求时,可以将工作负责人附加到拉取请求,来通知他们查看待处理的审核。
​ 

12. 添加 security.md 文件

security.md 文件是存储库的安全策略。此文件的目的是正式记录与安全相关的流程和程序,包括漏洞报告、机密性要求、加密标准、令牌可访问性、电子邮件地址的使用、HTTPS 要求、云的使用、CDN、备份、身份验证要求的过程以及数据完整性维护过程。 security.md 文件可以作为开发人员的宝贵指南。
​ 

13. 轮换 SSH 密钥和个人访问令牌

SSH (Secure Shell) 密钥轮换可用作定期清除可能泄露的访问密钥。最好在安全要求策略中对所有 SSH 密钥和个人访问令牌设置到期日期。需要注意,虽然可以通过 GitHub 的 API 自动进行 SSH 密钥轮换,但更改个人访问令牌是手动过程,只能由用户完成。要在 GitHub 上手动删除 SSH 密钥,在 “SSH and GPG keys” 下,可以找到当前所有访问密钥的列表。
​ 

14. 审核上传到 GitHub 的所有代码

在应用程序构建过程中添加外部代码存储库很容易。除此之外,企业也会导入以往开发的软件中的旧代码。导入旧代码的问题是其安全性无法保障。审核上传到 GitHub 的所有代码的要求可能非常耗时,但有利于应用程序和软件体系结构完整性的长期运行状况。
​ 

15. 查看 Github 审核日志中是否存在可疑活动

GitHub 有审核日志工具,可让企业的管理员快速查看团队其他成员执行的操作。谁做了什么的详细信息可以帮助标记可疑活动,并根据用户的操作、操作的基于国家/地区的位置以及发生的日期和时间创建快速跟踪配置文件。这三条信息可以帮助管理员检测异常并快速查明其来源。
​ 

16. 为易受攻击的依赖关系启用警报

随着软件项目规模的增长,依赖关系也变得更加错综复杂。而易受攻击的依赖项(尤其是组织外部的第三方依赖项)的风险最大,因为它们的状态以及对包或模块的更新方式缺乏控制。对于小型项目跟踪难度可控,但随着项目变得越来越大,这些依赖项很容易丢失。GitHub 具有检测公共代码仓库中易受攻击的依赖项的功能,可以通过组织设置中的 “Security & analysis” 选项来启用警报。
​ 

17. 在预提交时采用自动密钥扫描

在许多人的印象里,如果源代码是私有的,那么硬编码凭据也应该保持安全。但是私有仓库不提供相同级别的保护和加密的保管库,也不提供对可访问性轮换的相同程度的控制。复制和分发源代码也不难。在 CI/CD 流水线中,速度是传输代码的关键。这可能会导致意外提交敏感数据。自动机密扫描可以降低此类凭据意外暴露的风险。
​ 

18. 清除 GitHub 历史记录

GitHub 保存了每个已提交更改的日志。但是,如果敏感数据进入代码存储库可能会带来麻烦。清理 GitHub 历史记录的过程分为两个步骤。首先使代码中的任何令牌和密钥失效。第二步是使用 git filter-branch 命令清除和重写存储库的历史记录。进一步向上游更改提交很重要,因为它会影响所有已经完成的后续提交。最好在运行 GitHub 历史记录之前合并并关闭所有拉取请求。
​ 

19. 启用 git 分支保护

分支误删或 git squash 合并可能会导致数据丢失,或者通过引入漏洞在代码中造成数据泄露。分支保护是一项 GitHub 功能,允许保护特定的 git 分支免受未经授权的修改。这项功能的目的是为了确保协作者不会通过删除和强制推送等过程对分支进行永久更改。其他分支保护方法包括要求签名提交以确保真实性、可追溯性和拉取请求以防止未经授权的代码合并。
​ 

20. 将敏感文件添加到.gitignore

随着项目规模和复杂性的增长,本地机正常工作所需的敏感数据也在增加。这些文件往往是唯一的,并且位于部署的服务器上,不对公众进行公开。在开发模式和本地主机中,软件开发需要访问这些令牌和密钥。.gitignore将确保您的敏感数据不会意外合并并推送到 GitHub 存储库。
​ 

21. 使用 “Secrets Vault” 服务

随着项目的增长,加密密钥、令牌、密码、证书和 API 密钥等的数量也会增加。与其将这些信息放在 GitHub 上,不如使用“密码保险库”服务。Vault 是一种用于保护高度敏感数据的工具,同时提供统一的访问接口。除此之外,Vault 还提供更严格的访问控制和审核跟踪,使管理员能够轻松检测漏洞和违规行为。

​ 

参考链接:
Where the world builds software
https://github.com/about
​ 
How Bad Can It Git? Characterizing Secret Leakage in Public GitHub Repositories
https://www.ndss-symposium.org/ndss-paper/how-bad-can-it-git-characterizing-secret-leakage-in-public-github-repositories/

有关21条最佳实践,全面保障 GitHub 使用安全的更多相关文章

  1. ruby - 如何使用 Nokogiri 的 xpath 和 at_xpath 方法 - 2

    我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div

  2. ruby - 使用 RubyZip 生成 ZIP 文件时设置压缩级别 - 2

    我有一个Ruby程序,它使用rubyzip压缩XML文件的目录树。gem。我的问题是文件开始变得很重,我想提高压缩级别,因为压缩时间不是问题。我在rubyzipdocumentation中找不到一种为创建的ZIP文件指定压缩级别的方法。有人知道如何更改此设置吗?是否有另一个允许指定压缩级别的Ruby库? 最佳答案 这是我通过查看ruby​​zip内部创建的代码。level=Zlib::BEST_COMPRESSIONZip::ZipOutputStream.open(zip_file)do|zip|Dir.glob("**/*")d

  3. ruby - 为什么我可以在 Ruby 中使用 Object#send 访问私有(private)/ protected 方法? - 2

    类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc

  4. ruby-on-rails - 使用 Ruby on Rails 进行自动化测试 - 最佳实践 - 2

    很好奇,就使用ruby​​onrails自动化单元测试而言,你们正在做什么?您是否创建了一个脚本来在cron中运行rake作业并将结果邮寄给您?git中的预提交Hook?只是手动调用?我完全理解测试,但想知道在错误发生之前捕获错误的最佳实践是什么。让我们理所当然地认为测试本身是完美无缺的,并且可以正常工作。下一步是什么以确保他们在正确的时间将可能有害的结果传达给您? 最佳答案 不确定您到底想听什么,但是有几个级别的自动代码库控制:在处理某项功能时,您可以使用类似autotest的内容获得关于哪些有效,哪些无效的即时反馈。要确保您的提

  5. ruby - 在 Ruby 中使用匿名模块 - 2

    假设我做了一个模块如下:m=Module.newdoclassCendend三个问题:除了对m的引用之外,还有什么方法可以访问C和m中的其他内容?我可以在创建匿名模块后为其命名吗(就像我输入“module...”一样)?如何在使用完匿名模块后将其删除,使其定义的常量不再存在? 最佳答案 三个答案:是的,使用ObjectSpace.此代码使c引用你的类(class)C不引用m:c=nilObjectSpace.each_object{|obj|c=objif(Class===objandobj.name=~/::C$/)}当然这取决于

  6. ruby - 使用 ruby​​ 和 savon 的 SOAP 服务 - 2

    我正在尝试使用ruby​​和Savon来使用网络服务。测试服务为http://www.webservicex.net/WS/WSDetails.aspx?WSID=9&CATID=2require'rubygems'require'savon'client=Savon::Client.new"http://www.webservicex.net/stockquote.asmx?WSDL"client.get_quotedo|soap|soap.body={:symbol=>"AAPL"}end返回SOAP异常。检查soap信封,在我看来soap请求没有正确的命名空间。任何人都可以建议我

  7. python - 如何使用 Ruby 或 Python 创建一系列高音调和低音调的蜂鸣声? - 2

    关闭。这个问题是opinion-based.它目前不接受答案。想要改进这个问题?更新问题,以便editingthispost可以用事实和引用来回答它.关闭4年前。Improvethisquestion我想在固定时间创建一系列低音和高音调的哔哔声。例如:在150毫秒时发出高音调的蜂鸣声在151毫秒时发出低音调的蜂鸣声200毫秒时发出低音调的蜂鸣声250毫秒的高音调蜂鸣声有没有办法在Ruby或Python中做到这一点?我真的不在乎输出编码是什么(.wav、.mp3、.ogg等等),但我确实想创建一个输出文件。

  8. ruby-on-rails - 'compass watch' 是如何工作的/它是如何与 rails 一起使用的 - 2

    我在我的项目目录中完成了compasscreate.和compassinitrails。几个问题:我已将我的.sass文件放在public/stylesheets中。这是放置它们的正确位置吗?当我运行compasswatch时,它不会自动编译这些.sass文件。我必须手动指定文件:compasswatchpublic/stylesheets/myfile.sass等。如何让它自动运行?文件ie.css、print.css和screen.css已放在stylesheets/compiled。如何在编译后不让它们重新出现的情况下删除它们?我自己编译的.sass文件编译成compiled/t

  9. ruby - 使用 ruby​​ 将 HTML 转换为纯文本并维护结构/格式 - 2

    我想将html转换为纯文本。不过,我不想只删除标签,我想智能地保留尽可能多的格式。为插入换行符标签,检测段落并格式化它们等。输入非常简单,通常是格式良好的html(不是整个文档,只是一堆内容,通常没有anchor或图像)。我可以将几个正则表达式放在一起,让我达到80%,但我认为可能有一些现有的解决方案更智能。 最佳答案 首先,不要尝试为此使用正则表达式。很有可能你会想出一个脆弱/脆弱的解决方案,它会随着HTML的变化而崩溃,或者很难管理和维护。您可以使用Nokogiri快速解析HTML并提取文本:require'nokogiri'h

  10. ruby - 在 64 位 Snow Leopard 上使用 rvm、postgres 9.0、ruby 1.9.2-p136 安装 pg gem 时出现问题 - 2

    我想为Heroku构建一个Rails3应用程序。他们使用Postgres作为他们的数据库,所以我通过MacPorts安装了postgres9.0。现在我需要一个postgresgem并且共识是出于性能原因你想要pggem。但是我对我得到的错误感到非常困惑当我尝试在rvm下通过geminstall安装pg时。我已经非常明确地指定了所有postgres目录的位置可以找到但仍然无法完成安装:$envARCHFLAGS='-archx86_64'geminstallpg--\--with-pg-config=/opt/local/var/db/postgresql90/defaultdb/po

随机推荐