Is Nodemailer secure?

Hi there! I have to deploy a website with a contact form. Since I’m using nodemailer (which requires to write the password of an email account), I’m wondering if it’s secure to do so, or if it’s better to encrypt the password before (e. g. using bcryptjs?).

Encryption won’t do you any good in this case. You didn’t say how you’re hosting, but there are some general tips I can give:

  • Instead of hard coding them into your source code, reference the secrets from another file somewhere. I keep them in a file called something like secrets.js and then just require them like any other module.
module.exports = {
    emailPassword: "batm4n",
    flickrAPIkey: "f981hlkjafdk1jkaodijkn"
}

Later, in app.js

var config = require("*../../config/secrets");

var emailPassword = config.emailPassword;
var flickerKey = config.flickrAPIkey;
  • Don’t check this secrets file into your repository! I put the filename in my global .gitignore file as well as project level ignore files just to make sure. To remind myself what I need to include to make the app work each time I checkout a fresh copy, I keep a copy of the secrets file, called secrets_backup.js, with all the keys but empty strings where all the passwords should go. e.g.
module.exports = {
   emailPassword: "",
   flickerAPIkey: ""
}
  • Other people use environmental variables for this. The benefit here is that you don’t have a single file that someone could get to. It’s a fine way to go, but it’s (IMHO) more complicated and easier to screw up than a plain data object, plus it would require you to either write a bunch of code cacheing each environmental variable within the app, or adding another dependency from NPM. This article should tell you how to set this up (I think, didn’t read it).

  • Set up a burner email account for NodeMailer and generate an application specific password. That way, in the unlikely event that someone gets your app password and is able to login with it, you don’t actually lose anything. Do be considerate and make sure the sent folder gets cleared out regularly.

  • Of course, standard security procedure should be followed. Have a firewall, use RSA keys instead of passwords, install fail2ban if on Linux, etc.

3 Likes

Is there a way to do that securely if you have this in your GitHub repo, i.e, if you deploy from GH?

You’d have to upload that file separately regardless of the method you use to get the secrets in your app. As far as I know, that’s the only way, but I’ve never run anything more than my own, personal servers!

2 Likes

This is a side issue, but I stumbled into troubles when using Emailjs (similar to nodemailer, I guess) because my burner email address didn’t like being linked to a web app to automate transactional emails.

Gmail in particular was really cranky about this - but it kept failing in such a way that it didn’t tell you that was the problem. Outlook is a little more forgiving - after a few panic emails claiming ‘your account has been hacked!?’

The next time I set up a mailer, I’ll use sparkpost, I think, since that is designed for transactional emails from web apps.

Ok, I think I understand that - I’ll stick to env variables for now :slight_smile:

.[quote=“JacksonBates, post:5, topic:35135”]
Gmail in particular was really cranky about this - but it kept failing in such a way that it didn’t tell you that was the problem.
[/quote]

Really? I didn’t have any trouble using Nodemailer via Gmail. As far as I knew, Gmail couldn’t even tell the difference because Nodemailer just uses SMTP. I haven’t tested it much yet, though.

Well, if you’re hosting it yourself, that might be different.

Mine was coming from Heroku and I think Gmail could smell it :slight_smile:

It was fine when I was doing stuff from localhost, but from Heroku I kept getting nondescript errors. A bit of googling suggested I might need to register an app with Google which cost $something and I’m a cheapskate, so I jumped to outlook. Outlook worked fine.

Also, I was using emailjs - I can’t imagine that their SMTP wrangling is any different to nodemailer’s, but on the off-chance it is, that’s another variable to consider…

Aaahhh… Good to know. I use my DNS company’s email service, but if I’m ever to recommend Nodemailer to Gmail users, I’ll have to do some research into these problems.

Thank you very much! This solution with the secret.js file is brilliant. So, if I understood it well, you just use secrets.js during deployment?
Until now I’ve always deployed in heroku, because it takes less time and configuration. But my problem is that I don’t want this app to sleep after 30 minutes, so I should upgrade my account (== pay). So I’m considering also other services like AWS or Digital Ocean to see which solution is better for me…