Skip to content

Gys/cmdscanner

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

16 Commits
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

cmdscanner - Go Module Dependency Scanner

A command-line tool that parses Go module files (go.mod) and scans all dependencies for command pattern usage. It identifies and extracts code lines containing specific command patterns like .Command(, .RunCommand(, and .Cmd(.

Why

Bad actors copy popular GitHub projects, add faked stars for credibility and then injected malicious code at runtime. Attackers obfuscate their code but a common pattern is executing the command in the shell. This tool hopefully helps identify unexpected shell access from dependencies of a Golang project.

A typical use case is to run this tool on a project directly after adding a new dependency.

See this discussion on Reddit: Someone copied our GitHub project, made it look more trustworthy by adding stars from many fake users, and then injected malicious code at runtime for potential users.

Features

  • Parse go.mod files to extract module information
  • Scan all Go files in dependencies for specific command patterns:
    • .Command(
    • .RunCommand(
    • .Cmd(
  • Extract and display the actual lines of code containing these patterns
  • Handle replace directives
  • Skip test files (*_test.go) to focus on implementation code
  • Optionally skip official Go packages (golang.org/*)
  • Optionally skip user-specified packages
  • Optionally no color output

Installation

# Clone the repository
git clone https://github.com/Gys/cmdscanner
cd cmdscanner

# Build the application
go build -o cmdscanner

Usage

# Scan the first found go.mod file in the current directory or parent directories
./cmdscanner

# Scan a specific go.mod file
./cmdscanner -file /path/to/go.mod

# Also include official Go packages (*.golang.org/*)
./cmdscanner -include-go-official

# Skip specific packages (comma-separated list)
./cmdscanner -skip github.com/modernc.org/libc,github.com/pkg/errors

# By default color output is enabled
./cmdscanner -no-color

Example Output

Module: github.com/example/myproject
Go version: 1.20
Module cache location: /home/user/go/pkg/mod
Searching for command patterns: .Command(, .RunCommand(, .Cmd(
Skipping test files (*_test.go)
Skipping official Go packages (golang.org/*)
Skipping user-specified packages: github.com/pkg/errors

Summary:

/home/user/go/pkg/mod/github.com/spf13/[email protected]/command.go:142
rootCmd.Command("version", "Print the version number")

/home/user/go/pkg/mod/github.com/spf13/[email protected]/command.go:157
cmd := &Command{Use: "app"}

/home/user/go/pkg/mod/github.com/spf13/[email protected]/cobra.go:120
c := root.Cmd("status", "Show status")

Technical Notes

Source

95% of this code and the README.md are generated by Claude 3.7 Sonnet, using Cody in VS Code.

Command Pattern Detection

The tool looks for these command patterns:

  • .Command(
  • .RunCommand(
  • .Cmd(

Test File Exclusion

The tool skips all files ending with _test.go to focus on implementation code.

Go Official Package Inclusion

With the -include-go-official flag, the tool will include scanning packages from the Go project itself (those with paths starting with golang.org/).

Package Skipping

Use the -skip flag to specify a comma-separated list of packages to skip during scanning.

Colored output

By default the code lines are colored yellow. Use the -no-color flag to disble.

Go Module Cache

Go stores downloaded packages in a central module cache. The location of this cache is determined by:

  1. The GOMODCACHE environment variable (Go 1.14+)
  2. Fallback: $GOPATH/pkg/mod (older Go versions)

You can find your module cache location by running:

go env GOMODCACHE

Module Path Encoding

Module paths in the filesystem are encoded to handle special characters:

  • Uppercase letters are converted to '!' followed by the lowercase letter
  • The '!' character is converted to '!!'
  • Other special characters may also be encoded

The tool handles this encoding automatically using Go's module.EscapePath function.

Version Handling

Module versions in the filesystem may have special suffixes:

  • +incompatible suffix for modules that don't follow semantic versioning
  • Pseudo-versions like v0.0.0-20230822171919-f59e071c2a15

The tool handles these special cases when determining installation paths.

Replace Directives

Replace directives in go.mod files can point to:

  1. Another module version (stored in the module cache)
  2. A local filesystem path (not in the module cache)

The tool distinguishes between these cases and shows the appropriate location.

File Scanning

The tool recursively scans all .go files in each dependency's directory:

  • It skips directories like .git, testdata, and vendor
  • It skips test files (*_test.go)
  • It optionally includes official Go packages (golang.org/*)
  • It searches for the specified command patterns in each Go file
  • It extracts and displays the actual lines of code containing these patterns
  • It provides a detailed summary of all matching files and code lines at the end
  • It groups and counts occurrences by pattern type

Extending the Command Patterns

To add more command patterns to search for, modify the CommandPatterns slice in the code:

var CommandPatterns = []string{
    `.Command(`,
    `.RunCommand(`,
    `.Cmd(`,
    // Add more patterns here
    `.NewCommand(`,
    `.AddCommand(`,
}

Vendoring

If your project uses vendoring (go mod vendor), dependencies are also copied to the vendor directory in your project. This tool focuses on the module cache, not vendored dependencies.

Proxy Settings

Go may use a proxy for downloading modules (controlled by the GOPROXY environment variable). This doesn't affect where packages are stored locally, but it affects how they're downloaded.

Sum Database

Go maintains a checksum database (go.sum file) to verify the integrity of modules. This is separate from the actual module storage.

License

MIT License

About

Scans for shell access in any used pkg

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages