From 9ba23db45248c1d2151ba718d0471cf3f2ddf085 Mon Sep 17 00:00:00 2001 From: Claude Date: Fri, 8 May 2026 17:08:14 +0000 Subject: [PATCH] chore: clean up lint exclusions deferred in #98 Address pre-existing code issues that were suppressed in #98 to keep that PR scoped to the Go 1.25 / golangci-lint v2 toolchain bump. https://claude.ai/code/session_01S433Zq3Xzm3ZethsqkyaZF --- .golangci.yml | 21 --------------------- internal/logger/logger.go | 4 ++-- internal/nuclei/format/format.go | 16 ++++++++-------- internal/nuclei/templates/templates.go | 8 ++++++-- internal/scan/builtin/nuclei_module.go | 3 ++- internal/scan/ports.go | 7 ++++--- internal/scan/shodan.go | 12 ++++++------ internal/scan/subdomaintakeover.go | 2 +- sif.go | 8 ++++++-- 9 files changed, 35 insertions(+), 46 deletions(-) diff --git a/.golangci.yml b/.golangci.yml index 75a9fea..a699b97 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -72,15 +72,11 @@ linters: - unnecessaryDefer # common pattern in tests # inverting conditions in scan logic hurts readability - nestingReduce - - importShadow # nuclei output pkg alias conflict, intentional - - rangeValCopy # nuclei module iterates value types, fine here gosec: excludes: - G104 # errcheck covers this - G107 # pentesting tool -- variable URLs are the whole point - G110 # nuclei template decompression, acceptable context - - G301 # log/template dirs need 0755 for common tooling - - G302 # log files intentionally world-readable for tailing - G304 # sif reads user-supplied wordlist paths -- intentional exclusions: @@ -90,23 +86,6 @@ linters: linters: - errcheck - noctx - # net.* calls predate context plumbing; refactor tracked separately - - path: internal/scan/(ports|shodan|subdomaintakeover)\.go - linters: - - noctx - # Close on concrete types errcheck can't match to (io.Closer).Close - - path: internal/nuclei/templates/templates\.go - text: "tarball.Close" - linters: - - errcheck - - path: internal/scan/ports\.go - text: "tcp.Close" - linters: - - errcheck - - path: sif\.go - text: "logger.Close" - linters: - - errcheck issues: max-issues-per-linter: 50 diff --git a/internal/logger/logger.go b/internal/logger/logger.go index 6bdd6c0..07a3638 100644 --- a/internal/logger/logger.go +++ b/internal/logger/logger.go @@ -37,7 +37,7 @@ var defaultLogger = &Logger{ // Init creates the log directory if it doesn't exist. func Init(dir string) error { if _, err := os.Stat(dir); os.IsNotExist(err) { - if err := os.Mkdir(dir, 0o755); err != nil { + if err := os.Mkdir(dir, 0o750); err != nil { return err } } @@ -62,7 +62,7 @@ func (l *Logger) getWriter(path string) (*bufio.Writer, error) { return w, nil } - f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o666) + f, err := os.OpenFile(path, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0o600) if err != nil { return nil, err } diff --git a/internal/nuclei/format/format.go b/internal/nuclei/format/format.go index 7975207..2625aab 100644 --- a/internal/nuclei/format/format.go +++ b/internal/nuclei/format/format.go @@ -14,22 +14,22 @@ package format import ( "github.com/dropalldatabases/sif/internal/styles" - "github.com/projectdiscovery/nuclei/v3/pkg/output" + nucleiout "github.com/projectdiscovery/nuclei/v3/pkg/output" ) -func FormatLine(event *output.ResultEvent) string { - output := event.TemplateID +func FormatLine(event *nucleiout.ResultEvent) string { + line := event.TemplateID if event.MatcherName != "" { - output += ":" + styles.Highlight.Render(event.MatcherName) + line += ":" + styles.Highlight.Render(event.MatcherName) } else if event.ExtractorName != "" { - output += ":" + styles.Highlight.Render(event.ExtractorName) + line += ":" + styles.Highlight.Render(event.ExtractorName) } - output += " [" + event.Type + "]" - output += " [" + formatSeverity(event.Info.SeverityHolder.Severity.String()) + "]" + line += " [" + event.Type + "]" + line += " [" + formatSeverity(event.Info.SeverityHolder.Severity.String()) + "]" - return output + return line } func formatSeverity(severity string) string { diff --git a/internal/nuclei/templates/templates.go b/internal/nuclei/templates/templates.go index bf45ffa..80f117b 100644 --- a/internal/nuclei/templates/templates.go +++ b/internal/nuclei/templates/templates.go @@ -53,7 +53,11 @@ func Install(logger *log.Logger) error { if err != nil { return err } - defer tarball.Close() + defer func() { + if cerr := tarball.Close(); cerr != nil { + logger.Warnf("closing gzip reader: %v", cerr) + } + }() data := tar.NewReader(tarball) @@ -68,7 +72,7 @@ func Install(logger *log.Logger) error { switch header.Typeflag { case tar.TypeDir: - if err := os.Mkdir(header.Name, 0o755); err != nil { + if err := os.Mkdir(header.Name, 0o750); err != nil { return err } case tar.TypeReg: diff --git a/internal/scan/builtin/nuclei_module.go b/internal/scan/builtin/nuclei_module.go index 39eaaca..4e6509e 100644 --- a/internal/scan/builtin/nuclei_module.go +++ b/internal/scan/builtin/nuclei_module.go @@ -51,7 +51,8 @@ func (m *NucleiModule) Execute(ctx context.Context, target string, opts modules. } // Process nuclei results into module findings - for _, event := range nucleiResults { + for i := range nucleiResults { + event := &nucleiResults[i] severity := "info" switch event.Info.SeverityHolder.Severity.String() { diff --git a/internal/scan/ports.go b/internal/scan/ports.go index 8f12f73..00e8b2e 100644 --- a/internal/scan/ports.go +++ b/internal/scan/ports.go @@ -30,7 +30,7 @@ import ( const commonPorts = "https://raw.githubusercontent.com/dropalldatabases/sif-runtime/main/ports/top-ports.txt" -func Ports(scope string, url string, timeout time.Duration, threads int, logdir string) ([]string, error) { +func Ports(ctx context.Context, scope string, url string, timeout time.Duration, threads int, logdir string) ([]string, error) { log := output.Module("PORTS") log.Start() @@ -89,7 +89,8 @@ func Ports(scope string, url string, timeout time.Duration, threads int, logdir progress.Increment(strconv.Itoa(port)) charmlog.Debugf("Looking up: %d", port) - tcp, err := net.DialTimeout("tcp", fmt.Sprintf("%s:%d", sanitizedURL, port), timeout) + addr := fmt.Sprintf("%s:%d", sanitizedURL, port) + tcp, err := (&net.Dialer{Timeout: timeout}).DialContext(ctx, "tcp", addr) if err != nil { charmlog.Debugf("Error %d: %v", port, err) } else { @@ -100,7 +101,7 @@ func Ports(scope string, url string, timeout time.Duration, threads int, logdir mu.Lock() openPorts = append(openPorts, strconv.Itoa(port)) mu.Unlock() - tcp.Close() + _ = tcp.Close() } } }(thread) diff --git a/internal/scan/shodan.go b/internal/scan/shodan.go index 9f3a21c..549f3f3 100644 --- a/internal/scan/shodan.go +++ b/internal/scan/shodan.go @@ -160,20 +160,20 @@ func resolveHostname(hostname string) (string, error) { return hostname, nil } - ips, err := net.LookupIP(hostname) + addrs, err := net.DefaultResolver.LookupIPAddr(context.TODO(), hostname) if err != nil { return "", err } // prefer IPv4 - for _, ip := range ips { - if ip.To4() != nil { - return ip.String(), nil + for _, addr := range addrs { + if addr.IP.To4() != nil { + return addr.IP.String(), nil } } - if len(ips) > 0 { - return ips[0].String(), nil + if len(addrs) > 0 { + return addrs[0].IP.String(), nil } return "", fmt.Errorf("no IP addresses found for %s", hostname) diff --git a/internal/scan/subdomaintakeover.go b/internal/scan/subdomaintakeover.go index 0b989c0..8b086df 100644 --- a/internal/scan/subdomaintakeover.go +++ b/internal/scan/subdomaintakeover.go @@ -124,7 +124,7 @@ func checkSubdomainTakeover(subdomain string, client *http.Client) (bool, string if err != nil { if strings.Contains(err.Error(), "no such host") { // Check if CNAME exists - cname, err := net.LookupCNAME(subdomain) + cname, err := net.DefaultResolver.LookupCNAME(context.TODO(), subdomain) if err == nil && cname != "" { return true, "Dangling CNAME" } diff --git a/sif.go b/sif.go index 25ed7f8..eca9020 100644 --- a/sif.go +++ b/sif.go @@ -166,7 +166,11 @@ func (app *App) Run() error { if err := logger.Init(app.settings.LogDir); err != nil { return err } - defer logger.Close() + defer func() { + if err := logger.Close(); err != nil { + log.Errorf("closing logger: %v", err) + } + }() } // target expansion - securitytrails discovers new domains before scanning @@ -253,7 +257,7 @@ func (app *App) Run() error { } if app.settings.Ports != "none" { - result, err := scan.Ports(app.settings.Ports, url, app.settings.Timeout, app.settings.Threads, app.settings.LogDir) + result, err := scan.Ports(context.Background(), app.settings.Ports, url, app.settings.Timeout, app.settings.Threads, app.settings.LogDir) if err != nil { log.Errorf("Error while running port scan: %s", err) } else {