Golang Audit Checklist

Cover photo credit to https://michenriksen.com/blog/gitrob-now-in-go/
These are broad questions I ask and points I check from a security-oriented perspective on each Golang project that I audit.
Static analysis⌗
- Run code through gosec check
- Run golangci-lint against code
- Run Docker security checks
Linters and style⌗
- Are they using a linter?
- Are they using a style guide, and if they are, are they following it?
- Are they using pointers in places where they shouldn’t be?
- Are they checking nil interfaces correctly? Nil interface checks can be weird.
- Sanity check package names and structuring - are there any obvious weird clashing or separation of concerns?
Dependencies and package management⌗
- Are they relying on external libraries? Which ones and why?
- What’s their dependency situation?
- Are they using any dependencies they don’t need?
- Are there dependencies we consider risky or unnecessary that could be removed?
- Do they have their dependencies pinned?
- Have they conducted prior audits of their dependencies?
Tests and test coverage⌗
- What’s the test situation like?
- Are they testing the things they need to be testing?
- Run the entire test suite multiple times to check for flakey tests.
- Do they have a single easy command for testing?
- Do their tests sufficiently test core business logic?
- Do their tests need a large amount of setup?
- Are their tests isolated and specific?
- What is the nature of their entire test suite?
Fuzz testing⌗
- Have they done any fuzz testing themselves?
- Do they want fuzz testing?
- If they do have fuzz testing, are they using an established corpus?
- Are they implementing the latest in genetic mutation algorithm input generation?
- Are they scaling and parallelizing their fuzz tests?
Comments⌗
- What’s the commenting situation like?
- Are they the right kind of comments?
- Is the team in a clear habit of commenting code?
- Do the comments explain why decisions were made rather than just what the code is doing?
- Do the comments explain what each module does at a higher level and what it’s main responsibilities are?
Encryption⌗
- If so, what are they using and how are they using it?
- Are they keeping sensitive data?
- If so, how are they storing it? How are they accessing it?
- What’s their documentation like? Minimal? Reasonable? Substantial? Absolutely thorough?
- Are they violating the cryptographic principle of doom anywhere?
- Are they using encryption?
- Are they vulnerable to side-channel or timing attacks because of non-constant comparison?
Pointers⌗
- Are they using pointers in the best or most intuitive way possible?
- Are they checking pointers correctly everywhere that nil pointer values are possible?
Contexts⌗
- Are context cancellations being handled at termination points?
- Are they using contexts?
- Are they using deadlines or timeouts where appropriate?
- Are there any places where contexts aren’t being handled?
Modules⌗
It’s easiest to approach each project as a set of modules that we examine individually. Often times, interactions between internal modules is where we find exploits and security issues.
- Does this module do one thing and one thing well?
- Does this module care about things it doesn’t need to care about?
- Does this module have access to information it doesn’t strictly need?
- What does this module do?
Miscellaneous⌗
- Check for unsafe or reflect package usage. If they’re using it, are the use cases valid? Are they safe?
Conclusion⌗
These are not meant to be taken as must haves, but more as sanity checks and qualitative answers that an audit should cover.
For example, I don’t think that every projects needs a style guide, but if it’s a community-heavy project with lots of open source contributions, and the main repository lacks a style guide, then I would probably consider adding it as a recommendation in our final report. Context matters most, so it’s a point in my checklist to consider.
As with everything, take this with an ounce of salt and read everything yourself.
Documentation is divine.