选择所需的最低权限
注册 GitHub App 时,选择 GitHub App 所需的最低权限。 如果应用的任何密钥或令牌遭到入侵,这将限制可能发生的损害量。 有关如何选择权限的详细信息,请参阅“为 GitHub Apps 选择权限”。
当 GitHub App 创建安装访问令牌或用户访问令牌时,可以进一步限制应用可以访问的存储库以及令牌拥有的权限。 有关详细信息,请参阅 为 GitHub 应用生成安装访问令牌 和 为 GitHub 应用生成用户访问令牌。
保持在速率限制范围内
订阅 Webhook 事件,而不是轮询 API 以获取数据。 这将帮助你的 GitHub App 保持在 API 速率限制范围内。 有关详细信息,请参阅 将 Webhook 与 GitHub 应用配合使用 和 构建响应 Webhook 事件的 GitHub 应用。
请考虑使用条件请求来协助保持在速率限制范围内。 有关条件请求的详细信息,请参阅“使用 REST API 的最佳做法”。
如果可能,请考虑使用合并 GraphQL 查询而不是 REST API 请求来协助保持在速率限制范围内。 有关详细信息,请参阅 比较 GitHub 的 REST API 和 GraphQL API 和 GitHub GraphQL API 文档。
如果达到了速率限制,并且需要重试 API 请求,请使用 x-ratelimit-reset
或 Retry-After
响应头。 如果这些标头不可用,请在两次重试之间等待一段呈指数级增长的时间,并在重试特定次数后引发错误。 有关详细信息,请参阅“使用 REST API 的最佳做法”。
保护应用的凭据
可以为 GitHub App 生成私钥和客户端密码。 专用密钥用于生成安装访问令牌,而客户端密码用于获取用户访问令牌和刷新令牌。 这些令牌可用于代表应用安装或用户发出 API 请求。
必须安全地存储专用密钥、令牌和客户端密码。 但是,存储机制及其相对安全性取决于集成体系结构及其运行平台。 通常,应使用旨在将敏感数据存储在所使用的平台上的存储机制。
私钥
GitHub App 的私钥授予对安装应用的每个帐户的访问权限。 它必须安全存储,不能广泛共享。****
请考虑将 GitHub App 的私钥存储在密钥保管库(例如 Azure Key Vault)中,并将其设置为“仅登录”。
或者,可以将密钥存储为环境变量。 但是,此方法不如将密钥存储在密钥保管库中强。 如果攻击者获得了对环境的访问权限,他们就可以读取私钥,并作为 GitHub App 获得永久身份验证。
即使代码存储在专用存储库中,也绝不应在应用中对私钥进行硬编码。 如果你的应用是本机客户端、客户端应用,或在用户设备上运行(而不是在服务器上运行),则绝不应随应用一起交付私钥。
生成的私钥数量不得超出所需数量。 应删除不再使用的专用密钥。 有关详细信息,请参阅“管理 GitHub 应用的私钥”。
客户端机密
若应用未使用设备流,则需使用客户端密码生成用户访问令牌。 有关详细信息,请参阅“为 GitHub 应用生成用户访问令牌”。
如果应用是机密客户端(即能够安全保管客户端密码),可考虑将客户端密码存储在密钥保管库(如 Azure Key Vault)中,或作为加密的环境变量或服务器上的机密进行存储。
如果应用是公共客户端(即在用户设备上运行的本机应用、CLI 实用工具或单页 Web 应用程序),则无法保护客户端密码。 必须将客户端密码包含在应用程序代码中,同时应使用 PKCE 来更好地保护身份验证流。 如果计划基于应用生成的令牌来限制对自己服务的访问,需谨慎行事,因为公共客户端极易被伪造,任何人都可以重复使用应用的客户端 ID 登录。
不要无故启用设备流
如果担心在公共客户端中使用客户端密码,建议使用带 PKCE 的授权码,而非设备流。 设备流完全不需要重定向 URI,这意味着攻击者可以利用设备流远程模拟应用,实施网络钓鱼攻击。 因此,除非在受限环境(CLI、IoT 设备或无外设系统)中使用应用,否则不要为应用程序启用设备流。
安装访问令牌、用户访问令牌和刷新令牌
安装访问令牌用于代表应用安装发出 API 请求。 用户访问令牌用于代表用户发出 API 请求。 刷新令牌用于重新生成用户访问令牌。 应用可以使用其私钥生成安装访问令牌。 应用可以使用其客户端密码生成用户访问令牌和刷新令牌。
如果应用是网站或 Web 应用,则应在后端加密令牌,并确保可以访问令牌的系统的安全性。 请考虑将刷新令牌存储在与活动访问令牌不同的位置。
如果你的应用是本机客户端、客户端应用或在用户设备上运行(而不是在服务器上运行),则可能无法保护令牌以及在服务器上运行的应用。 不应生成安装访问令牌,因为这样做需要私钥。 相反,应生成用户访问令牌。 应通过为应用平台推荐的机制来存储令牌,请记住,存储机制可能并不完全安全。
使用合适的令牌类型
GitHub Apps 可以生成安装访问令牌或用户访问令牌,以便发出经过身份验证的 API 请求。
安装访问令牌会将活动归因于你的应用。 这对于独立于用户运行的自动化非常有用。
用户访问令牌会将活动归因于用户和应用。 这些对于根据用户输入或代表用户执行操作非常有用。
会基于 GitHub App 的权限和访问权限限制安装访问令牌。 会基于 GitHub App 的权限和访问权限以及用户的权限和访问权限限制用户访问令牌。 因此,如果你的 GitHub App 代表用户执行操作,它应始终使用用户访问令牌而不是安装访问令牌。 否则,应用可能会允许用户查看或执行他们不该看到或执行的操作。
在任何情况下,应用都不应使用 personal access token 或 GitHub 密码进行身份验证。
全面、持久且频繁地检查授权情况
用户登录后,应用开发人员必须完成额外的步骤,以确保用户有权访问系统中的数据。 必须定期检查他们的成员身份、访问权限以及他们当前的 SSO 状态,确保这些都允许访问你的应用程序及其所保护的资源。
使用持久且唯一的 id
来还原用户
当用户登录并在应用程序中执行操作时,你必须记住是哪个用户执行了该操作,以便在他们下次登录时授予他们访问相同资源的权限。
若要将用户正确存储在数据库中,请始终使用用户的 id
。 此值永远不会为用户更改,也不会用于指向其他用户,因此它可以确保你对用户提供所需访问权限。 可以使用 GET /user
REST API 终结点查找用户的 id
。 请参阅“用户的 REST API 终结点”。
如果存储对存储库、组织和企业的引用,也请使用其 id
来确保指向它们的链接保持准确。
_切勿_使用可能随时间变化的标识符,包括用户句柄、组织数据域或电子邮件地址。
验证每个新身份验证的组织访问权限
当你为用户登录时,你应该跟踪用户的令牌被授权访问哪些组织。 在登录后,随着用户被从组织中移除,这一情况可能会随时间而发生变化。 如果组织使用 SAML SSO,而用户未执行 SAML SSO,则用户访问令牌将无法访问该组织。 应该定期使用 GET /user/installations
REST API 终结点来验证用户访问令牌有权访问哪些组织。 如果用户未被授权访问组织,则应在他们执行 SAML SSO 或重新加入组织之前阻止他们访问你自己的应用程序中组织拥有的数据。 有关详细信息,请参阅“GitHub App 安装的 REST API 终结点”。
使用组织和企业上下文存储用户数据
除了通过 id
字段跟踪用户标识之外,还应该保留每个用户所处的组织或企业的数据。 这将有助于确保在用户切换角色时不会泄露敏感信息。
例如:
- 用户处于需要 SAML SSO 的
Mona
组织中,并在执行 SSO 后登录到你的应用。 你的应用现在可以访问用户在Mona
中所做的任何操作。 - 用户从
Mona
中的存储库中提取一堆代码,并将其保存在你的应用中进行分析。 - 稍后,用户切换作业,并从
Mona
组织中删除。
当用户访问你的应用时,他们能否在其用户帐户中查看来自 Mona
组织的代码和分析?
这就是为什么跟踪应用保存的数据来源至关重要。 否则,你的应用对组织来说是一个数据保护威胁,如果他们不能相信你的应用正确地保护了其数据,他们很可能会禁止你的应用。
令牌过期
GitHub 强���建议使用会过期的用户访问令牌。 如果之前选择不使用会过期的用户访问令牌,但希望重新启用此功能,请参阅“激活 GitHub 应用的可选功能”。
安装访问令牌在 1 小时后过期,即将过期的用户访问令牌在 8 小时后过期,刷新令牌在 6 个月后过期。 但是,还可以在不再需要令牌时立即撤销令牌。 有关详细信息,请参阅“DELETE /installation/token
”来撤销安装访问令牌,参阅“DELETE /applications/{client_id}/token
”来撤销用户访问令牌。
缓存令牌
用户访问令牌和安装访问令牌将一直用到过期。 应缓存创建的令牌。 创建新令牌前,检查缓存以查看是否已有有效令牌。 重用令牌将使应用更快,因为这会减少生成令牌的请求。
制定处理安全漏洞的计划
应制定计划,以便及时处理任何安全漏洞。
如果应用的私钥或机密遭到入侵,则需要生成新的密钥或机密,更新应用以使用新密钥或机密,并删除旧密钥或机密。
如果安装访问令牌、用户访问令牌或刷新令牌遭到入侵,应立即撤销这些令牌。 有关详细信息,请参阅“DELETE /installation/token
”来撤销安装访问令牌,参阅“DELETE /applications/{client_id}/token
”来撤销用户访问令牌。
定期进行漏洞扫描
应定期对应用进行漏洞扫描。 例如,可以为托管应用代码的存储库设置代码扫描和机密扫描。 有关详细信息,请参阅 关于代码扫描 和 关于机密扫描。
选择适当的环境
如果应用在服务器上运行,请验证服务器环境是否安全,以及它是否能够处理应用预期的流量。
订阅最少 Webhook
仅订阅应用所需的 Webhook 事件。 这将有助于减少延迟,因为应用不会收到不需要的有效负载。
使用 Webhook 机密
应为 GitHub App 设置 Webhook 机密,并验证传入 Webhook 事件的签名是否与机密匹配。 这有助于确保传入的 Webhook 事件是有效的 GitHub 事件。
有关详细信息,请参阅“将 Webhook 与 GitHub 应用配合使用”。 有关示例,请参阅“构建响应 Webhook 事件的 GitHub 应用”。
为用户留出时间接受新权限
当你向 GitHub App 添加存储库或组织权限时,在其个人帐户或组织中安装了该应用的用户将收到一封电子邮件,提示他们查看新权限。 在用户批准新权限之前,其应用安装将仅获得旧权限。
更新权限时,应考虑让应用后向兼容,为用户留出时间来接受新权限。 可以使用安装带有 new_permissions_accepted
操作属性的 Webhook,了解用户接受应用新权限的时间。
以安全的方式使用服务
如果应用使用第三方服务,则应以安全的方式使用它们:
- 应用使用的任何服务都应具有唯一的登录名和密码。
- 应用程序不应共享服务帐户(如电子邮件或数据库服务)来管理 SaaS 服务。
- 只有履行管理职责的员工才应具有托管应用的基础结构的管理员访问权限。
添加日志记录和监视
请考虑为应用添加日志记录和监视功能。 安全日志可以包括:
- 身份验证和授权事件
- 服务配置更改
- 对象读取和写入
- 用户和组权限更改
- 角色提升到管理员
日志应为每个事件使用一致的时间戳,并应记录所有记录事件的用户、IP 地址或主机名。
启用数据删除
如果 GitHub App 可供其他用户或组织使用,则应为用户和组织所有者提供删除其数据的方法。 用户应无需发送电子邮件或致电支持人员即可删除其数据。