Secure coding in Go and common mistakes
You find and fix the security mistakes common in Go programs in a weak service in your own lab, and stop them returning with tests and analysis.
Level 401 · 19 lessons · 18 practice labs
Lessons
Input and injection
- Untrusted input: limits, types and size
- SQL injection: never build queries with fmt.Sprintf
- Command injection: exec.Command and the shell trap
- Path traversal: filepath.Join is not enough, use os.Root
- XSS in templates: text/template versus html/template
- Short task: close three injection flaws in the weak service
Network and crypto mistakes
- SSRF: making requests to user-supplied addresses
- InsecureSkipVerify and the cost of disabling certificate checks
- Crypto mistakes: math/rand, hard-coded keys, home-made ciphers
- Timing leaks: subtle.ConstantTimeCompare
- Denial of service: unbounded reads, zip bombs, regexes
- Short task: fix token generation and verification
Language-specific traps and tools
- Integer conversions and overflow
- When a race condition becomes a vulnerability
- Leaking error messages and unchecked panics
- Dependency vulnerabilities with govulncheck
- Static security analysis with gosec
- Short task: add a security gate to the test pipeline
Capstone
- Capstone: audit, fix and report on a weak file-sharing service
Practice labs
- Putting limits on untrusted input: Add size, type and range checks to a handler that reads an unbounded body and does not check its page parameter.
- Closing queries built with Sprintf: Fix a report endpoint that splices filter and sort parameters into the query with placeholders and a column allow-list and add a regression test.
- Closing three injections in a weak service: In your own lab service find the three places that run a command through the shell, concatenate a query and print HTML with text/template, fix them and write a test for each.
- Taking a command off the shell: Convert a diagnostic command run with sh -c to exec.Command with separate arguments and validate the host name.
- Blocking directory escape in file download: Fix a download handler that relies on filepath.Join so it uses os.Root and test that parent-directory and symlink attempts are rejected.
- Hardening archive extraction with path and size limits: Harden code that unpacks an uploaded zip so it blocks writes outside the target, excessively inflating content and file-count explosions.
- Moving token generation to crypto/rand: Replace a reset token generated with math/rand by crypto/rand and return it at sufficient length with URL-safe encoding.
- Making token verification constant-time: Compare signatures with subtle.ConstantTimeCompare, take the hard-coded key from the environment and remove the InsecureSkipVerify use.
- Closing SSRF in webhook addresses: In a webhook sender that requests user-supplied addresses, block access to internal networks and loopback, including through redirects, by checking at dial time.
- Preventing truncation in an integer conversion: Add a range check to code that converts a user-supplied 64-bit length to int32 before allocating and reject negative values.
- Cutting details that leak through error messages: Use a generic message and a request id in handlers that return SQL errors and file paths to the client, logging details only and recovering panics.
- Closing a race that becomes a vulnerability: Reduce the check and the mark to one atomic step in code where a coupon can be used twice by concurrent requests so a hundred concurrent attempts yield one success.
- Finding and upgrading a vulnerable dependency with govulncheck: Run govulncheck with the offline vulnerability database, find the vulnerable function that is actually called and upgrade the module to a safe version.
- Limiting unbounded reads and costly patterns: Limit a handler that reads the body without bound with io.ReadAll and compiles a pattern per request, passing the memory and time tests.
- Adding a security gate to the test pipeline: Add gosec and govulncheck to the test script, mark false alarms with justifications, fix the real findings and show the gate breaks on a new finding.
- Triaging static security scan findings: Scan the project with gosec, fix the real findings, annotate false alarms with a reason and show the scan comes out clean.
- Validating the post-login redirect address: Fix a handler that sends users to the address in the next parameter after login so it accepts only same-site relative paths, falling back to the home page for external addresses.
- Fixing encryption that reuses a nonce: Fix token encryption code that uses AES-GCM with a fixed nonce so it generates a random nonce per message, take the key from the environment and show with tests that altered messages are rejected.
About this course
You find and fix the security mistakes common in Go programs in a weak service in your own lab, and stop them returning with tests and analysis.
What you will learn
- Input and injection
- Network and crypto mistakes
- Language-specific traps and tools
- Capstone
Prerequisites
You should have practised the topics of the same path up to level 301.
Lab environment
Lessons run in your own Kali Linux terminal that opens in the browser. Nothing to install; the lab starts clean in every lesson.
Frequently asked questions
- Is this course right for my level?
- The course is at level 401; it assumes you know the topics of the lower-level courses.
- Is there anything to install?
- No. Every lesson runs in your own lab environment that opens in the browser.
- How do lessons work?
- Each lesson has 8 to 10 steps and a short quiz. Early steps show the command to type, later steps give less help; if two attempts fail, the solution opens.
- Can I try it for free?
- Yes. The first three lessons of every course are free.