diff --git a/VERSION b/VERSION index 6e8bf73..b1e80bb 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -0.1.0 +0.1.3 diff --git a/api_security.go b/api_security.go index 65a87e7..851a7e7 100644 --- a/api_security.go +++ b/api_security.go @@ -74,7 +74,7 @@ func (a *APISecurityChecker) CheckCORS(url string) []Finding { if err != nil { continue } - resp.Body.Close() + _ = resp.Body.Close() acao := resp.Header.Get("Access-Control-Allow-Origin") acac := resp.Header.Get("Access-Control-Allow-Credentials") @@ -140,7 +140,7 @@ func (a *APISecurityChecker) CheckRateLimiting(url string) []Finding { if err != nil { continue } - resp.Body.Close() + _ = resp.Body.Close() if resp.StatusCode == http.StatusTooManyRequests { rateLimitHeaderFound = true @@ -188,7 +188,7 @@ func (a *APISecurityChecker) CheckAuthHeaders(url string) []Finding { if err != nil { return findings } - resp.Body.Close() + _ = resp.Body.Close() requiredHeaders := []struct { Name string @@ -256,7 +256,7 @@ func (a *APISecurityChecker) CheckVerbTampering(url string) []Finding { continue } body, _ := io.ReadAll(io.LimitReader(resp.Body, 1024)) - resp.Body.Close() + _ = resp.Body.Close() // TRACE is especially dangerous if it echoes back the request if m.Method == "TRACE" && resp.StatusCode == http.StatusOK { @@ -289,7 +289,7 @@ func (a *APISecurityChecker) CheckVerbTampering(url string) []Finding { if err == nil { resp, err := client.Do(req) if err == nil { - resp.Body.Close() + _ = resp.Body.Close() allow := resp.Header.Get("Allow") if allow == "" { allow = resp.Header.Get("Access-Control-Allow-Methods") @@ -370,7 +370,7 @@ func (a *APISecurityChecker) CheckErrorLeakage(url string) []Finding { continue } body, _ := io.ReadAll(io.LimitReader(resp.Body, 4096)) - resp.Body.Close() + _ = resp.Body.Close() bodyStr := string(body) diff --git a/config.go b/config.go index e42fb96..ded3e30 100644 --- a/config.go +++ b/config.go @@ -44,7 +44,7 @@ func loadConfigFile(dir string) (*FileConfig, error) { return nil, nil } - data, err := os.ReadFile(path) + data, err := os.ReadFile(path) // #nosec G304 -- path comes from findInspectConfigFile(dir), which searches for .inspect.toml/.inspect.yaml in the target project directory or its parents, not attacker-controlled input if err != nil { return nil, err } diff --git a/dependency_check.go b/dependency_check.go index e694cf5..53bdea7 100644 --- a/dependency_check.go +++ b/dependency_check.go @@ -136,7 +136,7 @@ var KnownVulnerabilities = map[string][]VulnEntry{ func (d *DependencyChecker) ScanGoMod(path string) []Finding { var findings []Finding - file, err := os.Open(path) + file, err := os.Open(path) // #nosec G304 -- path is the go.mod location supplied to this dependency checker (a project file to be scanned for vulnerable packages), not attacker-controlled input if err != nil { findings = append(findings, Finding{ Check: "dependency-gomod", @@ -190,7 +190,7 @@ func (d *DependencyChecker) ScanGoMod(path string) []Finding { func (d *DependencyChecker) ScanPackageJSON(path string) []Finding { var findings []Finding - data, err := os.ReadFile(path) + data, err := os.ReadFile(path) // #nosec G304 -- path is the package.json location supplied to this dependency checker (a project file to be scanned for vulnerable packages), not attacker-controlled input if err != nil { findings = append(findings, Finding{ Check: "dependency-npm", @@ -238,7 +238,7 @@ func (d *DependencyChecker) ScanPackageJSON(path string) []Finding { func (d *DependencyChecker) ScanRequirements(path string) []Finding { var findings []Finding - file, err := os.Open(path) + file, err := os.Open(path) // #nosec G304 -- path is the requirements.txt location supplied to this dependency checker (a project file to be scanned for vulnerable packages), not attacker-controlled input if err != nil { findings = append(findings, Finding{ Check: "dependency-python", diff --git a/internal/check/links.go b/internal/check/links.go index 9fbcb8d..9d4b6a7 100644 --- a/internal/check/links.go +++ b/internal/check/links.go @@ -241,8 +241,8 @@ func (l *LinksCheck) checkExternalLinkWithDetector(ctx context.Context, pageURL, getResp, err := client.Do(getReq) if err == nil { // Read at most 1 byte -- we only need the status code. - io.CopyN(io.Discard, getResp.Body, 1) - getResp.Body.Close() + _, _ = io.CopyN(io.Discard, getResp.Body, 1) + _ = getResp.Body.Close() // Use the GET response status instead. if l.isAcceptedStatus(getResp.StatusCode) { return nil diff --git a/internal/check/reachability.go b/internal/check/reachability.go index a5fa583..a6a9cf4 100644 --- a/internal/check/reachability.go +++ b/internal/check/reachability.go @@ -126,8 +126,8 @@ func checkResourceReachable(ctx context.Context, client *http.Client, ref resour getReq.Header.Set("User-Agent", "inspect/1.0 (reachability check)") getResp, err := client.Do(getReq) if err == nil { - io.CopyN(io.Discard, getResp.Body, 1) - getResp.Body.Close() + _, _ = io.CopyN(io.Discard, getResp.Body, 1) + _ = getResp.Body.Close() if getResp.StatusCode >= 200 && getResp.StatusCode < 400 { return nil } diff --git a/internal/check/soft404.go b/internal/check/soft404.go index dd80579..5f7e054 100644 --- a/internal/check/soft404.go +++ b/internal/check/soft404.go @@ -176,7 +176,7 @@ func (d *Soft404Detector) Detect(ctx context.Context, client *http.Client, page return false, nil } probeBody, err := io.ReadAll(io.LimitReader(probeResp.Body, 1*1024*1024)) - probeResp.Body.Close() + _ = probeResp.Body.Close() if err != nil { return false, nil } @@ -213,7 +213,7 @@ func (d *Soft404Detector) Detect(ctx context.Context, client *http.Client, page return false, nil } pageBody, err := io.ReadAll(io.LimitReader(pageResp.Body, 1*1024*1024)) - pageResp.Body.Close() + _ = pageResp.Body.Close() if err != nil { return false, nil } diff --git a/internal/crawler/crawler.go b/internal/crawler/crawler.go index 1455d76..2994172 100644 --- a/internal/crawler/crawler.go +++ b/internal/crawler/crawler.go @@ -454,7 +454,7 @@ func (c *Crawler) doFetch(ctx context.Context, page *Page, targetURL string) err // Handle auth-required responses as findings rather than errors if resp.StatusCode == 401 || resp.StatusCode == 403 { - resp.Body.Close() + _ = resp.Body.Close() page.StatusCode = resp.StatusCode page.Headers = resp.Header page.Error = nil @@ -464,7 +464,7 @@ func (c *Crawler) doFetch(ctx context.Context, page *Page, targetURL string) err // Handle redirects manually if resp.StatusCode >= 300 && resp.StatusCode < 400 { - resp.Body.Close() + _ = resp.Body.Close() loc := resp.Header.Get("Location") if loc == "" { page.StatusCode = resp.StatusCode @@ -493,12 +493,12 @@ func (c *Crawler) doFetch(ctx context.Context, page *Page, targetURL string) err contentType := resp.Header.Get("Content-Type") if !strings.Contains(contentType, "text/html") { - resp.Body.Close() + _ = resp.Body.Close() return nil } body, err := io.ReadAll(io.LimitReader(resp.Body, 10*1024*1024)) - resp.Body.Close() + _ = resp.Body.Close() if err != nil { page.Error = err return err diff --git a/sbom.go b/sbom.go index bbb2436..3ebcfa4 100644 --- a/sbom.go +++ b/sbom.go @@ -101,7 +101,7 @@ func GenerateSBOMJSON(projectDir string, version string) (string, error) { func scanGoModForSBOM(path string) []SBOMComponent { var components []SBOMComponent - file, err := os.Open(path) + file, err := os.Open(path) // #nosec G304 -- path is filepath.Join(projectDir, "go.mod") computed by GenerateSBOM against the project directory being scanned, not attacker-controlled input if err != nil { return nil } @@ -160,7 +160,7 @@ func goModLineToComponent(line string) *SBOMComponent { func scanPackageJSONForSBOM(path string) []SBOMComponent { var components []SBOMComponent - data, err := os.ReadFile(path) + data, err := os.ReadFile(path) // #nosec G304 -- path is filepath.Join(projectDir, "package.json") computed by GenerateSBOM against the project directory being scanned, not attacker-controlled input if err != nil { return nil } @@ -203,7 +203,7 @@ func scanPackageJSONForSBOM(path string) []SBOMComponent { func scanRequirementsForSBOM(path string) []SBOMComponent { var components []SBOMComponent - file, err := os.Open(path) + file, err := os.Open(path) // #nosec G304 -- path is filepath.Join(projectDir, "requirements.txt") computed by GenerateSBOM against the project directory being scanned, not attacker-controlled input if err != nil { return nil } diff --git a/symbol_search.go b/symbol_search.go index d64bf04..c1aa06d 100644 --- a/symbol_search.go +++ b/symbol_search.go @@ -251,7 +251,7 @@ func extractSymbolName(m []string, kind, ext string) string { } func readLines(path string) ([]string, error) { - f, err := os.Open(path) + f, err := os.Open(path) // #nosec G304 -- path is the source file under analysis, supplied by the scanning tool's own localization phase/CLI target; reading arbitrary project files is this tool's purpose if err != nil { return nil, err } diff --git a/template.go b/template.go index 484369d..5b2f384 100644 --- a/template.go +++ b/template.go @@ -105,7 +105,7 @@ func ParseTemplates(data []byte) ([]RuleCheck, error) { // LoadTemplateFile reads and parses a single YAML template file. func LoadTemplateFile(path string) ([]RuleCheck, error) { - data, err := os.ReadFile(path) + data, err := os.ReadFile(path) // #nosec G304 -- path is a caller-supplied template file location (this tool's own declarative check templates), not attacker-controlled input if err != nil { return nil, fmt.Errorf("inspect: read template %s: %w", path, err) }