| |
@@ -108,3 +108,154 @@
|
| |
suitable default values if necessary) ensures that data from a
|
| |
previous deserialization operation does not leak into the current
|
| |
one. This is especially relevant when structs are deserialized.
|
| |
+
|
| |
+
|
| |
+ [[chap-Defensive_Coding-Go-Marshaling]]
|
| |
+ == Good Practices for Securing Go - High Level Overview
|
| |
+
|
| |
+ Secure coding is the practice of writing programs that are resistant to attack by malicious or mischievous people or programs.
|
| |
+
|
| |
+ Golang’s adoption has been increasing over the years. Projects within Red Hat like https://cloud.redhat.com/learn/topics/operators/[*Operators*] and https://www.terraform.io/[*Terraform*] have been completed in this programming language.
|
| |
+
|
| |
+
|
| |
+ === 1. Use Go Modules
|
| |
+ Modules are how Go manages dependencies. https://go.dev/ref/mod/[*Go Modules*] allow for dependency version pinning, including transitive modules, and also provides assurance against unexpected module mutation via the go.sum checksum database.
|
| |
+
|
| |
+ For an introduction to creating Go projects, see https://go.dev/doc/code/[*How to Write Go Code*]. For information on using modules, migrating projects to modules, and other topics, see the blog series starting with https://go.dev/blog/using-go-modules[*Using Go Modules*].
|
| |
+
|
| |
+ === 2. Validate input entries
|
| |
+ Helps avoid attackers who send us intrusive data that could damage the system.
|
| |
+
|
| |
+ To validate user input, you can use native Go packages like strconv to handle string conversions to other data types. Go also has support for regular expressions with regexp for complex validations. Even though Go’s preference is to use native libraries, there are third-party packages like https://github.com/go-playground/validator/[*validator*]. With validator, you can include validations for structs or individual fields more easily.
|
| |
+
|
| |
+ === 3. Use HTML templates
|
| |
+ One critical and common vulnerability is cross-site scripting or XSS. This exploit consists basically of the attacker being able to inject malicious code into the app to modify the output.
|
| |
+
|
| |
+ Go has the package https://pkg.go.dev/html/template[*html/template*] to encode what the app will return to the user. So, instead of the browser executing an input like <script>alert(‘You’ve Been Hacked!’);</script>, popping up an alert message; you could encode the input, and the app will treat the input as a typical HTML code printed in the browser.
|
| |
+
|
| |
+ There are also third-party libraries you can use when developing web apps in Go. For example, there’s https://www.gorillatoolkit.org/[*Gorilla web toolkit*], which includes libraries to help developers to do things like encoding authentication cookie values. There’s also https://github.com/justinas/nosurf/[*nosurf*], which is an HTTP package that helps with the prevention of cross-site request forgery (https://owasp.org/www-community/attacks/csrf/[*CSRF*]).
|
| |
+
|
| |
+ [source, go]
|
| |
+ ----
|
| |
+ ```golang
|
| |
+ name := r.FormValue("name")
|
| |
+ template := template.Must(template.ParseGlob("xss.html"))
|
| |
+ data["Name"] = name
|
| |
+ err := template.ExecuteTemplate(w, name, data)
|
| |
+ ```
|
| |
+ ----
|
| |
+
|
| |
+ === 4. Protect yourself from SQL injections
|
| |
+ The first thing you need you to do is make sure a user that connects to the database has limited permissions. A good practice is to also sanitize the user’s input, as I described in a previous section, or to escape special characters and use https://pkg.go.dev/html/template#HTMLEscapeString/[*HTMLEscapeString*] function from the HTML template package.
|
| |
+ But, the most critical piece of code you’d need to include is the use of parameterized queries. In Go, you don’t prepare a statement in a connection; you prepare it on the DB. Here’s an example of how to use parameterized queries:
|
| |
+
|
| |
+ [source, go]
|
| |
+ ----
|
| |
+ ```golang
|
| |
+ customerName := r.URL.Query().Get("name")
|
| |
+ db.Exec("UPDATE creditcards SET name=? WHERE customerId=?", customerName, 233, 90)
|
| |
+ ```
|
| |
+ ----
|
| |
+ If using the db.Query() function instead, ensure you sanitize the user’s input first, as above.
|
| |
+
|
| |
+ === 5. Encrypt sensitive information
|
| |
+ Go package that includes robust implementations to encrypt information like https://pkg.go.dev/golang.org/x/crypto/[*crypto*].
|
| |
+
|
| |
+ === 6. Enforce HTTPS communication
|
| |
+ To secure in-transit connection in the system isn’t only about the app listening in port 443. You also need to use proper certificates and enforce HTTPS to avoid attackers downgrading the protocol to HTTP.
|
| |
+
|
| |
+ [source, go]
|
| |
+ ----
|
| |
+
|
| |
+ ```golang
|
| |
+ w.Header().Add("Strict-Transport-Security", "max-age=63072000; includeSubDomains")
|
| |
+ ```
|
| |
+ ----
|
| |
+
|
| |
+ You might also want to specify the server name in the TLS configuration, like this:
|
| |
+
|
| |
+ [source, go]
|
| |
+ ----
|
| |
+ ```golang
|
| |
+ config := &tls.Config{ServerName: "yourSiteOrServiceName"}
|
| |
+ ```
|
| |
+ ----
|
| |
+ Of Note: It’s always a good practice to implement in-transit encryption even if your application is only for internal communication. Imagine if, for some reason, an attacker could sniff your internal traffic. Whenever you can, it’s always best to raise the difficulty bar for possible future attackers.
|
| |
+
|
| |
+
|
| |
+ === 7. Use caution with unsafe and cgo
|
| |
+
|
| |
+ Package https://pkg.go.dev/unsafe[*unsafe*] provides an escape hatch from Go’s type system, enabling interactions with low-level and system call APIs, in a manner similar to C programs. However, unsafe has several rules which must be followed in order to perform these interactions in a sane way. It’s easy to make https://github.com/golang/sys/commit/b69606af412f43a225c1cf2044c90e317f41ae09/[*subtle mistakes when writing unsafe code*], but these mistakes can often be avoided.
|
| |
+ This blog post: https://blog.gopheracademy.com/advent-2019/safe-use-of-unsafe-pointer/[*Safe-use-of-unsafe-pointer*] will introduce some of the current and upcoming Go tooling that can verify safe usage of the unsafe. Pointer type in your Go programs. If you have not worked with unsafe before, Recommended reading previous https://blog.gopheracademy.com/advent-2017/unsafe-pointer-and-system-calls/[*Gopher Academy Advent series blog*] on the topic.
|
| |
+
|
| |
+ Go's https://pkg.go.dev/cmd/cgo[*cgo*] system for calling C functions offers a very convenient feature. As outlined in https://relistan.com/cgo-when-and-when-not-to-use-it
|
| |
+
|
| |
+ Here are some problems with using Cgo in your application:
|
| |
+
|
| |
+ * It breaks a lot of Go’s awesome tooling
|
| |
+ * Puts Go’s concurrency promise at risk
|
| |
+ * Might break your static binary,
|
| |
+ * Breaks cross-compiling almost always
|
| |
+ * Calls into Cgo are much slower than native Go calls
|
| |
+
|
| |
+ === 8. Be mindful with Errors and Logs
|
| |
+ Go doesn’t have exceptions. This means that you’d need to handle errors differently than with other languages. The standard looks like this:
|
| |
+ [source, go]
|
| |
+ ----
|
| |
+ ```golang
|
| |
+ if err != nil {
|
| |
+ // handle the error
|
| |
+ }
|
| |
+ ```
|
| |
+ ----
|
| |
+
|
| |
+
|
| |
+ Also, Go offers a native library to work with logs. The most simple code is like this:
|
| |
+ [source, go]
|
| |
+ ----
|
| |
+ ```golang
|
| |
+ package main
|
| |
+
|
| |
+ import (
|
| |
+ "log"
|
| |
+ )
|
| |
+
|
| |
+ func main() {
|
| |
+ log.Print("Logging in Go!")
|
| |
+ }
|
| |
+ ```
|
| |
+ ----
|
| |
+
|
| |
+
|
| |
+ Finally, make sure you apply all the previous rules like encryption and sanitization of the data you put into the logs.
|
| |
+
|
| |
+
|
| |
+ ==== Libraries
|
| |
+ * https://github.com/o1egl/paseto[*paseto - Platform-Agnostic Security Tokens implementation in GO (Golang)*]
|
| |
+ * https://github.com/StalkR/hsts/[*hsts - Go HTTP Strict Transport Security library*]
|
| |
+ * https://github.com/dgrijalva/jwt-go/[*jwt-go - Golang implementation of JSON Web Tokens (JWT)*]
|
| |
+
|
| |
+
|
| |
+
|
| |
+
|
| |
+ ==== Further Reading
|
| |
+
|
| |
+
|
| |
+ * https://github.com/Binject/awesome-go-securityhttps://github.com/Binject/awesome-go-security
|
| |
+ * https://owasp.org/www-pdf-archive/Owasp-171123063052.pdf
|
| |
+ * https://github.com/securego/gosec
|
| |
+ * https://tutorialedge.net/golang/secure-coding-in-go-input-validation/
|
| |
+ * https://tour.golang.org/list
|
| |
+ * https://snyk.io/blog/go-security-cheatsheet-for-go-developers/
|
| |
+ * https://hackernoon.com/security-considerations-in-golang-xo4y3ykk
|
| |
+ * https://golang.org/security
|
| |
+ * https://github.com/guardrailsio/awesome-golang-security
|
| |
+ * https://blog.sqreen.com/top-6-security-best-practices-for-go/
|
| |
+ * https://cyral.com/blog/security-as-code-implementing-lint-and-gosec/
|
| |
+ * https://github.com/OWASP/Go-SCP
|
| |
+ * https://spacetime.dev/memory-security-go
|
| |
+ * https://github.com/parsiya/Hacking-with-Go
|
| |
+ * https://github.com/denji/golang-tls
|
| |
+ * https://checkmarx.com/blog/redos-go/
|
| |
+ * https://blog.trailofbits.com/2019/11/07/attacking-go-vr-ttps/
|
| |
+ * https://utcc.utoronto.ca/~cks/space/blog/programming/GoCgoErrorReturns
|
| |
rfc add Good Practices for Securing Go