{"id":37096959,"url":"https://github.com/jlauinger/go-geiger","last_synced_at":"2026-01-14T11:55:42.558Z","repository":{"id":57549567,"uuid":"281714431","full_name":"jlauinger/go-geiger","owner":"jlauinger","description":"Static code analysis tool to find unsafe usages in Go packages and their dependencies","archived":false,"fork":false,"pushed_at":"2020-09-11T01:59:15.000Z","size":46,"stargazers_count":40,"open_issues_count":1,"forks_count":4,"subscribers_count":5,"default_branch":"master","last_synced_at":"2024-06-20T03:57:05.033Z","etag":null,"topics":["go","golang","static-analysis","unsafe-code"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/jlauinger.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-07-22T15:27:39.000Z","updated_at":"2024-04-25T02:07:03.000Z","dependencies_parsed_at":"2022-08-27T00:40:42.320Z","dependency_job_id":null,"html_url":"https://github.com/jlauinger/go-geiger","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/jlauinger/go-geiger","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlauinger%2Fgo-geiger","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlauinger%2Fgo-geiger/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlauinger%2Fgo-geiger/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlauinger%2Fgo-geiger/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/jlauinger","download_url":"https://codeload.github.com/jlauinger/go-geiger/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/jlauinger%2Fgo-geiger/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28419272,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-14T10:47:48.104Z","status":"ssl_error","status_checked_at":"2026-01-14T10:46:19.031Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["go","golang","static-analysis","unsafe-code"],"created_at":"2026-01-14T11:55:41.947Z","updated_at":"2026-01-14T11:55:42.540Z","avatar_url":"https://github.com/jlauinger.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# go-geiger\n\n[![build](https://github.com/jlauinger/go-geiger/workflows/build/badge.svg)](https://github.com/jlauinger/go-geiger/actions/)\n\n![go-geiger logo](https://user-images.githubusercontent.com/1872086/88236443-55c25980-cc7d-11ea-9e81-15c28a8e7daa.png)\n\nFind and count `unsafe` usages in Go packages and their dependencies.\n\n\n## Output example\n\n```\ngo-geiger -v github.com/jlauinger/go-geiger\n```\n\n![go-geiger output example](https://user-images.githubusercontent.com/1872086/88232276-dc733880-cc75-11ea-8081-bab01106390b.png)\n\n\n## What is the benefit?\n\nA Go package can avoid the restrictions Go normally sets on pointer use by using `unsafe.Pointer`. This can be valuable\nto improve efficiency or even necessary e.g. to interact with C code or syscalls.\n\nHowever, developers must use extreme caution with `unsafe.Pointer` because mistakes can happen quickly and\n[they can introduce serious vulnerabilities](https://dev.to/jlauinger/exploitation-exercise-with-unsafe-pointer-in-go-information-leak-part-1-1kga)\nsuch as use-after-free, buffer reuses or buffer overflows.\n\nSince usages of `unsafe.Pointer` can be introduced through dependencies (and dependencies of dependencies), it is necessary\nto audit not only the project code but also its dependencies, or at least know who one needs to trust.\n\n`go-geiger` helps developers to quickly identify which packages in the import tree of a Go package use `unsafe.Pointer`, so that developers\ncan focus auditing efforts onto those, or decide to switch libraries for one that does not use `unsafe.Pointer`.\n\n\n## Install\n\nTo install `go-geiger`, use the following command:\n\n```\ngo get github.com/jlauinger/go-geiger\n```\n\nThis will install `go-geiger` to `$GOPATH/bin`, so make sure that it is included in your `$PATH` environment variable.\n\n\n## Usage\n\nRun go-geiger on a package like this:\n\n```\n$ go-geiger example/cmd\n```\n\nOr supply multiple packages, separated by spaces:\n\n```\n$ go-geiger example/cmd example/util strings\n```\n\nTo check the package in the current directory you can call `go-geiger` without parameters:\n\n```\n$ go-geiger\n```\n\nSupplying the `--help` flag prints the usage information for `go-geiger`:\n\n```\n$ go-geiger --help\n```\n\nThere are the following flags available:\n\n```\n      --filter-context string   Count only lines of requested context type (all,variable,parameter,assignment,call,other). Default all (default \"all\")\n      --filter-match string     Count only lines of requested match type (all,pointer,sizeof,offsetof,alignof,sliceheader,stringheader,uintptr). Default pointer (default \"pointer\")\n  -h, --help                    help for geiger\n  -q, --hide-stats              Hide statistics table, print only code. --show-code needs to be set manually\n      --include-std             Show / include Golang stdlib packages\n  -l, --link                    Print link to pkg.go.dev instead of package name\n  -d, --max-depth int           Maximum transitive import depth (default 10)\n      --show-code               Print the code lines with unsafe usage\n      --show-only-once          Do not repeat packages, show them only once and abbreviate further imports (default true)\n  -v, --verbose                 Show usage counts by different usage types\n```\n\n\n## Unsafe Match Types\n\nBy default, `go-geiger` will count only `unsafe.Pointer` usages. By setting the `--filter-match` argument to one of\n`sizeof`, `offsetof`, `alignof`, `sliceheader`, `stringheader`, `uintptr`, or `all`, you can also use `go-geiger` to\nfind usages of `unsafe.Sizeof`, `unsafe.Offsetof`, `unsafe.Alignof`, `reflect.SliceHeader`, `reflect.StringHeader`,\n`uintptr`, or all of them at the same time.\n\n\n## Unsafe Context Types\n\nUsing the `--verbose` argument, you can instruct `go-geiger` to show individual counts for different usage contexts\nof unsafe. `go-geiger` distinguishes between the following:\n\nVariable\n\n```go\nvar x unsafe.Pointer\n```\n\nParameter\n\n```go\nfunc foo(x unsafe.Pointer) {}\n```\n\nAssignment\n\n```go\nx := unsafe.Pointer(\u0026y)\n```\n\nCall\n\n```go\nx := unsafe.Pointer(\u0026y)\nfoo(x)\n```\n\nOther, which includes everything that doesn't fall under the first four.\n\nUse the `--filter-context` argument to filter counting to a specific context type. You can use `variable`, `parameter`,\n`assignment`, `call`, `other`, or `all`.\n\n\n## Dependency management\n\nIf your project uses Go modules and a `go.mod` file, `go-geiger` will fetch all dependencies automatically before it\nanalyzes them. It behaves exactly like `go build` would.\n\nIf you use a different form of dependency management, e.g. manual `go get`, `go mod vendor` or anything else, you need\nto run your dependency management before running `go-geiger` in order to have all dependencies up to date before\nanalysis.\n\n\n## Related work\n\n`go-geiger` is inspired by [Cargo Geiger](https://github.com/rust-secure-code/cargo-geiger), a similar tool to find unsafe\ncode blocks in Rust programs and their dependencies.\n\n[jlauinger/go-unsafepointer-poc](https://github.com/jlauinger/go-unsafepointer-poc) contains proof of concepts for exploiting\nvulnerabilities caused by misuse of `unsafe.Pointer`. I also wrote a [blog post series](https://dev.to/jlauinger/exploitation-exercise-with-unsafe-pointer-in-go-information-leak-part-1-1kga)\non the specific problems and vulnerabilities.\n\n[go-safer](https://github.com/jlauinger/go-safer) is a Go linter tool that can help to identify two common and dangerous usage\npatterns of `unsafe.Pointer`.\n\n\n## Development\n\nTo get the source code and compile the binary, run this:\n\n```\n$ git clone https://github.com/jlauinger/go-geiger\n$ cd go-geiger\n$ go build\n```\n\nRun the tests with `go test`.\n\n\n## License\n\nLicensed under the MIT License (the \"License\"). You may not use this project except in compliance with the License. You\nmay obtain a copy of the License [here](https://opensource.org/licenses/MIT).\n\nCopyright 2020 Johannes Lauinger\n\nThis tool has been developed as part of my Master's thesis at the\n[Software Technology Group](https://www.stg.tu-darmstadt.de/stg/homepage.en.jsp) at TU Darmstadt.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjlauinger%2Fgo-geiger","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjlauinger%2Fgo-geiger","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjlauinger%2Fgo-geiger/lists"}