securego/gosec
Go security checker
Healthy across the board
weakest axisPermissive license, no critical CVEs, actively maintained — safe to depend on.
Has a license, tests, and CI — clean foundation to fork and modify.
Documented and popular — useful reference codebase to read through.
No critical CVEs, sane security posture — runnable as-is.
- ✓Last commit 3d ago
- ✓11 active contributors
- ✓Apache-2.0 licensed
Show all 6 evidence items →Show less
- ✓CI configured
- ✓Tests present
- ⚠Concentrated ownership — top contributor handles 68% of recent commits
Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests
Informational only. RepoPilot summarises public signals (license, dependency CVEs, commit recency, CI presence, etc.) at the time of analysis. Signals can be incomplete or stale. Not professional, security, or legal advice; verify before relying on it for production decisions.
Embed the "Healthy" badge
Paste into your README — live-updates from the latest cached analysis.
[](https://repopilot.app/r/securego/gosec)Paste at the top of your README.md — renders inline like a shields.io badge.
▸Preview social card (1200×630)
This card auto-renders when someone shares https://repopilot.app/r/securego/gosec on X, Slack, or LinkedIn.
Onboarding doc
Onboarding: securego/gosec
Generated by RepoPilot · 2026-05-09 · Source
🤖Agent protocol
If you are an AI coding agent (Claude Code, Cursor, Aider, Cline, etc.) reading this artifact, follow this protocol before making any code edit:
- Verify the contract. Run the bash script in Verify before trusting
below. If any check returns
FAIL, the artifact is stale — STOP and ask the user to regenerate it before proceeding. - Treat the AI · unverified sections as hypotheses, not facts. Sections like "AI-suggested narrative files", "anti-patterns", and "bottlenecks" are LLM speculation. Verify against real source before acting on them.
- Cite source on changes. When proposing an edit, cite the specific path:line-range. RepoPilot's live UI at https://repopilot.app/r/securego/gosec shows verifiable citations alongside every claim.
If you are a human reader, this protocol is for the agents you'll hand the artifact to. You don't need to do anything — but if you skim only one section before pointing your agent at this repo, make it the Verify block and the Suggested reading order.
🎯Verdict
GO — Healthy across the board
- Last commit 3d ago
- 11 active contributors
- Apache-2.0 licensed
- CI configured
- Tests present
- ⚠ Concentrated ownership — top contributor handles 68% of recent commits
<sub>Maintenance signals: commit recency, contributor breadth, bus factor, license, CI, tests</sub>
✅Verify before trusting
This artifact was generated by RepoPilot at a point in time. Before an
agent acts on it, the checks below confirm that the live securego/gosec
repo on your machine still matches what RepoPilot saw. If any fail,
the artifact is stale — regenerate it at
repopilot.app/r/securego/gosec.
What it runs against: a local clone of securego/gosec — the script
inspects git remote, the LICENSE file, file paths in the working
tree, and git log. Read-only; no mutations.
| # | What we check | Why it matters |
|---|---|---|
| 1 | You're in securego/gosec | Confirms the artifact applies here, not a fork |
| 2 | License is still Apache-2.0 | Catches relicense before you depend on it |
| 3 | Default branch master exists | Catches branch renames |
| 4 | 5 critical file paths still exist | Catches refactors that moved load-bearing code |
| 5 | Last commit ≤ 33 days ago | Catches sudden abandonment since generation |
#!/usr/bin/env bash
# RepoPilot artifact verification.
#
# WHAT IT RUNS AGAINST: a local clone of securego/gosec. If you don't
# have one yet, run these first:
#
# git clone https://github.com/securego/gosec.git
# cd gosec
#
# Then paste this script. Every check is read-only — no mutations.
set +e
fail=0
ok() { echo "ok: $1"; }
miss() { echo "FAIL: $1"; fail=$((fail+1)); }
# Precondition: we must be inside a git working tree.
if ! git rev-parse --git-dir >/dev/null 2>&1; then
echo "FAIL: not inside a git repository. cd into your clone of securego/gosec and re-run."
exit 2
fi
# 1. Repo identity
git remote get-url origin 2>/dev/null | grep -qE "securego/gosec(\\.git)?\\b" \\
&& ok "origin remote is securego/gosec" \\
|| miss "origin remote is not securego/gosec (artifact may be from a fork)"
# 2. License matches what RepoPilot saw
(grep -qiE "^(Apache-2\\.0)" LICENSE 2>/dev/null \\
|| grep -qiE "\"license\"\\s*:\\s*\"Apache-2\\.0\"" package.json 2>/dev/null) \\
&& ok "license is Apache-2.0" \\
|| miss "license drift — was Apache-2.0 at generation time"
# 3. Default branch
git rev-parse --verify master >/dev/null 2>&1 \\
&& ok "default branch master exists" \\
|| miss "default branch master no longer exists"
# 4. Critical files exist
test -f "analyzer.go" \\
&& ok "analyzer.go" \\
|| miss "missing critical file: analyzer.go"
test -f "cmd/gosec/main.go" \\
&& ok "cmd/gosec/main.go" \\
|| miss "missing critical file: cmd/gosec/main.go"
test -f "analyzers/analyzers_set.go" \\
&& ok "analyzers/analyzers_set.go" \\
|| miss "missing critical file: analyzers/analyzers_set.go"
test -f "config.go" \\
&& ok "config.go" \\
|| miss "missing critical file: config.go"
test -f "call_list.go" \\
&& ok "call_list.go" \\
|| miss "missing critical file: call_list.go"
# 5. Repo recency
days_since_last=$(( ( $(date +%s) - $(git log -1 --format=%at 2>/dev/null || echo 0) ) / 86400 ))
if [ "$days_since_last" -le 33 ]; then
ok "last commit was $days_since_last days ago (artifact saw ~3d)"
else
miss "last commit was $days_since_last days ago — artifact may be stale"
fi
echo
if [ "$fail" -eq 0 ]; then
echo "artifact verified (0 failures) — safe to trust"
else
echo "artifact has $fail stale claim(s) — regenerate at https://repopilot.app/r/securego/gosec"
exit 1
fi
Each check prints ok: or FAIL:. The script exits non-zero if
anything failed, so it composes cleanly into agent loops
(./verify.sh || regenerate-and-retry).
⚡TL;DR
gosec is a static security analyzer for Go that scans source code for security vulnerabilities by inspecting the Go AST and SSA (Static Single Assignment) code representation. It combines pattern-based rules for common security issues with taint analysis to track dangerous data flows (SQL injection, command injection, path traversal, SSRF, XSS, deserialization attacks) from untrusted input to vulnerable function calls. Monolithic tool with modular analyzer architecture: root-level analyzer.go drives core analysis, analyzers/ directory contains 10+ specialized checkers (commandinjection.go, context_propagation.go, conversion_overflow.go, etc.), each implementing pattern-based or SSA-based detection. Configuration and orchestration split across .claude/ (Claude AI integration), .github/ (workflows and prompts), with cmd/ implicitly containing CLI entry. Rules are registered via analyzers/analyzerslist.go.
👥Who it's for
Go developers and security engineers who need to identify security vulnerabilities in Go codebases before deployment. Used by projects that require automated security scanning in CI/CD pipelines via the GitHub Action, and by teams building supply-chain security tooling.
🌱Maturity & risk
Production-ready. The project shows clear maturity: CII Best Practices badge, consistent CI/CD across 4 GitHub workflows (.github/workflows/), comprehensive test suite (analyzer_test.go, analyzers_suite_test.go with both unit and benchmark tests), active maintenance with recent dependency updates (go 1.50.0, tooling 0.44.0), and extensive rule documentation in RULES.md. Last commit data not explicitly shown but dependency freshness indicates ongoing updates.
Low risk, well-maintained. Dependency count is moderate (~25 direct deps) with mostly stable, widely-used libraries (golang.org/x/tools, golang.org/x/crypto, google.golang.org/genai). Single-maintainer concentration unclear from provided data, but CII Best Practices badge and public GitHub workflows suggest distributed governance. Recent addition of LLM integrations (anthropic-sdk-go, openai-go/v3, google.golang.org/genai) may introduce external API dependencies and associated risks.
Active areas of work
Active development of AI-assisted security capabilities: recent additions include .claude/commands/ with prompts for rule creation and bug fixing, integration of Anthropic and OpenAI SDKs in go.mod, and .github/skills/ directories suggesting structured AI agent integration for common tasks (create-gosec-rule, fix-issue, update-action-version). GitHub workflows include action-integration.yml (testing action compatibility) and scan.yml (security scanning).
🚀Get running
Clone and build:
git clone https://github.com/securego/gosec.git
cd gosec
go build -o gosec ./cmd/gosec
./gosec ./...
Or run directly:
go run ./cmd/gosec ./...
For Docker: docker build -t gosec . (Dockerfile present).
Daily commands: Development build and test:
make test # Run test suite
make bench # Run benchmarks (see analyzer_bench_test.go, analyzers/bench_test.go)
make install # Build and install
make fmt # Format code per .golangci.yml
Local analysis:
go run ./cmd/gosec -fmt json ./...
go run ./cmd/gosec -include G101,G102 ./path/to/code
🗺️Map of the codebase
analyzer.go— Core analyzer that orchestrates the entire security scanning pipeline; all contributors must understand how gosec processes Go AST and executes rules.cmd/gosec/main.go— Command-line entry point and driver for the gosec tool; essential for understanding how CLI flags and configuration flow into the analyzer.analyzers/analyzers_set.go— Manages the registry of all security analyzers and rule execution; critical for understanding how individual security checks are registered and dispatched.config.go— Handles configuration parsing and rule enablement/disablement; necessary for understanding how users customize which checks run.call_list.go— Tracks function calls and their arguments for taint analysis; fundamental to understanding how gosec detects injection vulnerabilities.analyzers/tls_resumption_verifypeer.go— Example SSA-based analyzer demonstrating type conversion and crypto security checks; shows the pattern for implementing advanced static analysis rules.RULES.md— Complete documentation of all security rules; required reference for understanding gosec's detection capabilities and rule IDs.
🛠️How to make changes
Add a new pattern-based security rule
- Create a new analyzer file in analyzers/ (e.g., analyzers/new_vulnerability.go) implementing pattern-matching logic using Go AST inspection (
analyzers/new_vulnerability.go) - Register the analyzer in analyzers/analyzerslist.go by adding an entry to the list of available rules with its ID and description (
analyzers/analyzerslist.go) - Add test cases in analyzers/new_vulnerability_test.go following existing test patterns (testcases struct with positive/negative examples) (
analyzers/new_vulnerability_test.go) - Document the new rule in RULES.md with rule ID, title, severity, and example vulnerable code (
RULES.md)
Add a new SSA-based security analyzer
- Create analyzer in analyzers/ using golang.org/x/tools/go/ssa for static single assignment analysis (reference conversion_overflow.go or slice_bounds.go) (
analyzers/conversion_overflow.go) - Implement the analyzer interface and register in analyzers/analyzers_set.go to instantiate your analyzer during rule setup (
analyzers/analyzers_set.go) - Add test cases in _test.go file using testcases with IR code snippets that compile to SSA form (
analyzers/conversion_overflow_test.go)
Add a new taint analysis rule
- Create analyzer using call_list.go to track function calls; identify source (user input) and sink (dangerous function) pairs (
call_list.go) - Implement taint propagation logic in your analyzer to track data flow from sources to sinks (
analyzers/sqlinjection.go) - Register in analyzers/analyzerslist.go and add comprehensive tests covering source→propagation→sink flows (
analyzers/analyzerslist.go) - Document in RULES.md with examples of detectable and non-detectable taint flows (
RULES.md)
Modify CLI output or reporting
- Update cmd/gosec/main.go to add new command-line flags or change result formatting before output (
cmd/gosec/main.go) - Update cmd/gosec/sort_issues.go if changing issue sorting or filtering logic (
cmd/gosec/sort_issues.go) - Add tests in cmd/gosec/main_test.go to verify new CLI behavior (
cmd/gosec/main_test.go)
🔧Why these technologies
- Go AST (golang.org/x/tools) — Enables precise pattern-matching on Go source code syntax; foundation for detecting common injection and configuration vulnerabilities
- SSA form (golang.org/x/tools/go/ssa) — Provides intermediate representation for complex data-flow analysis; enables detection of type conversions, slice bounds, and crypto misuse beyond simple pattern matching
- Taint analysis (call_list.go) — Tracks user input flow through function calls to detect SQL injection, XSS, SSRF, and other injection vulnerabilities at semantic level
- Multiple LLM integrations (OpenAI, Claude, Gemini) — Provides AI-assisted automated fixes for detected vulnerabilities; allows users to choose preferred LLM provider
- TOML/YAML configuration — Human-readable rule enablement and customization; allows teams to enforce consistent security checks across CI/CD
⚖️Trade-offs already made
-
Pattern-based rules in addition to SSA analyzers
- Why: Pattern matching is fast and catches common cases; SSA is slower but more accurate for complex flows
- Consequence: Users get quick feedback on simple issues but may still encounter false positives/negatives; layered approach balances speed and precision
-
Taint analysis uses call-list tracking rather than full constraint-based solver
- Why: Call-list tracking is simpler to implement and understand; full solver would be more powerful but significantly more complex
- Consequence: Some complex data-flow scenarios may be missed; but implementation remains maintainable and rules are auditable
-
No dynamic analysis or runtime instrumentation
- Why: Static analysis is fast, requires no test execution, works in CI without overhead
- Consequence: Cannot detect runtime-only vulnerabilities; false positives on defensive code paths not reached in practice
-
Configuration via separate TOML file rather than annotation directives
- Why: Centralized config is easier to audit and enforce organization-wide policies
- Consequence: Cannot suppress individual issues inline; requires discipline to maintain config file
🚫Non-goals (don't propose these)
- Does not perform dynamic/runtime analysis or code execution
- Does not provide automatic patching without AI integration
- Does not include SAST for languages other than Go
- Does not provide real-time IDE integration (though GitHub Action is available)
- Does not replace security code review or penetration testing
- Does not analyze transitive dependency vulnerabilities (see dependency_checker.go which only checks known advisories)
🪤Traps & gotchas
No explicit environment variable requirements documented in provided files, but LLM integrations (Anthropic, OpenAI, Google Generative AI SDKs in go.mod) suggest API keys may be needed for AI-assisted features if enabled. Benchmark tests (taint_benchmark_baseline.env in .github/benchmarks/) suggest performance testing requires specific baseline environment setup. golang.org/x/tools version must match Go toolchain; mismatches may cause AST/SSA analysis failures. Taint analysis is complex—custom analyzers can introduce false positives if data sources aren't properly declared.
🏗️Architecture
💡Concepts to learn
- Static Single Assignment (SSA) form — gosec converts Go code to SSA representation via golang.org/x/tools to perform advanced dataflow analysis, type conversion detection, and slice bounds checking that pattern matching alone cannot achieve
- Taint analysis — Core capability of gosec: tracks untrusted data (user input, network reads, command-line args) as 'tainted' through variable assignments and function calls to detect when tainted values reach dangerous functions like sql.Query or os.Exec
- Abstract Syntax Tree (AST) — gosec parses Go source files into AST representation using golang.org/x/tools to match patterns against code structure; AST walking is the foundation for pattern-based rules like G101 (weak crypto)
- Data flow analysis — Beyond SSA, gosec implements custom dataflow tracking to follow values through assignments, function parameters, and return values; critical for detecting context propagation violations and SSRF vulnerabilities
- False positive filtering — gosec supports rule suppression via code comments (#nosec) and configuration files to reduce noise from legitimate security-safe patterns; essential for CI/CD integration without alert fatigue
- G-codes (rule identifiers) — gosec assigns fixed identifiers (G101 weak crypto, G102 SQL injection, G103 unsafe, etc.) to enable precise rule selection, exclusion, and traceability across organizations
- Type conversion analysis — SSA-based analyzers in gosec detect unsafe type conversions (e.g., int to uint that can overflow) and slice bounds violations by inspecting operation semantics, not just patterns
🔗Related repos
golangci/golangci-lint— Alternative Go linter that includes gosec as one of many analyzers; integrates gosec rules into a unified linting frameworkgolang/go— Upstream Go language repository; gosec depends on golang.org/x/tools (sibling module) for AST/SSA infrastructuredominikh/go-tools— Complementary Go static analysis tool (staticcheck) that gosec runs alongside for comprehensive code quality and security checksfyne-io/fyne— Example large Go project that uses gosec in CI/CD for security scanning; demonstrates real-world gosec integration patternsaquasecurity/trivy— Container and dependency vulnerability scanner that complements gosec; used together for supply-chain security (SBOM, CVE detection vs. source code patterns)
🪄PR ideas
To work on one of these in Claude Code or Cursor, paste:
Implement the "<title>" PR idea from CLAUDE.md, working through the checklist as the task list.
Add comprehensive test coverage for new taint analysis analyzers (SSRF, XSS, unsafe deserialization)
The repo has several advanced taint-tracking analyzers (ssrf.go, ssti.go, loginjection.go, smtpinjection.go) but the file structure shows no corresponding *_test.go files for most of them. This is critical for security tooling where false negatives are dangerous. Adding test suites with positive/negative test cases would improve reliability and make it easier for contributors to understand taint analysis patterns.
- [ ] Create analyzers/ssrf_test.go with test cases covering: basic SSRF patterns, nested function calls, variable aliasing, and false positives
- [ ] Create analyzers/ssti_test.go with template injection scenarios across different template engines
- [ ] Create analyzers/loginjection_test.go with log statement taint propagation test cases
- [ ] Follow existing test patterns from analyzers/conversion_overflow_test.go and analyzers/slice_bounds_test.go
- [ ] Ensure each test file covers both positive detections and intentional false positive scenarios
Implement GitHub Actions workflow for testing gosec against real-world Go packages
The .github/workflows directory has ci.yml, release.yml, and scan.yml, but there's no dedicated workflow for validating gosec's detection accuracy against public Go repositories (like popular libraries with known vulnerabilities). This would serve as a regression test and help catch when rule changes inadvertently miss security issues in real code.
- [ ] Create .github/workflows/accuracy-validation.yml that clones 5-10 popular Go repos with known security issues
- [ ] Configure workflow to run gosec against these repos and verify expected rules fire (cross-reference RULES.md)
- [ ] Store baseline results in .github/benchmarks/accuracy_baseline.json (similar to taint_benchmark_baseline.env)
- [ ] Add workflow dispatch trigger to allow manual validation runs
- [ ] Document process in DEVELOPMENT.md for updating baseline when rules intentionally change
Add integration tests for dependency_checker analyzer with real go.mod scenarios
The analyzers/dependency_checker.go file exists but there's no analyzers/dependency_checker_internal_test.go (only *_test.go is missing the 'internal' variant in the file list). Since dependency checking involves parsing go.mod files and comparing against vulnerability databases, this needs robust test coverage for edge cases like version ranges, indirect dependencies, and missing databases.
- [ ] Create analyzers/dependency_checker_test.go with test fixtures in a test_data/ subdirectory containing various go.mod scenarios
- [ ] Add test cases for: vulnerable direct dependencies, vulnerable transitive dependencies, version constraints that should/shouldn't trigger, missing vulnerability database handling
- [ ] Test integration with the Mozilla TLS Observatory (github.com/mozilla/tls-observatory in go.mod) for realistic data source scenarios
- [ ] Add benchmarking test (similar to analyzers/bench_test.go pattern) for performance with large dependency graphs
- [ ] Document test data structure in DEVELOPMENT.md
🌿Good first issues
- Add missing test coverage for analyzers/context_propagation.go and analyzers/conversion_overflow.go (visible from limited test file references)—write unit tests following the pattern in existing analyzer_test.go to improve coverage metrics
- Create a new analyzer for detecting unsafe use of crypto/rand (G601 or next available code) by studying existing analyzers/commandinjection.go structure and adding pattern-based detection for insecure PRNG usage with corresponding tests
- Document taint sources and sinks with concrete code examples in RULES.md for SQL injection, command injection, and path traversal categories—add missing remediation guidance snippets for each rule class based on OWASP best practices
⭐Top contributors
Click to expand
Top contributors
- @ccojocar — 68 commits
- @renovate[bot] — 12 commits
- @ravisastryk — 11 commits
- @dependabot[bot] — 2 commits
- @scop — 1 commits
📝Recent commits
Click to expand
Recent commits
b4f2934— Harden the github workflows and action (#1665) (ccojocar)b7aca26— Fix justification delimiter in annotation format doc (#1661) (scop)945bce7— Update all dependencies (#1664) (renovate[bot])5f4eec9— Update action to use gosec version v2.26.1 (#1660) (ccojocar)4a3bd8a— Update cosign to v3.0.6 (#1659) (ccojocar)553d8a5— Sync taint rule docs and add missing CWE mappings for G113/G307 (#1658) (ravisastryk)bf0ccd3— Update all dependencies (#1657) (renovate[bot])4ead098— Add G710 rule for open redirect via taint analysis (#1654) (ravisastryk)8ff985f— Fix formatting (ccojocar)a1aad0c— Update the default models use by autofix and phase out the older models (ccojocar)
🔒Security observations
The gosec project demonstrates strong security posture as a security scanning tool. The codebase includes comprehensive analyzers for various injection vulnerabilities, taint analysis, and SSA-based security checks. However, minor improvements are recommended in Docker image hardening (remove unnecessary packages/users running as root), dependency version management, and ensuring benchmark configuration files don't contain sensitive data. No critical vulnerabilities were identified in the visible portions of the codebase. The project should regularly run 'govulncheck' to scan transitive dependencies for known vulnerabilities.
- Medium · Outdated TLS Observatory Dependency —
go.mod - github.com/mozilla/tls-observatory v0.0.0-20250923143331-eef96233227e. The dependency 'github.com/mozilla/tls-observatory' is pinned to a very recent version (2025-09-23) which may not have undergone sufficient security review. Additionally, this dependency appears to be for TLS scanning purposes, but the latest stable version should be verified for known vulnerabilities. Fix: Verify the stability and security of the tls-observatory dependency. Consider using official released versions instead of development snapshots. Run 'go list -u -m all' to check for updates and 'govulncheck ./...' to scan for known vulnerabilities. - Low · Potential Secrets in Benchmark Configuration —
.github/benchmarks/taint_benchmark_baseline.env. The file '.github/benchmarks/taint_benchmark_baseline.env' suggests environment variable configuration that could potentially contain sensitive data if not properly managed. Environment files should never be committed with actual secrets. Fix: Ensure this .env file only contains non-sensitive benchmark configuration values. Add .env files to .gitignore. Use GitHub Secrets for any sensitive configuration needed in workflows. - Low · Broad Alpine Package Permissions in Dockerfile —
Dockerfile - lines with 'apk add --no-cache ca-certificates bash git gcc libc-dev openssh'. The Dockerfile installs packages like 'gcc' and 'libc-dev' in the final runtime image (not just builder stage), which increases the attack surface. These are typically only needed at build time. Fix: Move gcc and libc-dev installation to the builder stage only if they're not needed at runtime. Keep the final image minimal with only essential runtime dependencies (ca-certificates, bash, git, openssh if truly needed). - Low · SSH Included in Container Runtime —
Dockerfile - openssh package in final image. OpenSSH is included in the runtime Docker image without clear justification. This expands the container's attack surface and potential vulnerability exposure. Fix: Evaluate if openssh is truly necessary in the runtime container. If not, remove it. If required, ensure SSH is properly configured with strong authentication, disabled root login, and restricted access. - Low · Missing HEALTHCHECK Directive —
Dockerfile - missing HEALTHCHECK. The Dockerfile lacks a HEALTHCHECK instruction, which prevents orchestration systems from detecting unhealthy container instances. Fix: Add a HEALTHCHECK directive to verify gosec functionality. Example: 'HEALTHCHECK CMD gosec --version || exit 1' - Low · No Non-Root User in Dockerfile —
Dockerfile - missing USER directive. The Dockerfile does not explicitly create or switch to a non-root user, meaning the entrypoint.sh script runs as root. This violates the principle of least privilege. Fix: Create a non-root user and switch to it before the ENTRYPOINT. Example: 'RUN addgroup -g 1000 gosec && adduser -u 1000 -G gosec gosec' followed by 'USER gosec'
LLM-derived; treat as a starting point, not a security audit.
👉Where to read next
- Open issues — current backlog
- Recent PRs — what's actively shipping
- Source on GitHub
Generated by RepoPilot. Verdict based on maintenance signals — see the live page for receipts. Re-run on a new commit to refresh.