chore: Add nolints to work around haywire linters (#7493)
Some checks failed
Tests / test (./cmd/caddy/caddy, ~1.26.0, macos-14, 0, 1.26, mac) (push) Waiting to run
Tests / test (./cmd/caddy/caddy.exe, ~1.26.0, windows-latest, True, 1.26, windows) (push) Waiting to run
Lint / lint (macos-14, mac) (push) Waiting to run
Lint / lint (windows-latest, windows) (push) Waiting to run
Tests / test (./cmd/caddy/caddy, ~1.26.0, ubuntu-latest, 0, 1.26, linux) (push) Failing after 1m23s
Tests / test (s390x on IBM Z) (push) Has been skipped
Tests / goreleaser-check (push) Has been skipped
Cross-Build / build (~1.26.0, 1.26, aix) (push) Successful in 1m27s
Cross-Build / build (~1.26.0, 1.26, darwin) (push) Successful in 1m24s
Cross-Build / build (~1.26.0, 1.26, dragonfly) (push) Successful in 1m21s
Cross-Build / build (~1.26.0, 1.26, freebsd) (push) Successful in 1m20s
Cross-Build / build (~1.26.0, 1.26, illumos) (push) Successful in 1m27s
Cross-Build / build (~1.26.0, 1.26, linux) (push) Successful in 1m23s
Cross-Build / build (~1.26.0, 1.26, netbsd) (push) Successful in 1m54s
Cross-Build / build (~1.26.0, 1.26, openbsd) (push) Successful in 1m32s
Cross-Build / build (~1.26.0, 1.26, solaris) (push) Successful in 1m40s
Cross-Build / build (~1.26.0, 1.26, windows) (push) Successful in 1m31s
Lint / lint (ubuntu-latest, linux) (push) Successful in 2m0s
Lint / govulncheck (push) Successful in 1m18s
Lint / dependency-review (push) Failing after 23s
OpenSSF Scorecard supply-chain security / Scorecard analysis (push) Failing after 35s

* chore: Add nolints to work around haywire linters

* More lint wrangling
This commit is contained in:
Matt Holt 2026-02-17 16:52:54 -07:00 committed by GitHub
parent 3adcafd4c1
commit 95941a71e8
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
19 changed files with 25 additions and 22 deletions

View File

@ -136,7 +136,7 @@ func (hl HTTPLoader) LoadConfig(ctx caddy.Context) ([]byte, error) {
}
func attemptHttpCall(client *http.Client, request *http.Request) (*http.Response, error) {
resp, err := client.Do(request)
resp, err := client.Do(request) //nolint:gosec // no SSRF; comes from trusted config
if err != nil {
return nil, fmt.Errorf("problem calling http loader url: %v", err)
} else if resp.StatusCode < 200 || resp.StatusCode > 499 {

View File

@ -106,7 +106,7 @@ func (adminLoad) handleLoad(w http.ResponseWriter, r *http.Request) error {
if err != nil {
caddy.Log().Named("admin.api.load").Error(err.Error())
}
_, _ = w.Write(respBody)
_, _ = w.Write(respBody) //nolint:gosec // false positive: no XSS here
}
body = result
}

View File

@ -187,7 +187,7 @@ func (tc *Tester) initServer(rawConfig string, configType string) error {
req.Header.Add("Content-Type", "text/"+configType)
}
res, err := client.Do(req)
res, err := client.Do(req) //nolint:gosec // no SSRF because URL is hard-coded to localhost, and port comes from config
if err != nil {
tc.t.Errorf("unable to contact caddy server. %s", err)
return err
@ -279,7 +279,7 @@ func validateTestPrerequisites(tc *Tester) error {
return err
}
tc.t.Cleanup(func() {
os.Remove(f.Name())
os.Remove(f.Name()) //nolint:gosec // false positive, filename comes from std lib, no path traversal
})
if _, err := fmt.Fprintf(f, initConfig, tc.config.AdminPort); err != nil {
return err
@ -506,7 +506,7 @@ func applyHeaders(t testing.TB, req *http.Request, requestHeaders []string) {
func (tc *Tester) AssertResponseCode(req *http.Request, expectedStatusCode int) *http.Response {
tc.t.Helper()
resp, err := tc.Client.Do(req)
resp, err := tc.Client.Do(req) //nolint:gosec // no SSRFs demonstrated
if err != nil {
tc.t.Fatalf("failed to call server %s", err)
}

View File

@ -127,7 +127,7 @@ func TestACMEServerAllowPolicy(t *testing.T) {
_, err := client.ObtainCertificateForSANs(ctx, account, certPrivateKey, []string{"not-matching.localhost"})
if err == nil {
t.Errorf("obtaining certificate for 'not-matching.localhost' domain")
} else if err != nil && !strings.Contains(err.Error(), "urn:ietf:params:acme:error:rejectedIdentifier") {
} else if !strings.Contains(err.Error(), "urn:ietf:params:acme:error:rejectedIdentifier") {
t.Logf("unexpected error: %v", err)
}
}
@ -200,7 +200,7 @@ func TestACMEServerDenyPolicy(t *testing.T) {
_, err := client.ObtainCertificateForSANs(ctx, account, certPrivateKey, []string{"deny.localhost"})
if err == nil {
t.Errorf("obtaining certificate for 'deny.localhost' domain")
} else if err != nil && !strings.Contains(err.Error(), "urn:ietf:params:acme:error:rejectedIdentifier") {
} else if !strings.Contains(err.Error(), "urn:ietf:params:acme:error:rejectedIdentifier") {
t.Logf("unexpected error: %v", err)
}
}

View File

@ -74,7 +74,7 @@ func cmdStart(fl Flags) (int, error) {
// ensure it's the process we're expecting - we can be
// sure by giving it some random bytes and having it echo
// them back to us)
cmd := exec.Command(os.Args[0], "run", "--pingback", ln.Addr().String())
cmd := exec.Command(os.Args[0], "run", "--pingback", ln.Addr().String()) //nolint:gosec // no command injection that I can determine...
// we should be able to run caddy in relative paths
if errors.Is(cmd.Err, exec.ErrDot) {
cmd.Err = nil
@ -820,7 +820,7 @@ func AdminAPIRequest(adminAddr, method, uri string, headers http.Header, body io
},
}
resp, err := client.Do(req)
resp, err := client.Do(req) //nolint:gosec // the only SSRF here would be self-sabatoge I think
if err != nil {
return nil, fmt.Errorf("performing request: %v", err)
}

View File

@ -287,7 +287,7 @@ type Account struct {
// The user's hashed password, in Modular Crypt Format (with `$` prefix)
// or base64-encoded.
Password string `json:"password"`
Password string `json:"password"` //nolint:gosec // false positive, this is a hashed password
password []byte
}

View File

@ -412,10 +412,12 @@ func CELMatcherImpl(macroName, funcName string, matcherDataTypes []*cel.Type, fa
return nil, fmt.Errorf("unsupported matcher data type: %s, %s", matcherDataTypes[0], matcherDataTypes[1])
}
case 3:
// nolint:gosec // false positive, impossible to be out of bounds; see: https://github.com/securego/gosec/issues/1525
if matcherDataTypes[0] == cel.StringType && matcherDataTypes[1] == cel.StringType && matcherDataTypes[2] == cel.StringType {
macro = parser.NewGlobalMacro(macroName, 3, celMatcherStringListMacroExpander(funcName))
matcherDataTypes = []*cel.Type{cel.ListType(cel.StringType)}
} else {
// nolint:gosec // false positive, impossible to be out of bounds; see: https://github.com/securego/gosec/issues/1525
return nil, fmt.Errorf("unsupported matcher data type: %s, %s, %s", matcherDataTypes[0], matcherDataTypes[1], matcherDataTypes[2])
}
}

View File

@ -169,6 +169,7 @@ func (fsrv *FileServer) serveBrowse(fileSystem fs.FS, root, dirPath string, w ht
// Actual files
for _, item := range listing.Items {
//nolint:gosec // not sure how this could be XSS unless you lose control of the file system (like aren't sanitizing) and client ignores Content-Type of text/plain
if _, err := fmt.Fprintf(writer, "%s\t%s\t%s\n",
item.Name, item.HumanSize(), item.HumanModTime("January 2, 2006 at 15:04:05"),
); err != nil {

View File

@ -500,7 +500,7 @@ func (h *Handler) doActiveHealthCheck(dialInfo DialInfo, hostAddr string, networ
}
// do the request, being careful to tame the response body
resp, err := h.HealthChecks.Active.httpClient.Do(req)
resp, err := h.HealthChecks.Active.httpClient.Do(req) //nolint:gosec // no SSRF
if err != nil {
if c := h.HealthChecks.Active.logger.Check(zapcore.InfoLevel, "HTTP request failed"); c != nil {
c.Write(

View File

@ -617,7 +617,7 @@ type CookieHashSelection struct {
// The HTTP cookie name whose value is to be hashed and used for upstream selection.
Name string `json:"name,omitempty"`
// Secret to hash (Hmac256) chosen upstream in cookie
Secret string `json:"secret,omitempty"`
Secret string `json:"secret,omitempty"` //nolint:gosec // yes it's exported because it needs to encode to JSON
// The cookie's Max-Age before it expires. Default is no expiry.
MaxAge caddy.Duration `json:"max_age,omitempty"`

View File

@ -529,7 +529,7 @@ func maskBytes(key [4]byte, pos int, b []byte) int {
// Create aligned word size key.
var k [wordSize]byte
for i := range k {
k[i] = key[(pos+i)&3]
k[i] = key[(pos+i)&3] // nolint:gosec // false positive, impossible to be out of bounds; see: https://github.com/securego/gosec/issues/1525
}
kw := *(*uintptr)(unsafe.Pointer(&k))

View File

@ -447,7 +447,7 @@ func (ms MatcherSets) String() string {
result.WriteByte('[')
for _, matcherSet := range ms {
for _, matcher := range matcherSet {
result.WriteString(fmt.Sprintf(" %#v", matcher))
fmt.Fprintf(&result, " %#v", matcher)
}
}
result.WriteByte(']')

View File

@ -246,7 +246,7 @@ func (s StaticResponse) ServeHTTP(w http.ResponseWriter, r *http.Request, next H
// write response body
if statusCode != http.StatusEarlyHints && body != "" {
fmt.Fprint(w, body)
fmt.Fprint(w, body) //nolint:gosec // no XSS unless you sabatoge your own config
}
// continue handling after Early Hints as they are not the final response

View File

@ -163,9 +163,9 @@ func (a *adminAPI) handleCACerts(w http.ResponseWriter, r *http.Request) error {
}
w.Header().Set("Content-Type", "application/pem-certificate-chain")
_, err = w.Write(interCert)
_, err = w.Write(interCert) //nolint:gosec // false positive... no XSS in a PEM for cryin' out loud
if err == nil {
_, _ = w.Write(rootCert)
_, _ = w.Write(rootCert) //nolint:gosec // false positive... no XSS in a PEM for cryin' out loud
}
return nil

View File

@ -77,7 +77,7 @@ type KeyPair struct {
// The private key. By default, this should be the path to
// a PEM file unless format is something else.
PrivateKey string `json:"private_key,omitempty"`
PrivateKey string `json:"private_key,omitempty"` //nolint:gosec // false positive: yes it's exported, since it needs to encode/decode as JSON; and is often just a filepath
// The format in which the certificate and private
// key are provided. Default: pem_file

View File

@ -337,7 +337,7 @@ func (iss *ACMEIssuer) generateZeroSSLEABCredentials(ctx context.Context, acct a
req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
req.Header.Set("User-Agent", certmagic.UserAgent)
resp, err := http.DefaultClient.Do(req)
resp, err := http.DefaultClient.Do(req) //nolint:gosec // no SSRF since URL is from trusted config
if err != nil {
return nil, acct, fmt.Errorf("performing EAB credentials request: %v", err)
}

View File

@ -588,7 +588,7 @@ func (hcp *HTTPCertPool) Provision(ctx caddy.Context) error {
if err != nil {
return err
}
res, err := httpClient.Do(req)
res, err := httpClient.Do(req) //nolint:gosec // SSRF false positive... uri comes from config
if err != nil {
return err
}

View File

@ -155,7 +155,7 @@ func (hcg HTTPCertGetter) GetCertificate(ctx context.Context, hello *tls.ClientH
return nil, err
}
resp, err := http.DefaultClient.Do(req)
resp, err := http.DefaultClient.Do(req) //nolint:gosec // SSRF false positive... request URI comes from config
if err != nil {
return nil, err
}

View File

@ -40,7 +40,7 @@ func init() {
type ZeroSSLIssuer struct {
// The API key (or "access key") for using the ZeroSSL API.
// REQUIRED.
APIKey string `json:"api_key,omitempty"`
APIKey string `json:"api_key,omitempty"` //nolint:gosec // false positive... yes this is exported, for JSON interop
// How many days the certificate should be valid for.
// Only certain values are accepted; see ZeroSSL docs.