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.
- 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?
- 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?
- 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?
- 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?
- Are they using pointers in the best or most intuitive way possible?
- Are they checking pointers correctly everywhere that nil pointer values are possible?
- 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?
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?
- Check for unsafe or reflect package usage. If they’re using it, are the use cases valid? Are they safe?
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.