From 95941a71e87d6ccd6318bfd95c56929b01edfafd Mon Sep 17 00:00:00 2001 From: Matt Holt Date: Tue, 17 Feb 2026 16:52:54 -0700 Subject: [PATCH] chore: Add nolints to work around haywire linters (#7493) * chore: Add nolints to work around haywire linters * More lint wrangling --- caddyconfig/httploader.go | 2 +- caddyconfig/load.go | 2 +- caddytest/caddytest.go | 6 +++--- caddytest/integration/acmeserver_test.go | 4 ++-- cmd/commandfuncs.go | 4 ++-- modules/caddyhttp/caddyauth/basicauth.go | 2 +- modules/caddyhttp/celmatcher.go | 2 ++ modules/caddyhttp/fileserver/browse.go | 1 + modules/caddyhttp/reverseproxy/healthchecks.go | 2 +- modules/caddyhttp/reverseproxy/selectionpolicies.go | 2 +- modules/caddyhttp/reverseproxy/streaming.go | 2 +- modules/caddyhttp/routes.go | 2 +- modules/caddyhttp/staticresp.go | 2 +- modules/caddypki/adminapi.go | 4 ++-- modules/caddypki/crypto.go | 2 +- modules/caddytls/acmeissuer.go | 2 +- modules/caddytls/capools.go | 2 +- modules/caddytls/certmanagers.go | 2 +- modules/caddytls/zerosslissuer.go | 2 +- 19 files changed, 25 insertions(+), 22 deletions(-) diff --git a/caddyconfig/httploader.go b/caddyconfig/httploader.go index a25041a34..e1a0fc85b 100644 --- a/caddyconfig/httploader.go +++ b/caddyconfig/httploader.go @@ -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 { diff --git a/caddyconfig/load.go b/caddyconfig/load.go index 9422d2fbb..d2498ed6f 100644 --- a/caddyconfig/load.go +++ b/caddyconfig/load.go @@ -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 } diff --git a/caddytest/caddytest.go b/caddytest/caddytest.go index dfced29cf..26fa0533e 100644 --- a/caddytest/caddytest.go +++ b/caddytest/caddytest.go @@ -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) } diff --git a/caddytest/integration/acmeserver_test.go b/caddytest/integration/acmeserver_test.go index d6a9ba005..06deaa0ef 100644 --- a/caddytest/integration/acmeserver_test.go +++ b/caddytest/integration/acmeserver_test.go @@ -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) } } diff --git a/cmd/commandfuncs.go b/cmd/commandfuncs.go index 8e46ba63b..3b458c2ba 100644 --- a/cmd/commandfuncs.go +++ b/cmd/commandfuncs.go @@ -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) } diff --git a/modules/caddyhttp/caddyauth/basicauth.go b/modules/caddyhttp/caddyauth/basicauth.go index 81b62d8eb..4152d7908 100644 --- a/modules/caddyhttp/caddyauth/basicauth.go +++ b/modules/caddyhttp/caddyauth/basicauth.go @@ -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 } diff --git a/modules/caddyhttp/celmatcher.go b/modules/caddyhttp/celmatcher.go index b67cb9e92..3038c8926 100644 --- a/modules/caddyhttp/celmatcher.go +++ b/modules/caddyhttp/celmatcher.go @@ -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]) } } diff --git a/modules/caddyhttp/fileserver/browse.go b/modules/caddyhttp/fileserver/browse.go index 52aa7a9f8..304417009 100644 --- a/modules/caddyhttp/fileserver/browse.go +++ b/modules/caddyhttp/fileserver/browse.go @@ -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 { diff --git a/modules/caddyhttp/reverseproxy/healthchecks.go b/modules/caddyhttp/reverseproxy/healthchecks.go index b72e723e0..a194b88c8 100644 --- a/modules/caddyhttp/reverseproxy/healthchecks.go +++ b/modules/caddyhttp/reverseproxy/healthchecks.go @@ -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( diff --git a/modules/caddyhttp/reverseproxy/selectionpolicies.go b/modules/caddyhttp/reverseproxy/selectionpolicies.go index 2059c3ecf..3b68f504c 100644 --- a/modules/caddyhttp/reverseproxy/selectionpolicies.go +++ b/modules/caddyhttp/reverseproxy/selectionpolicies.go @@ -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"` diff --git a/modules/caddyhttp/reverseproxy/streaming.go b/modules/caddyhttp/reverseproxy/streaming.go index 0a8118520..38f056cd8 100644 --- a/modules/caddyhttp/reverseproxy/streaming.go +++ b/modules/caddyhttp/reverseproxy/streaming.go @@ -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)) diff --git a/modules/caddyhttp/routes.go b/modules/caddyhttp/routes.go index 78bf12209..d029d19b9 100644 --- a/modules/caddyhttp/routes.go +++ b/modules/caddyhttp/routes.go @@ -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(']') diff --git a/modules/caddyhttp/staticresp.go b/modules/caddyhttp/staticresp.go index 1a5bbb9e1..439ba4f1f 100644 --- a/modules/caddyhttp/staticresp.go +++ b/modules/caddyhttp/staticresp.go @@ -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 diff --git a/modules/caddypki/adminapi.go b/modules/caddypki/adminapi.go index c37b8d7b6..dcd3b5816 100644 --- a/modules/caddypki/adminapi.go +++ b/modules/caddypki/adminapi.go @@ -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 diff --git a/modules/caddypki/crypto.go b/modules/caddypki/crypto.go index 715155eb2..cfe46cd6d 100644 --- a/modules/caddypki/crypto.go +++ b/modules/caddypki/crypto.go @@ -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 diff --git a/modules/caddytls/acmeissuer.go b/modules/caddytls/acmeissuer.go index 41c0e20a1..f254f7b2b 100644 --- a/modules/caddytls/acmeissuer.go +++ b/modules/caddytls/acmeissuer.go @@ -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) } diff --git a/modules/caddytls/capools.go b/modules/caddytls/capools.go index 55abb7466..97ce6af2b 100644 --- a/modules/caddytls/capools.go +++ b/modules/caddytls/capools.go @@ -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 } diff --git a/modules/caddytls/certmanagers.go b/modules/caddytls/certmanagers.go index 0a9d459df..68014635e 100644 --- a/modules/caddytls/certmanagers.go +++ b/modules/caddytls/certmanagers.go @@ -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 } diff --git a/modules/caddytls/zerosslissuer.go b/modules/caddytls/zerosslissuer.go index b8727ab66..3421e816a 100644 --- a/modules/caddytls/zerosslissuer.go +++ b/modules/caddytls/zerosslissuer.go @@ -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.