composer安装Laravel 11报错:laravel/framework[v11.9.0, …, v11.23.3] require fruitcake/php-cors ^1.3 -> found fruitcake/php-cors[dev-feat-setOptions, dev-master, dev-maincomposer…

我在使用composer安装Laravel 11的时候,遇到如下错误:

Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - laravel/framework[v11.9.0, ..., v11.23.3] require fruitcake/php-cors ^1.3 -> found fruitcake/php-cors[dev-feat-setOptions, dev-master, dev-main, dev-test-8.2, v0.1.0, v0.1.1, v0.1.2, v1.0-alpha1, ..., 1.2.x-dev (alias of dev-master)] but it does not match the constraint.
    - Root composer.json requires laravel/framework ^11.9 -> satisfiable by laravel/framework[v11.9.0, ..., v11.23.3].

原因是阿里云composer镜像源中没有fruitcake/php-cors包的最新版。

解决方法是,切换回默认的composer镜像源:

composer config -g --unset repos.packagist

执行composer install就安装成功了,不再报错。

参考

https://github.com/laravel/framework/issues/51201

升级PHP版本导致WordPress无法显示文章,而是显示“有点尴尬诶!该页无法显示。”的解决方法

我的WordPress版本是5.4.15,当我把服务器系统里的PHP 7.2升级到PHP 8.2后,通过浏览器访问WordPress网站,无法显示文章,而是显示“有点尴尬诶!该页无法显示。”这句话。

经测试,PHP可以正常连接到MySQL数据库。

原因应该是WordPress 5.4.15用到的某些PHP函数在PHP 8.2过时了。

升级WordPress到最新版本解决了这个问题。

为什么PHP的Composer包管理使用vendor模式而非全局模式?

vendor模式即在每个项目都创建一个vendor目录,用来存储本项目依赖的第三方模块的包或库文件。

全局模式即在操作系统的某个全局目录(一般是用户家目录里的某个子目录或者操作系统的某个系统目录)里,存储第三方模块的包或库文件,可以被多个项目共用,优点是相对于vendor模式节省存储空间。

都说PHP项目上线速度快,最大原因是PHP项目可以热更新热部署,通过FTP把整个PHP项目的源代码文件上传到服务器就部署好了,都不用重启Web服务器软件的。但是如果使用全局模式就会破坏这种方便的部署方式,因为你把PHP项目的源代码文件上传到服务器后,要么你还要把全局目录上传到服务器,要么你还需要在服务器运行composer命令安装本项目所缺的依赖项。使用vendor模式,就没有这个烦恼了。

Composer包管理器使用vendor模式,而非全局模式,应该就是出于这点考虑。像Go的go get、Java的maven、Node.js的npm、Python的pip使用全局模式,是因为它们无法做到像PHP那样热更新热部署Web项目。

PHP Warning: Module ‘curl‘ already loaded in Unknown on line 0警告的解决方法

我的软件环境是:Ubuntu 22操作系统,使用apt安装的PHP 8.2。

如果在执行PHP相关命令时,看到一条警告消息:

PHP Warning: Module ‘curl‘ already loaded in Unknown on line 0

那是由于curl模块被重复启用。如果在/etc/php/8.2/fpm/php.ini和/etc/php/8.2/fpm/conf.d/20-curl.ini两处配置文件里都启用了curl扩展,就会报这个警告。

解决方法是在/etc/php/8.2/fpm/conf.d/20-curl.ini配置文件中启用curl扩展即可,而在其他配置文件中都不启用curl扩展。

/etc/php/8.2/fpm/conf.d/里的配置文件其实都是/etc/php/8.2/mods-available/里的配置文件的符号链接,这些配置文件中的扩展是被PHP默认启用的。

修改了配置文件记得重启php-fpm服务。最后只要在php -m命令的输出中或者通过浏览器访问phpinfo函数的PHP脚本的输出中看到curl了,就说明已启用curl扩展。

Go安全

本文翻译自《Security》。

此页面为Go开发人员提供一些资源,以提高Go项目的安全性。

(另请参阅:Go开发人员应该知道的Go项目安全最佳实践。)

查找并修复已知的安全漏洞

Go的漏洞检测旨在为开发人员提供低噪声、可靠的工具,以了解可能影响其项目的已知漏洞。有关概述,请从Go漏洞管理体系架构和常见问题页面开始。对于应用方法,请探索以下工具。

使用govulcheck扫描代码以查找漏洞

开发人员可以使用govulcheck工具来确定是否有任何已知的漏洞会影响他们的代码,并根据实际调用的有安全漏洞的函数和方法来确定下一步先做什么。

在编辑器中检测漏洞

VS Code Go扩展可以检查第三方依赖项并发现相关漏洞。

查找你的项目用到的Go模块

Pkg.go.dev是一个用于发现、评估和学习有关go包和模块的更多信息的网站。在pkg.go.dev上发现和评估go包时,如果该版本存在漏洞,你会在页面顶部看到一条横幅。此外,你可以在go包的版本历史页面上看到影响某个版本的它的安全漏洞有哪些。

浏览安全漏洞数据库

Go漏洞数据库直接从Go包维护者以及MITRE和GitHub等外部来源收集数据。报告由Go Security团队策划。

报告Go项目中的安全漏洞

有关如何报告Go项目中的安全漏洞的说明,请参阅Go安全策略。该文章还详细介绍了Go安全团队跟踪问题并向公众披露的过程。有关过去的修复安全漏洞的记录的详细信息,请参阅发布历史记录。根据发布策略,我们在Go包的两个最新主版本上进行安全修复。

使用模糊测试发现意外输入

Go原生提供的模糊测试是一种自动测试,它不断地往程序的入数据来发现Bug。从Go 1.18开始,标准工具链加入模糊测试工具。也可以使用OSS fuzz,它支持原生的Go模糊测试。

使用Go的加密库提供的安全服务

Go的加密库旨在帮助开发人员构建安全的应用程序。请参阅有关加密的Go包golang.org/x/crypto/的文档

教程:使用govulncheck发现和修复有安全问题的依赖项

本文翻译自《Tutorial: Find and fix vulnerable dependencies with govulncheck》。

Govulncheck是一个低噪音的工具,可以帮助你发现并修复Go项目中易受攻击的依赖项。它通过扫描项目的依赖项以查找已知的漏洞,并识别出对这些漏洞的任何直接或间接调用的项目代码。

在本教程中,你将学习如何使用govulcheck扫描一个简单的程序以查找漏洞,如何对漏洞进行优先级排序和评估,以便首先集中精力修复最重要的漏洞。

要了解更多关于govulcheck的信息,请参阅govulceck文档和这篇关于Go漏洞管理的博客文章。我们也很乐意听取你的反馈。

先决条件

  • 使用Go 1.18或更高版本。Govulncheck旨在与Go 1.18及以后的版本配合使用。我们建议使用最新版本的Go来遵循本教程。(有关安装Go的说明,请参阅安装Go。)
  • 一个代码编辑器。任何文本编辑都可以很好地工作。
  • 一个命令终端。Go在Linux和Mac的终端程序,以及Windows中的PowerShell或cmd上都能很好地工作。

本教程将带你完成以下步骤:

1 创建一个Go模块示例,它的某个依赖项有漏洞

2 安装并运行govulcheck

3 评估漏洞 4 升级并修复有漏洞的依赖项

创建一个Go模块示例

步骤1,首先,创建一个名为vulntutorial的新文件夹并初始化Go模块。例如,从当前目录运行以下命令:

$ mkdir vuln-tutorial
$ cd vuln-tutorial
$ go mod init vuln.tutorial

步骤2,在vuln-tutorial文件夹中创建一个名为main.go的文件,并将以下代码复制到其中:

package main

import (
        "fmt"
        "os"

        "golang.org/x/text/language"
)

func main() {
        for _, arg := range os.Args[1:] {
                tag, err := language.Parse(arg)
                if err != nil {
                        fmt.Printf("%s: error: %v\n", arg, err)
                } else if tag == language.Und {
                        fmt.Printf("%s: undefined\n", arg)
                } else {
                        fmt.Printf("%s: tag %s\n", arg, tag)
                }
        }
}

此示例程序将语言标签的一个列表作为命令行参数,并为每个标签打印一条消息,指示标签是否解析成功、是否未定义或者解析标签时是否出错。

步骤3,运行go mod tidy命令,把main.go的代码所需的所有依赖项记录到go.mod文件。在vuln-tutorial文件夹所在目录,运行以下命令:

$ go mod tidy

你应该能看到类似如下输出:

go: finding module for package golang.org/x/text/language
go: downloading golang.org/x/text v0.9.0
go: found golang.org/x/text/language in golang.org/x/text v0.9.0

第4步,打开go.mod文件,它的内容应该如下所示:

module vuln.tutorial

go 1.20

require golang.org/x/text v0.9.0

第5步,降级golang.org/x/text依赖项的版本到v0.3.5,这个版本包含一个众所周知的安全漏洞:

$ go get golang.org/x/[email protected]

你应该能看到类似如下输出:

go: downgraded golang.org/x/text v0.9.0 => v0.3.5

打开go.mod文件,它的内容应该如下所示:

module vuln.tutorial

go 1.20

require golang.org/x/text v0.3.5

接下来我们使用govulncheck来发现vuln-tutorial项目中的安全漏洞。

安装并运行govulncheck

第6步,使用go install命令安装govulncheck:

$ go install golang.org/x/vuln/cmd/govulncheck@latest

第7步,在vuln-tutorial目录里运行govulncheck来分析vuln-tutorial项目中的安全漏洞:

$ govulncheck ./...

你应该会看到如下输出:

govulncheck is an experimental tool. Share feedback at https://go.dev/s/govulncheck-feedback.

Using go1.20.3 and [email protected] with
vulnerability data from https://vuln.go.dev (last modified 2023-04-18 21:32:26 +0000 UTC).

Scanning your code and 46 packages across 1 dependent module for known vulnerabilities...
Your code is affected by 1 vulnerability from 1 module.

Vulnerability #1: GO-2021-0113
  Due to improper index calculation, an incorrectly formatted
  language tag can cause Parse to panic via an out of bounds read.
  If Parse is used to process untrusted user inputs, this may be
  used as a vector for a denial of service attack.

  More info: https://pkg.go.dev/vuln/GO-2021-0113

  Module: golang.org/x/text
    Found in: golang.org/x/[email protected]
    Fixed in: golang.org/x/[email protected]

    Call stacks in your code:
      main.go:12:29: vuln.tutorial.main calls golang.org/x/text/language.Parse

=== Informational ===

Found 1 vulnerability in packages that you import, but there are no call
stacks leading to the use of this vulnerability. You may not need to
take any action. See https://pkg.go.dev/golang.org/x/vuln/cmd/govulncheck
for details.

Vulnerability #1: GO-2022-1059
  An attacker may cause a denial of service by crafting an
  Accept-Language header which ParseAcceptLanguage will take
  significant time to parse.
  More info: https://pkg.go.dev/vuln/GO-2022-1059
  Found in: golang.org/x/[email protected]
  Fixed in: golang.org/x/[email protected]

解释一下上述输出

注意,不同Go版本,上述输出可能不同。

我们的代码受到漏洞GO-2021-0113的影响,因为它直接调用golang.org/x/text/language的Parse函数,而这个函数在v0.3.5版本存在安全漏洞。

golang.org/x/text模块v0.3.5中存在另一个漏洞GO-2022-1059。然而,它被报告为“Informational”,因为我们的代码没有(直接或间接)调用这个安全漏洞相关的函数。

现在,让我们评估vuln-tutorial项目中的漏洞并确定要采取的行动。

评估漏洞

a.评估漏洞

首先,阅读漏洞的描述信息,并确定它是否真的适用于你的代码和用例。如果你需要更多信息,请访问“More info”链接。

根据描述,漏洞GO-2021-0113在使用Parse函数处理不受信任的用户输入时可能会引发panic。假设我们打算让我们的程序承受不受信任的输入,那么该漏洞可能就会被利用。

漏洞GO-2022-1059不会影响我们的代码,因为我们的代码没有从该依赖项中调用任何有安全漏洞的函数。

b.决定采取什么行动

为了解决GO-2021-0113漏洞问题,我们有以下几个选择:

选项1:升级到修复后的版本。如果有可用的修复,我们可以通过升级到该模块的修复版本来删除安全漏洞。

选项2:停止使用有安全漏洞的标识符。我们可以删除代码中对有安全漏洞的函数的所有调用。但我们需要找到一个替代方案,或者自己实现相关函数。

在本例情况下,我们可以使用修复后的版本,Parse函数是我们程序不可或缺的一部分。让我们将依赖项升级到“fixed in”版本v0.3.7。

漏洞GO-2022-1059与漏洞GO-2021-0113在同一模块中,而且它的修复版本是v0.3.8,所以我们可以通过升级到v0.3.8轻松地同时删除这两个漏洞。

升级并修复有安全漏洞的依赖项

幸运的是,升级并修复有安全漏洞的依赖项非常简单。

第8步,升级golang.org/x/text至v0.3.8版本:

$ go get golang.org/x/[email protected]

你应该能看到如下输出:

go: upgraded golang.org/x/text v0.3.5 => v0.3.8

请注意,我们也可以选择升级到最新版本,或v0.3.8之后的任何其他版本。

第9步,现在再次运行govulcheck:

$ govulncheck ./...

你现在会看到如下输出:

govulncheck is an experimental tool. Share feedback at https://go.dev/s/govulncheck-feedback.

Using go1.20.3 and [email protected] with
vulnerability data from https://vuln.go.dev (last modified 2023-04-06 19:19:26 +0000 UTC).

Scanning your code and 46 packages across 1 dependent module for known vulnerabilities...
No vulnerabilities found.

govuncheck确认没有发现漏洞。

使用命令govulcheck定期扫描依赖项,你可以识别、排序和解决安全漏洞来保护你的项目代码。

Go安全政策

本文翻译自《Go Security Policy》。

概述

本文档介绍Go Security团队处理报告的问题的流程以及预期的回复。

报告一个安全漏洞

Go发行版中的所有安全漏洞都应通过电子邮件报告给[email protected]。此邮件会发送给Go Security团队。

为了确保你的报告不被标记为垃圾邮件,请在电子邮件中的任何位置包含“vulnerability”一词。请在电子邮件中使用一行描述主题。

你的电子邮件将在7天内得到确认,在解决问题之前,你将了解最新进展。你的问题将在90天内解决或公开。

如果你在7天内没有收到电子邮件回复,请再次与Go安全团队联系,地址为[email protected]。请确保你的电子邮件中包含“vulnerability”一词。

如果再过3天,你仍未收到对报告的确认,则你的电子邮件可能已被标记为垃圾邮件。在这种情况下,请在此处提交问题。选择“我想报告谷歌产品(SQLi、XSS等)中的技术安全或滥用风险相关的错误”,并选中“Go”为受影响的产品。

跟踪问题

根据问题的性质,Go安全团队会将其归类为PUBLIC、PRIVATE或URGENT问题。所有安全问题都将被分配一个CVE编号。

PUBLIC

PUBLIC的问题影响非常有限,或者已经广为人知。

PUBLIC的问题被标记为“Proposal-Security”,通过公开的Go提案审查过程进行讨论,并返回到下一个计划的次要发布(minor releases)(每月发布一次)。发布公告包括这些问题的详细信息,但不会预先发布。

以下是过去发布的PUBLIC的问题的例子:

  • #44916:archive/zip:调用Reader.Open时可能会引发panic
  • #44913:encoding/xml:把自定义TokenReader传给xml.NewTokenDecoder时会引发无限循环
  • #40928: net/http/cgi,net/http/fcgi:但没有指定Content-Type时存在Cross-Site Scripting (XSS)攻击风险
  • #40618: encoding/binary: ReadUvarint和ReadVarint可以从非法输入中读取无限个字节
  • #36834: crypto/x509:Windows 10可以绕过证书验证

PRIVATE

PRIVATE中的问题违反了已提交的安全属性。

PRIVATE问题在下一个计划发布的次要版本中得到修复,并在此之前保持私有状态。

发布前三到七天,将发布预公告,宣布即将发布的版本中存在一个或多个安全修复程序,以及这些问题是否会影响标准库或(和)工具链,以及每个修复程序的CVE ID号码。

以下是过去发布的RIVATE的问题的例子:

  • #53416: path/filepath: Glob包会导致栈空间耗尽
  • #53616: go/parser:所有Parse*函数都存在栈空间耗尽的问题
  • #54658: net/http:GOAWAY发送GOAWAY给服务器后引发错误
  • #56284: syscall, os/exec:在环境变量中没有清除NUL

URGENT

URGENT问题对Go的生态系统的完整性构成威胁,或者正在被黑客积极利用,导致严重破坏。虽然最近没有这方面的例子,但它们可能包括net/http中的远程代码执行,或crypto/tls中的密钥恢复等。

URGENT问题是私下解决的,并会立即进行安全版本的发布,可能不会有预公告。

发送安全相关问题

如果你认为现有的某个问题与安全相关,我们请求你发送电子邮件至[email protected]。电子邮件应包括问题ID和为什么应根据此安全策略进行处理的简短描述。

披露和处理一个安全漏洞的流程

Go使用以下流程来披露和处理一个安全漏洞的流程:

  • 一旦收到一个安全报告,就会为其分配一个主处理流程。有个人负责协调整个修复和发布过程。
  • 问题已得到确认,并确定了受影响软件的列表。
  • 对代码进行审计,以发现任何潜在的类似问题。
  • 如果在与提交者协商后确定需要CVE编号,则主处理流程将获得一个。
  • 为最近的两个主版本号和head/master分支准备好修复程序。修复程序是为最近的两个主版本号准备的,并合并到head/master分支中。
  • 在应用修复程序的当天,会有公告发送到golang-announcement、golang-dev和golang-nuts。

这个过程可能需要一些时间,尤其是当需要与其他项目的维护人员进行协调时。我们将尽一切努力及时处理漏洞,但重要的是,我们要遵循上述流程,确保披露的漏洞得到一致的处理过程。

对于包括分配CVE号码在内的安全问题,该问题会在CVE详细信息网站国家漏洞披露网站的“Golang”产品下公开列出。

接收安全更新

接收安全公告的最佳方式是订阅golang-announce邮件列表。任何与安全问题有关的消息都将以[security]作为前缀。

对此政策的评论

如果你对改进此Go安全政策有任何建议,请提交一个问题进行讨论。

NPM今天应该做些什么才能阻止未来可能还会发生的类似于colors包故意破坏式更新这样的攻击

本文翻译自《What NPM Should Do Today To Stop A New Colors Attack Tomorrow》。

2022/01/10

周末,一位名叫Marak Squires的开发者故意破坏了他流行的NPM包colors和不太流行的包faker。在我写这篇文章的时候,NPM声称有18971个包直接依赖colors和2751个包直接依赖faker。据Open Source Insights统计,间接依赖colors的包至少有42000个。许多流行的NPM包都依赖于这些包。

NPM设计中的一个错误之处意味着,一旦最新版本的colors发布,新安装的基于colors的命令行工具就会立即开始使用它,而没有测试它是否与每个工具兼容。(剧透提醒:事实并非如此!)

具体的错误之处在于,当你使用NPM安装软件包(包括命令行工具)时,NPM会根据package.json文件中列出的需求以及当时的世界状态来选择依赖项版本,并且优先安装每个依赖项的最新版本。这意味着,从Marak更新colors包的那一刻起,aws-cdk和其他工具的安装就被中断,错误报告开始滚滚而来,就像下面这个那样

相关错误也出现在apostrophecdk8scompodocforeversdhexohighchartsjestnetlifyoclif等包里。

今天,NPM用户可能会对Marak感到沮丧,但Marak搞的破坏只是在终端上输出一些垃圾信息。情况其实可以更糟。即使忽略了这种故意破坏,非故意的错误也总是发生。从本质上讲,每一个开源软件许可证都指出,代码是在没有任何保证的情况下提供的。现代软件包管理器的设计需要预见并减轻这种风险。

任何运行现代生产系统的人都知道测试,然后是逐步或分阶段的部署,即在很长一段时间内逐步部署对运行中的系统的更改,以减少意外地同时删除所有内容的可能性。例如,上次我需要更改谷歌的核心DNS区域文件时,对该更改进行了多次回归测试,然后在24小时内一次一个地部署到谷歌的四个名称服务器中的每一个。回归测试检查了不该出现的意外情况,然后给了自动化系统和可靠性工程师足够的时间来逐步部署。

NPM的设计选择恰恰相反。最新版本的colors在所有人有机会测试它之前就被推广到了所有依赖它的包中,而且没有任何逐步升级的方法。用户现在可以通过固定其所有依赖项的确切版本来禁用这种行为。例如,这里是对aws-cdk的修复。这不是一个好答案,但至少这是能用的。

对于NPM和类似的包管理器来说,正确的前进道路是在安装新包时不要再优先安装所有依赖项的最新版本。相反,它们应该优先安装实际测试过的依赖项,或者尽可能接近这些版本的版本。我称之为高保真构建。相比之下,在周末安装aws-cdk和其他包的人得到了低保真度的构建:NPM插入了开发者从未测试过的新版本的colors包。用户在周末测试自己的项目时,测试失败了。

高保真度构建解决了测试问题和如何逐步升级问题。在aws-cdk作者有机会测试并在新版本的aws-cdk中引入之前,新版本的colors不会被aws-cdk包所接受。在那之后,所有新的aws-cdk包都会引入新的colors包,但所有其他包仍然不会受到影响,直到它们也测试并正式引入了新版本的colors包。

有许多方法可以生成高保真度构建。在Go中,一个包声明每个依赖项所需的最低版本,这就是构建项目时所使用的依赖项的版本,除非同一个项目里有某个依赖项依赖其中某个依赖项的更新的版本。然后,它只使用这个特定的更新版本,而不是刚刚在周末发布的、完全未经任何人测试的版本。有关这种方法的更多信息,请参阅“Go中的版本控制原则”。

NPM还有一个npm shrinkwrap命令和一个npm ci命令,这两个命令似乎都可以在某些有限的情况下解决这个问题。大多数受colors包影响的命令的作者和用户今天应该仔细研究这些命令。感谢NPM提供了这些命令,但他们不应该总是依赖这些命令。下一步应该是NPM安排这种保护默认发生。然后,当为依赖项安装新的包时,需要同样的保护,而不仅仅是在安装命令时。所有这些都需要更多的工作。

其他语言的包管理者也应该注意到这个问题。大多数包管理者在没有任何类型的测试的情况下自动采用新依赖项,也没有提供逐步升级软件包的方法,Marak的行为强调了这个问题,这给我们所有人带来了巨大的帮助。早就该解决这些问题了,否则下一次只会更糟。

Go开发人员应该知道的Go项目安全最佳实践

本文翻译自《Security Best Practices for Go Developers》。

点此回到《Go安全》。

此页面为Go开发人员提供了优先考虑项目安全的最佳实践。从使用自动化的模糊测试到轻松检查竞态条件(race condition),这些技巧可以帮助你的代码库更加安全可靠。

扫描源代码和二进制文件中的漏洞

定期扫描代码和二进制文件中的漏洞有助于及早发现潜在的安全风险。你可以使用由Go漏洞数据库支持的govulcheck来扫描代码中的漏洞,并分析哪些漏洞会真正影响到你。开始学习govuncheck教程

Govulncheck也可以集成到CI/CD工作流中。Go团队在GitHub Marketplace上为Govulcheck提供了一个GitHub动作( GitHub Action)。Govulncheck还支持-json标志,以帮助开发人员将漏洞扫描功能与其他CI/CD系统集成。

你还可以使用VS Code的Go扩展直接在编辑器中扫描漏洞。见本教程

使你的Go版本和依赖项保持最新

让你的Go版本保持最新,你就可以使用最新的语言功能、性能改进和已知安全漏洞的修补程序。更新的Go版本还确保了与新版本的依赖项的兼容性,有助于避免潜在的集成问题。查看Go版本的历史发布记录,查看在不同版本之间对Go进行了哪些更改。Go团队在整个发布周期中按照安全问题的议点发布,以解决安全漏洞。请确保更新到最新的Go的小版本号,以确保你拥有最新的安全修复程序。

维护最新的第三方依赖项对于Go生态系统中的软件的安全性、性能和遵守最新标准都至关重要。然而,在没有彻底审查的情况下更新到最新版本也可能存在风险,可能会引入新的Bug、不兼容的更改,甚至恶意代码。因此,虽然更新到最新的安全补丁和改进的依赖项至关重要,但每次更新都应该仔细审查和测试。

使用模糊测试来发现代码的边界漏洞

模糊测试是一种自动测试,它使用覆盖率导向(coverage guidance)来操纵随机输入并遍历代码,以发现和报告潜在的漏洞,例如SQL注入、缓冲区溢出、拒绝服务以及跨站点脚本攻击。模糊测试经常会触及程序员错过的边界测试用例,或者认为不太可能出错的边界测试用例。见本教程

使用Go的竞态检测器检查竞态情况

当两个或多个goroutine同时访问同一资源,并且其中至少有一个访问是写操作时,就会出现竞态情况。这可能会导致软件中出现不可预测、难以诊断的问题。使用内置的竞态检测器在Go代码中识别潜在的竞态情况,这可以帮助你确保并发程序的安全性和可靠性。不过,竞态检测器只会查找运行时发生的争用,没法在未执行的代码中查找。

要使用内置的竞态检测器,请在运行测试或构建应用程序时添加-race标志,例如go test -race。这将在启用竞态检测器的情况下编译代码,并报告它在运行时检测到的任何竞态情况。当竞态检测器在程序中发现数据冲突时,它将打印一份报告,其中包含冲突访问的堆栈跟踪,以及创建相关goroutine的堆栈。

使用Vet检查可疑的代码结构

Go的vet命令旨在分析源代码,并标记不一定是语法错误,但可能在运行时导致问题的潜在代码,例如无法访问到的代码、未使用的变量以及goroutine中常见的错误。在开发过程的早期发现这些问题,有助于保持代码质量,减少调试时间,并提高软件的整体可靠性。要为指定项目运行go vet,请运行:

go vet ./...

译者注:Goland这种IDE已经集成并会自动使用vet命令了。

订阅golang公告以获取安全相关发布的通知

包含安全修复程序的Go版本已预先发布到[email protected]邮件列表中。如果你想知道Go本身的安全修复何时开始,请订阅。