1.使用Go模块
从1.1.1版开始,Go Modules系统是正式的依赖项管理系统,而旧的Vendor和Dep系统已被弃用。Go Modules允许依赖项版本固定,包括传递模块,还可以通过go.sum校验和数据库提供针对意外模块突变的保证。

首先,您应该通过go mod init [namespace/project-name]在最顶层的目录中运行来初始化项目。

$ go mod init mycorp.com/myapp
这将在当前目录中创建一个名为的文件,go.mod其中包含您的项目名称和当前使用的Go版本。假设你的源代码在他们包装的产品进口,只需运行go build (或者test,install等)将更新go.mod与使用,包括它们的版本的模块文件。您还可以使用go get更新依赖项,从而可以将依赖项更新到特定版本,这也将更新go.mod。

示例go.mod文件:

module mycorp.com/myapp
go 1.15
require (
github.com/containerd/console v1.0.1
rsc.io/quote/v3 v3.1.0
)
请注意,go.sum还创建了一个名为的文件。该文件包含每个所用模块的哈希列表,Go可以利用该列表来验证每个构建都使用相同的二进制文件。无论是go.mod和go.sum文件应该检查与您的应用程序代码的源代码控制。

官方Go Blog上的《使用Go模块》教程是一个很好的资源,可用于学习有关Go模块的更多信息,包括如何固定传递依赖版本,清理未使用的依赖等等。

2.扫描CVE的依赖关系
与大多数项目一样,应用程序所依赖的模块中的代码量通常超过应用程序本身的代码量,并且这些外部依赖性是引入安全漏洞的常见媒介。诸如Snyk之类的工具(由我们广泛的漏洞数据库提供支持)可用于测试这些依赖关系图中的已知漏洞,建议进行升级以解决所发现的问题,甚至可以持续监视您的项目以发现将来发现的任何新漏洞。

例如,仅synk test在Go应用程序上运行将解析您的模块并报告所有已知的CVE,以及有关您可以升级到的任何固定版本的信息。此外,基于Web的Snyk工具可以直接,连续地监视GitHub存储库,即使在您未更改代码或未在其上运行CI的情况下,也可以提醒您将来发现的漏洞。

CLI示例

3.使用Go标准加密软件包而不是第三方
Go标准库加密软件包已通过安全研究人员的严格审核,但由于它们并不全面,因此您可能会倾向于使用第三方软件包。

就像不使用自己的加密算法一样,您应该非常警惕第三方加密库,因为它们可能会或可能不会受到相同级别的审核。了解您的来源。

4.使用html / template帮助避免XSS攻击
使用io.WriteString()或text/template软件包将未过滤的字符串传递回Web客户端会使您的用户遭受跨站点脚本(XSS)攻击。这是因为返回的字符串中的所有HTML标签都将不经过编码地呈现到输出流,并且Content-Type: plain/text如果未明确设置,则还可能发送带有错误定义的响应标头。

使用该html/template软件包是一种自动对返回的内容进行Web编码的简单方法,而不是试图确保已在应用程序逻辑中手动完成了编码。在OWASP / GO-SCP文档具有优良的篇章,例如详细说明这个话题。

5.换壳
在Go中,subshell基本上可以直接通过Shell访问您的系统,其使用通常仅限于命令行工具类型的应用程序。在可能的情况下,始终希望使用适当的模块在Go代码中本地实现的解决方案。

如果确实需要使用子外壳,请注意清除可能传递给它的任何外部源数据以及返回的数据,以确保您的应用程序不会暴露有关基础系统的不必要的细节。这种关心类似于您对呈现模板的攻击(请参阅上面的#4)或SQL命令注入所给予的关注。还应考虑将调用运行外部流程作为应用程序请求线程的一部分进行操作,可能会产生其他副作用,这些副作用是您无法从Go代码中控制的,例如对文件系统的更改,对外部依赖项的调用或对安全格局的更改可能会阻止此类调用,例如,由在容器中运行或由AppArmor,SELinux等工具施加的限制