Skip to content

Latest commit

 

History

History
196 lines (140 loc) · 6.74 KB

CONTRIBUTING.md

File metadata and controls

196 lines (140 loc) · 6.74 KB
layout default
title Contributing

Contributing to subenum

We welcome contributions! Please read this guide to understand how you can contribute.

See the Code of Conduct.

Development Environment Setup

Prerequisites

  • Go 1.26 or later
  • Git
  • Make (optional but recommended)
  • Docker (optional, for containerized development)

The go directive in go.mod must stay exactly go 1.26.0. CI fails the build if it drifts. Current golang.org/x/sys and golang.org/x/text declare go 1.26.0, so it is also the floor. New dependencies must keep it and pass govulncheck, which CI runs. On PowerShell, quote -go=1.26.0; unquoted it is parsed as -go=1. After changing dependencies run make tidy (plain go mod tidy), then confirm the go directive is still go 1.26.0.

The toolchain line is separate: it names the patched Go release that builds from source use (#243). With the default GOTOOLCHAIN=auto, an older local Go downloads that release, so go install and source builds of the action never ship the original 1.26.0 standard library, which has since had security fixes. Raise it to the newest 1.26.x when a Go patch release comes out; it never changes the go 1.26.0 language floor.

Codespaces / Dev Containers

The quickest start needs no local setup. Open the repository in GitHub Codespaces, or use "Reopen in Container" in VS Code. The container in .devcontainer/ comes with the current Go release (1.27; the module supports 1.26 and later) and the CI version of golangci-lint, and builds the binary. make test and ./subenum -simulate example.com then work with no network access to any target.

New here? Look for issues labeled good first issue, and ask questions in Discussions.

Getting Started

  1. Fork the repository on GitHub
  2. Clone your fork:
    git clone https://github.com/YOUR-USERNAME/subenum.git
    cd subenum
  3. Set up the upstream remote:
    git remote add upstream https://github.com/TMHSDigital/subenum.git

Development Workflow

Using Make

The project includes a Makefile to simplify development tasks:

# Build the binary
make build

# Run tests (go test -v ./..., without the race detector; see Testing Requirements)
make test

# Run linter
make lint

# Tidy modules: runs go mod tidy; then confirm the go directive is still go 1.26.0
make tidy

# Clean up build artifacts
make clean

# Run a safe simulated scan (live scans need: make run DOMAIN=yourdomain.com)
make simulate

Using Docker

You can use Docker for development to ensure a consistent environment:

# Build the Docker image
make docker-build

# Simulated scan in a container (no DNS traffic)
make docker-simulate

# Live scan in a container: name a domain you own or may test
make docker-run DOMAIN=yourdomain.com

Pull Request Process

  1. Create a branch for your feature:

    git checkout -b feature/your-feature-name
  2. Make your changes and ensure they follow the project's coding standards

  3. Test your changes with the race detector, as CI does (see Testing Requirements), and lint them:

    go test -race ./...
    make lint

    The race detector needs cgo and a C toolchain. If you have none, run make test locally; CI still runs the suite with -race.

  4. Commit your changes with a clear message describing the change

  5. Push to your fork:

    git push origin feature/your-feature-name
  6. Create a pull request to the main repository

  7. Address any feedback from the code review

Ethical Guidelines

Please ensure that any contributions adhere to the ethical usage principles of this project:

  • Features should be designed for educational or legitimate security testing purposes
  • Consider potential misuse and implement appropriate safeguards
  • Document proper usage scenarios and any necessary warnings

Reporting Bugs

  1. Search existing issues first to avoid duplicates.
  2. Open a new issue using the Bug Report template.
  3. Include:
    • The exact command you ran
    • Your OS, Go version, and subenum version (./subenum -version)
    • Full terminal output (redact any sensitive domain names)
    • Expected vs. actual behaviour

Do NOT include sensitive information, unauthorized scan results, or private domain details.

Suggesting Features

  1. Search existing issues to avoid duplicates.
  2. Open a new issue using the Feature Request template.
  3. Describe:
    • The problem the feature solves
    • Your proposed solution
    • Legitimate security testing use cases it enables

Features that could primarily enable malicious use will be declined.

Simulation Mode for Development

Use -simulate to develop and test without making real DNS queries:

./subenum -simulate -hit-rate 30 -w examples/sample_wordlist.txt example.com

This lets you iterate on output formatting, flag handling, and new features safely.

Testing Requirements

All pull requests must pass the full test suite, including the race detector:

go test -v -race ./...

On Windows, Go 1.26.0 reports false data races (between context.WithTimeout and the net package's DNS lookup goroutine) and can crash with Exception 0xc0000005 in scan.Run; neither is a bug in subenum, and Linux, where CI runs -race, is not affected. You need no workaround: go.mod names toolchain go1.26.11, so a local Go older than that switches to the patched toolchain by itself. The problem only comes back if you force Go 1.26.0 with GOTOOLCHAIN=local.

New features should include tests. New flags must be covered by at least one test case. Do not hit public resolvers. Use -simulate or the in-process DNS server in internal/dnstest, which answers from a per-query handler (records, RCODE, NODATA, delay, drop, truncation) and counts every query per name and type. internal/dns tests can also use the table-driven startTestDNS wrapper in internal/dns/testdns_test.go. The optional live smoke test is gated on SUBENUM_NETWORK_TESTS=1.

Parsers of untrusted input have fuzz targets (grep -rn "^func Fuzz" .): the Wayback answer, lab scenarios, domain and wordlist normalisation, MCP request lines, and zone-transfer and DNSSEC denial messages. go test runs their seed inputs; to fuzz one, name it and its package:

go test -run '^$' -fuzz '^FuzzHostNames$' -fuzztime 1m ./internal/passive/

A failing input is saved under the package's testdata/fuzz/; commit it with the fix so it stays a regression test.