httperroryzer: static analysis pass to catch missing returns after http.Error for Go
TL;DR: at Orijtech, Inc., we’ve developed and open sourced a first of its kind static analyzer, “httperroryzer”, that examines your Go code with HTTP handlers, and reports missing return statements after http.Error, which could cause security vulnerabilities, malfunctions, nil pointer dereferences/crashes, and all other sorts of embarassments. httperroryzer’s nemesis is reminiscent of the goto fail; our tools can help solve these problems!
The Go programming language is the undisputed language of the cloud, with more than 25% of the Fortune 100 using it in production at companies like Walmart, Amazon, Apple, Google/Alphabet, Microsoft, American Express, JP Morgan Chase, Netflix, Paypal etc, majority of the popular and most used cloud computing projects like Kubernetes, Istio, OpenCensus/OpenTelemetry agent, written in Go. The blog and the pipeline serving this post probably uses Go too.
Motivation:
Amongst the many benefits of using Go, one of the most praised parts of Go is its all batteries included HTTP standard libray “net/http”. The Go standard library is powerful, concise and used in production at very many companies. This webpage might even have been served by Go’s net/http package as you read it!
To write an HTTP handler in Go, let’s take a look at the guide at https://golang.org/pkg/net/http/#HandleFunc where the signature is
The body of the HTTP handler will contain the business logic to serve a request. Notice that it doesn’t return any values. Any errors or responses will be performed on the http.ResponseWriter
and use a helper http.Error
and this is the signature of http.ResponseWriter
Here is a sample HTTP handler as per the examples
Adapting this code to your company
Let for example someone from our company ACME Corp start modifying this code to make it privileged with a secret key say in the HTTP header, to send back a secret location
That code gets examined by your colleagues in a code review, it looks simple and very similar to the example code, no one questions why line 4 and line 6 don’t have an exclusive-or execution, thinking that http.Error is sufficient. You write tests for it, toensure that it returns a 401 on an invalid request and contains the substring indicating an error
Code review passes alright, CI/CD pass, teams exchange virtual high-fives #COVID19WuzHere and start celebrating that they’ve rolled out a functional endpoint for giving access to secret coordinates.
Aftermath
This endpoint is announced to customers, deploy into production and everyone goes home looking forward to the weekend! Later, the team notices the spike in load, the internet is posting about logging into your application without any password, let’s see what we get back when we make a request to the API
The server tries to kick them out as unauthorized, but then also sends the secret location :( :( Ouch!!!
Similar fatalities:
Static analysis helps catch such problems in which code takes unconditional and unexpected paths than the coders intended. The most prominent and similar bug was exhibited in this blogpost are similar to the critical vulnerability “Apple goto fail” which Adam Langley describes here https://www.imperialviolet.org/2014/02/22/applebug.html in which a mistaken paste of goto fail
caused unconditionally going to return a nil error regardless of the SHA1 value of a certificate.
Where do we go from here?
You hear about httperroryzerr and decide to try it out… Let’s install httperroryzer and see what happens
Boom, we have the fix, and let’s make it now
We deploy the fix, and then pentest again or with a fuzz pass
and it is now working alright
The test was subtly flawed too, it needs to be more rigorous!!
Conclusion:
At Orijtech, Inc. we work on a wide range of technology but firstly focusing on improving the state of technology for the Go programming language project, and we’ll contribute it upstream to the Go project. We’ve released it at https://github.com/orijtech/httperroryzer
You can get this pass today by doing go get github.com/orijtech/httperroryzer/cmd/httperroryzer
and run it in your projects. Please share it with your friends, provide feedback, report bugs and enjoy!
Thank you for reading this far.
Kind regards,
Engineering Department @ Orijtech, Inc.