DEV Community

Cover image for 12 Security Tips for Golang Apps - validation, sanitization, auth, CSRF attacks, hashing ++
Nik L.
Nik L.

Posted on

12 Security Tips for Golang Apps - validation, sanitization, auth, CSRF attacks, hashing ++

Security isn't optional, it's foundational.

Let's talk about building bulletproof Golang applications! Here's a breakdown of the key practices, with some code examples to get your hands dirty:

1. Validating and Sanitizing Input (Say NO to Dirty Data!)

Never trust user input! Always validate it to prevent attacks like SQL injection, XSS, and command injection. Think of it as building a security checkpoint for your app. Here's an example using the popular Govalidator package:

package main

import (

type User struct {
  Username string `validate:"required,min=3"` // Enforce username length
  Email    string `validate:"required,email"`   // Validate email format

func main() {
  user := User{Username: "admin", Email: "invalid@email"}
  validate := validator.New()
  err := validate.Struct(user)
  if err != nil {
    fmt.Println("Validation error:", err)
  fmt.Println("User data is valid!")
Enter fullscreen mode Exit fullscreen mode

2. Authentication

Think of authentication as your app's entry point. It ensures only authorized users can access sensitive areas. Common methods include username/password, tokens, or social logins. Here's a simplified example (implementation details will vary):

func Login(username, password string) (bool, error) {
  // Simulate checking credentials against a database
  if username == "admin" && password == "secret" {
    return true, nil
  return false, fmt.Errorf("Invalid username or password")
Enter fullscreen mode Exit fullscreen mode

3. Authorization: Role-Based Access Control (RBAC) – Who Gets What?

Once a user is authenticated, RBAC restricts access based on their roles. Imagine an admin having full access, while a regular user might only view specific data. Here's a conceptual example:

func GetUserRoles(username string) ([]string, error) {
  // Simulate fetching user roles from a database
  if username == "admin" {
    return []string{"admin"}, nil
  return []string{"user"}, nil

func CanAccessResource(username string, resource string) (bool, error) {
  roles, err := GetUserRoles(username)
  if err != nil {
    return false, err
  // Check if user's roles allow access to the resource
  for _, role := range roles {
    if allowedRoles := map[string][]string{"admin": {"*"}, "user": {"read_only"}}; allowedRoles[role] != nil && contains(allowedRoles[role], resource) {
      return true, nil
  return false, nil
Enter fullscreen mode Exit fullscreen mode

4. HTTPS: Encrypting the Conversation

Imagine your app and server having a secret conversation. HTTPS encrypts that conversation using TLS/SSL, making it unreadable even if intercepted. Here's a simplified example using the Let's Encrypt library (refer to their documentation for proper implementation):

// (code to obtain certificates from Let's Encrypt)

func StartServer(addr string) error {
  srv := &http.Server{Addr: addr}
  return srv.ListenAndServeTLS("", "") // Use obtained certificates here
Enter fullscreen mode Exit fullscreen mode

5. CSRF Protection with Anti-Forgery Tokens

Cross-Site Request Forgery (CSRF) attacks trick a user's browser into performing unauthorized actions. To prevent this, use CSRF tokens. These tokens are unique values embedded in forms or requests, ensuring they originate from your app.

6. Dependency Management: Keeping Third-Party Code Clean

Third-party libraries can be a double-edged sword. While convenient, they can introduce vulnerabilities. Regularly scan your dependencies for known issues using tools like gosec and update them promptly.

7. Password Hashing

Never store passwords in plain text! Use strong hashing algorithms (like bcrypt) with a random salt to create a unique, one-way hash for each password. This makes it extremely difficult to crack passwords even if attackers breach your database.

8. Secure Configuration is Key

Think of secure configuration as setting the right security settings for your app, server, and libraries. This might involve disabling unnecessary services, using strong defaults, and setting appropriate security headers.

9. Session Management: Don't Let Sessions Fall into the Wrong Hands

Sessions store user data during their interaction with your app. Weak session management can lead to attacks like session hijacking or fixation. Here are some tips:

  • Use a Secure Session Store: Don't store session data in cookies directly. Popular libraries like gorilla/sessions or alexedwards/scs provide secure session storage mechanisms.
  • Set Session Timeouts: Sessions shouldn't last forever. Set appropriate expiration times to automatically log users out after inactivity.
  • Use Secure Communication: Transmit session data only over HTTPS to prevent eavesdropping.

10. Error Handling: Silence is Golden (Except for Security!)

While informative error messages can aid debugging, revealing sensitive information in error messages or logs can be a security risk. Aim for informative yet secure error messages.

11. Security Audits & Penetration Testing: Regular Checkups

Just like a car needs regular maintenance, your application needs security checkups. Conduct security audits and penetration tests to identify and fix vulnerabilities before attackers exploit them.

12. Secure Deployment: Fortress Your Servers

Securing your deployment environment is crucial. Here's what you can do:

  • Use Firewalls: Firewalls act as gatekeepers, controlling incoming and outgoing traffic. Configure them to restrict access to only authorized sources.
  • Keep Software Updated: Outdated software can have known vulnerabilities. Regularly update your server software and libraries.
  • Minimize Access: Grant access (to servers and code) only to those who absolutely need it. The principle of least privilege applies here.

Remember: This is just a security foundation. Every application has unique needs. Analyze your application's specific functionalities and data to identify potential security risks and implement additional security measures accordingly.

Similar to this, I along with other open-source loving dev folks, run a developer-centric community on Slack. Where we discuss these kinds of topics, implementations, integrations, some truth bombs, weird chats, virtual meets, contribute to open--sources and everything that will help a developer remain sane ;) Afterall, too much knowledge can be dangerous too.

I'm inviting you to join our free community (no ads, I promise, and I intend to keep it that way), take part in discussions, and share your freaking experience & expertise. You can fill out this form, and a Slack invite will ring your email in a few days. We have amazing folks from some of the great companies (Atlassian, Gong, Scaler), and you wouldn't wanna miss interacting with them. Invite Form

Top comments (1)

caarl profile image

I really loved reading the most recent post on the Gizmogo Blog! The topic was not just intelligent, but also engagingly presented. Congratulations to the author for sharing such great information in such an understandable manner. I look forward to more great articles from this blog!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.