13 practical tips for writing secure golang applications
TRANSCRIPT
13 Go security tipsKarthik Gaekwad - @iteration1
I’m Karthik @iteration1
I speak docker golang
History of Go• “Go is an open source programming language that makes it
easy to build simple, reliable, and efficient software.”
• Almost 6 years old (November 10th).
• Born after looking at hairy C++ code.
• Current: Go 1.5
• Over 200 companies use go
• ~1200 people @gophercon
• Great for webapps/devops/server mgmt
“Go is awesome”
“Iron.io: How We Went from 30 Servers to 2 with Go”
“Another go at the Next Big Language”
“CloudFlare blows hole in laws of Web physics with Go and
Railgun”
"I have now completed two projects in Go. I predict that it's going to be the dominant language for server work."
Source
“Why I went from Python to Go (and not node.js)”“Why you PHP guys should learn Golang”
"Prediction: Go will become the dominant language for systems work in IaaS, Orchestration, and
PaaS in 24 months."
Pwnage?Does anyone care?
Is there a security policy?https://golang.org/security#tmp_1
Vulnerability List
https://www.cvedetails.com/vendor/14185/Golang.html
Okay, so it’s not all bad news…
Features!
Go is strongly-typed
• The type of every object is known at runtime.
• This cannot be changed.
• Pointers exist, but pointer arithmetic does not.
Memory Managed
• Garbage collector FTW.
• Accessing out of bound indexes in arrays ends with a hard panic.
• Once again, no pointer arithmetic:: can’t create buffer overflows.
Gofmt
• Source code formatter.
• Spend time writing code, not formatting it.
• Integrated with editors (vim/sublimetext/eclipse etc)
• Untweakable!
Gofmt motivation
• Code Reviews
• A Best Practice but….
• “Too much time lost on reviewing formatting rather than code.”
https://talks.go-zh.org/2015/gofmt-en.slide
Other tooling• golint
• Code linter.
• Finds common lint issues or things that don’t belong to a standard.
• Could add this to your CI pipeline, but is volatile.
• go vet
• Looks for weird constructs in your code.
• Examples: Useless assignments, incorrect printf format, unreachable code
• Good list of tools to review: http://dominik.honnef.co/posts/2014/12/an_incomplete_list_of_go_tools/
Standard Packages ftw• Standard libs have pretty good support for most things
you need.
• Don’t have to search for 3rd party libs first…
• All crypto algorithms are in packages under the crypto package.
• crypto.random uses /dev/urandom by default
• good read: https://leanpub.com/gocrypto (Kyle Isom)
Single Binary
• Statically linked, so everything you need is in your binary.
• Helps with product distribution.
• Reduces burden with installation issues on client host.
App Dependencies• Package management:
• Keeps team on the same page.
• Reproducible builds.
• Godep:
• Most popular
• Code is vendorized.
• All your dependencies live inside your application.
• Sorta like (java) ant, but with the source.
Web Application Building• Easy to build your own HTTP/HTTPS server
Web Applications: XSS
• Go Templates- html/template and text/template:
• You want to use html/template for your webapps.
• html/template package escapes all html tags! (template.HTMLEscape or ExecuteTemplate).
• text/template does not!!
Gorilla toolkit
• Awesome toolkit for writing web applications.
• Assists with writing more secure code when you don’t know how to code.
• Gorilla toolkit >>> roll your own
• http://www.gorillatoolkit.org/
Gorilla toolkit• gorilla/securecookie
• Secure cookie: Encodes/Decodes cookie values for you.
• Value is validated with HMAC.
• Add encryption, and content is inaccessible to end user.
• gorilla/sessions
• Simple API for signed (and encrypted) cookies.
• Clean mechanism to rotate session authentication and encryption keys.
• gorilla/mux: Great for routing web apps
• Also gorilla/context, gorilla/websockets and a few others
c’mon man
Secure middleware• https://github.com/unrolled/secure
• Middleware that helps you with some quick security wins.
• + XSS Protection headers
• + CSP headers
• + SSL Check/SSL Redirects
Example: secureMiddleware := secure.New(secure.Options{ AllowedHosts: []string{"example.com", "ssl.example.com"}, SSLRedirect: true, SSLHost: "ssl.example.com", SSLProxyHeaders: map[string]string{"X-Forwarded-Proto": "https"}, STSSeconds: 315360000, STSIncludeSubdomains: true, STSPreload: true, FrameDeny: true, ContentTypeNosniff: true, BrowserXssFilter: true, ContentSecurityPolicy: "default-src 'self'", PublicKey: `pin-sha256="base64+primary=="; pin-sha256="base64+backup=="; max-age=5184000; includeSubdomains; report-uri="https://www.example.com/hpkp-report"`, })
CSRF• nosurf is an HTTP package that helps with
prevention of cross site request forgery.
• https://github.com/justinas/nosurf
nosurf examplevar templateString = ` <!doctype html> <html><body> {{ if .name }} <p>Your name: {{ .name }}</p> {{ end }} <form action="/" method="POST"> <input type="text" name="name"> <!-- Try removing this or changing its value and see what happens --> <input type="hidden" name="csrf_token" value="{{ .token }}"><input type="submit" value="Send"> </form></body></html> `
var templ = template.Must(template.New("t1").Parse(templateString))
func myFunc(w http.ResponseWriter, r *http.Request) { context := make(map[string]string) context["token"] = nosurf.Token(r)
if r.Method == "POST" { context["name"] = r.FormValue("name") }
templ.Execute(w, context) }
func main() { myHandler := http.HandlerFunc(myFunc) fmt.Println("Listening on http://127.0.0.1:8000/") http.ListenAndServe(":8000", nosurf.New(myHandler)) }
SQL Injections• Same as other languages…..
username := r.Form.Get("username") password := r.Form.Get(“password")
// Oh noes!! sql := "SELECT * FROM user WHERE username='" + username + "' AND password='" + password + “'" Db.Exec(sql)
// Oh yes!! sql := "SELECT * FROM user WHERE username=? AND password=?” Db.Exec(sql, username, password)
SQL Injections• Limit DB user permissions so that the impact is minimal.
• Sanitize inputs, escape special characters (‘“\&*;).
• Use the HTMLEscapeString for this.
• Use parameterized queries!
• Code review DB.exec so that you’re using the parameterized query interface.
• Or use Query/Prepare instead.
• Run your code against sqlmap or gauntlt.
Friends who Go!
This could be you
More resources• Austin Golang meetup (@Umbel downtown)
• https://golang.org/doc/
• https://golang.org/doc/code.html
• https://www.digitalocean.com/company/blog/get-your-development-team-started-with-go/
• https://github.com/astaxie/build-web-application-with-golang
• https://speakerdeck.com/ngalbreath/secure-application-development-with-golang
Thanks!