uAdmin The Golang Web Framework #8 Advanced Security

Abdullah Alrasheed
6 min readNov 13, 2018

--

IMPORTANT (BEFORE YOU START)

If you installed uAdmin before November 13th version 0.1.0-beta.3, please update your uAdmin installation (If you are not sure, just update it anyway):

go get -u github.com/uadmin/uadmin/...

After you do that go to your project’s folder and run:

uadmin prepare

This will update uAdmin templates and static files.

Advanced Security

There are many built in security features in uAdmin but we will talk about the most important features which are:

  • SSL
  • 2-Factor Authentication
  • Password Reset
  • Hash Salt
  • Database Encryption

SSL

To enable SSL for your project, you need an SSL certificate. This is a two parts system with a public key and a private key. The public key is used for encryption and the private key is used for decryption. To get an SSL certificate, you can generate one using openssl which is a tool for generating self-signed SSL certificate.

openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout priv.pem -out pub.pem

It will ask you for several certificate parameters but you can just press “Enter” and skip filling them for development.

You can change the key size by changing 2048 to a higher value like 4096. For production, you would want to get a certificate that is not self-signed to avoid the SSL error message on the browser. For that, you can buy one from any SSL vendor or you can get a free one from letsencrypt.org.

Once you have your keys, you can change your main.go like this:

package mainimport (
"github.com/twistedhardware/todo/models"
"github.com/uadmin/uadmin"
)
func main() {
uadmin.Register(
models.Todo{},
models.Task{},
)
uadmin.RegisterInlines(models.Task{}, map[string]string{
"Todo": "TaskID",
})
uadmin.SiteName = "Todo App"
//uadmin.StartServer()
uadmin.StartSecureServer("pub.pem", "priv.pem")
}

Notice that we commented uadmin.StartServer() and used uadmin.StartSecureServer("pub.pem", "priv.pem") instead.

Once you start your app, you will notice that your terminal logs are showing a message that says https instead of http:

When you open your app make sure that your URL uses https:// instead of http:// and you should get an error messag in your browser warning you that your SSL certificate could not be authenticated (because it is self-signed).

Proceed and you will see that your browser marks your URL in red to remind you that there is something wrong with your SSL certificate:

2-Factor Authentication

It is also referred to as 2FA which is a way of using a OTP (One Time Password) for your login process to add an extra level of security to your account. uAdmin allows you to enable 2FA per user. To enable it for your account, open your profile:

On the left you will see a link that says “Enable 2-Factor Auth” click on that to enable 2FA.

Once you enable it, you will see your 2FA QR Code. You can use Google Authenticator to scan this code.

Now log out and try to login again:

Notice that you have a new field called “Verification Code” this is the number that you have in your Google Authenticator.

If you locked your self out and because of OTP, you can get your OTP from the terminal where you are running your application:

[  INFO  ]   User: admin OTP: 621031

Password Reset

For password reset to work you need to setup an email account that will send the password reset link. Also make sure that your user has an email in the system, otherwise they will not be able to reset their password. To setup an email account, you can use your gmail account or any SMTP account. Open your main.go and add these lines of code:

import (
"github.com/twistedhardware/todo/models"
"github.com/uadmin/uadmin"
)

func main() {
uadmin.Register(
models.Todo{},
models.Task{},
)
uadmin.RegisterInlines(models.Task{}, map[string]string{
"Todo": "TaskID",
})
// Setup Email
uadmin.EmailSMTPServer = "smtp.gmail.com"
uadmin.EmailSMTPServerPort = 587
uadmin.EmailFrom = "TODO System <myemail@gmail.com>"
uadmin.EmailUsername = "myemail@gmail.com"
uadmin.EmailPassword = "my very hard password!"

uadmin.SiteName = "Todo App"
//uadmin.StartServer()
uadmin.StartSecureServer("pub.pem", "priv.pem")
}

Now run your app again and log out if you are still logged in and press “Forgot Password” from the login page:

Enter your email:

This will send you an email with a password reset link:

Click on that and you will be able to reset your password:

Hash Salt

All user passwords are hashed in the database. That means they are encrypted using a one way encryption meaning, your system does not know any user’s password. It actually encrypts the password again using the same algorithm and compares the two “hashes”. Bcrypt adds standard salt to your password to make it even more secure.

What happens when you get attacked and your database leaks into the Internet? We added one more level on security for you for this scenario. We create a file called .salt to your app’s folder which includes a 128 bytes of extra salt. This means doing any attack on your hashed passwords without knowing that long salt value is useless!

What about when the worst case scenario happens and both your database and your .salt file get hacked and leaked into the Internet. What can you do now to protect your system and yours? The answer is simple: just delete or rename your .salt file and run your system again and uAdmin will generate a new .salt file and create an emergency recovery user for you. This user does not have remote access so make sure you have access to your app from the same network before deleting your .salt file.

Database Encryption

You can keep your data in the database encrypted for any field. You might do that to protect some data or to comply with standards or fulfill client’s request. Let’s encrypt the name of our task model. To do that, open /models/task.go and add this tag to the Name fields:

package modelsimport (
"github.com/uadmin/uadmin"
)
type Task struct {
uadmin.Model
Name string `uadmin:"required;encrypt"`
TotalProgress int `uadmin:"progress_bar:30:red,70:yellow,100:green"`
}

Notice that you have to add encrypt tag to make this field encrypted in your database. Open your application and edit that field in any task you have and save:

When you check your database, you will notice that your data is encypted there.

NOTE: encrypt tag only works with string fields

Congrats for finishing this long blog. Really I was seriously thinking of making this into two parts but I believed in you and if you are reading this part it means it was worth it.

In part 9 we will talk about publishing your app.

--

--