Writing secure applications in a new language is challenging. Here are some tips to help get you started for writing secure code in golang. Presented at Lascon 2015
3. 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
4. “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."
11. Go is strongly-typed
• The type of every object is known at runtime.
• This cannot be changed.
• Pointers exist, but pointer arithmetic does not.
12. 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.
13. Gofmt
• Source code formatter.
• Spend time writing code, not formatting it.
• Integrated with editors (vim/sublimetext/eclipse etc)
• Untweakable!
14. 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
15. 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/
16. 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)
17. Single Binary
• Statically linked, so everything you need is in your
binary.
• Helps with product distribution.
• Reduces burden with installation issues on client
host.
18. 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.
20. 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!!
21. 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/
22. 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
26. CSRF
• nosurf is an HTTP package that helps with
prevention of cross site request forgery.
• https://github.com/justinas/nosurf
27. nosurf example
var 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))
}
28. 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)
29. 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.