There is no reason that a software application built today, whether for web, desktop, or mobile, should lack basic security principles. It’s like locking your house before you leave for the day or entering a pin number when using your debit card - it's standard protocol to ensure the safety of your assets. However, you'd be surprised by the number of applications out there that don’t follow best practices for security. Why do you think this is?
One of the main reasons we see this happening is because it’s not as obvious to the business that its been overlooked, as let's say -- someone neglecting to include a "Buy Now" button. As developers, whether we do or don’t implement security features should be standard protocol; but that isn’t something that the customer will typically see and thus make it obvious that it wasn't considered. And while it isn’t extremely difficult, it’s something that does take forethought, planning, and most importantly--time. In real world scenarios, and when there are tight deadlines to meet, security is one of those concepts that often takes a back seat. So although words like encryption, authentication, authorization, etc. may seem intimidating, they're actually not overly complex to incorporate when you strip them down and build an actionable plan to implement.
For all of you who are not sure how to even begin this conversation, we’ve provided some tremendous introductory topics and suggestions below for how to build a robust, secure application.Nerd Alert: the following topics can get a little tech-heavy. So fasten your seatbelts and forward this page to your technical team, if needed.
In each of the examples below, we’ll explain the following concepts as well as provide our recommended approach:
Encrypting External Communication
Authentication Best Practices
When communicating between external services such as a server and a client application, that communication needs to be encrypted or else all of the data being communicated (including sensitive data such as passwords) can be seen by other clients on the same network as you, or by any node that the communication passes through to its final destination.
Encrypting your communication is the absolute best way to begin securing your application, and it’s not a hard task. Usually it involves some minor configuration upfront and potentially a small fee if you’re purchasing a Transport Layer Security (TLS) certificate from a Certificate Authority (CA). Typically applications handle external communication via the following ways:
HTTP (Hypertext Transfer Protocol)
Message Queue protocols such as MQTT (Message Queuing Telemetry Transport) and AQMP (Advanced Message Queuing Protocol)
To encrypt via TLS, you just need to get a public key, private key, and a certificate from a CA, and then configure your web server to use that information. Certificate renewing is often a manual process that someone will have to go through once a year or so, but there are also ways of automating certificate generation and renewal. In the past, certificates historically could last several years, but ~1 year is becoming the maximum length of time for certificate validity in all major browsers (as started by Apple), which makes an automated certificate renewal process more appealing.Suggestion: At Clevyr, we use LetsEncrypt to be able to automate the renewing of our TLS certificates. Their certs have a 90 day expiration, which is typically renewed at any point within 30 days of the expiration. For message queues, either MQTT or AQMP is fine depending on the use-case (MQTT is more lightweight, while AQMP has more features), but be sure to use an implementation that handles authentication and allows for TLS; we typically use Mosquitto for MQTT and RabbitMQ for AQMP.
Authentication in software is the set of rules that defines how you get access to that software. If you google around, you’ll find plenty of various ways to handle authentication including Basic, Token (e.g. JWT, or JSON Web Token), OAuth, SAML (Security Assertion Markup Language), and more. The scope of this post doesn’t include reviewing each of these in detail, but there is a core idea among most of these authentication patterns that involves using a piece of data that is meaningless to the user for authentication. Typically in coding, we refer to this as a "token".
Let’s take a form of Token Authentication as an example. While there are many specific implementations, they all involve gathering some sort of sensitive, identifiable data (such as a username and password) to determine a user, generating a representation of that user via a token, sending that back to the user’s client application, and using that token to authenticate as that user throughout the rest of the application’s experience. This way, if your token gets compromised, you won’t have compromised the user’s password - just their token, in which case you can revoke or expire the current token and regenerate a new token for that user, or you can make tokens expire on their own for extra safety. Revoking or expiring a token may mean that your user has to log out and back in again - but that’s a much better experience than forcing them to change their password.
Your application needs to do something like this. As aforementioned, there are tons of ways to implement token authentication, and OAuth and SAML both use many of these concepts under the hood too (Basic Authentication, does not, and is not an ideal method of application-wide authentication; however, it is commonly used to send over the initial username and password to identify a user before a token is generated).Suggestion: We suggest using both signed and encrypted JWT token authentication that generates a short-lived access token and a long-lived refresh token for the user, and sending both of these tokens back to the client application on the initial authentication response. This allows you to store session-style information in an access token, but not let the client read or tamper with it. How we suggest storing these tokens is dependent on your platform. For a server-rendered web application, we suggest a secure cookie or browser local storage for the access token (both have extra securities and vulnerabilities in their own ways), as well as optionally storing the access token in memory for single-page apps (SPAs), whereas for iOS and Android we would suggest exploring Keychain and KeyStore, respectively.
This topic is going to surprise you, because our suggestions are going to be much simpler than what you’re probably expecting. In the United States, the National Institute of Standards and Technology (NIST) is the agency under the Department of Commerce that handles setting technology guidelines for government-based software applications, including password requirements. NIST has documented password requirements via their Special Publication (SP) 800-series. In a nutshell, these requirements are:
Passwords need to be at a minimum 8 characters.
Password “maximums” need to be at least 64 characters. If your application wants to allow more than 64 character passwords, that’s absolutely fine.
Screen new passwords against a list of known compromised passwords.
Don’t require a user to change their password unless it has been knowingly compromised.
Limit the number of failed logins to prevent brute force attacks.
And that’s it! One thing that may really surprise you is that NIST doesn’t recommend ever expiring user passwords. This is because password expirations provide an annoyance to the user more than anything, with no real security benefit. Think about it; when you are told that your password has expired and you need to set a new one, what do you do? If you’re not using a password manager like LastPass or 1Password to generate a new random password, you’ll probably just add a “1” to your password - and that’s not adding any realistic security whatsoever.
This same idea is present with not having a requirement for a certain number of uppercase/lowercase letters, numbers, symbols, etc. Requiring those characters doesn’t make your password more secure; it’s just a minor annoyance that likely results in you adding a number and an exclamation mark at the end of your password.Suggestion: We would suggest following NIST’s guidelines above and don’t make it any harder than necessary.
Two-factor authentication (2FA) is the idea of supplementing some form of identity verification (such as a username/password combination) with another form, such as verifying access to a phone number or email address. This becomes increasingly important depending on the sensitivity of the data that you are interacting with.
Historically, 2FA has taken place by clicking a verification link in an email that you’re sent, or by entering a code that is sent to your phone via SMS message. Over the past several years, authenticator apps such as Google Authenticator have become popular. In general these authenticator apps verify access to a single specific device or application account, instead of access to something more broad such as an email address or phone number.Suggestion: The need for 2FA is application-specific. If you’re logging in to a note-taking application, then you probably wouldn’t expect to be required to use 2FA; however, for anything involving payment information, it becomes more warranted.
Lastly, we need to address session timeouts. The idea behind a session timeout is to automatically log you out of an application if you’re not using it for a certain period of time. Tailgating / Piggybacking is the main threat that we’re trying to address here. You really don’t want someone getting unauthorized access to a service through your account, and if you leave for the day or go out to lunch with your computer unlocked while logged into an application, then you’re opening yourself up to that threat.
There’s no hard and fast suggestion here other than saying that you should do this. Depending on your application’s sensitivity, this timeout can be as short as a few minutes (i.e. banks, medical records) to several weeks (i.e. Facebook). How you “refresh” a session to keep it active depends too; some applications use page loads or data requests to refresh a session, while a mobile application may use physical touches.Suggestion: In general, for non-sensitive data, beginning with a 6 hour period of inactivity for a session timeout is acceptable. That will generally allow someone to use an application for a full day, but still be required to log in the next day. However, we would suggest beginning around a 30-minute inactivity window for a more tightly controlled experience, and shrinking that as needed.
We haven’t addressed all forms of security here, not by a longshot. You might also be thinking “but how about securing the actual data itself?” and that’s a very good point. This post is the first post in a three-part series, and we only dealt with implementing Application security here; in the next post, we’ll deal with implementing Database security, where we’ll cover topics such as SQL injection, database encryption, password storage, and backup policies.
Don't forget to communicate up front the security needs with your clients and the rest of your team -- your future selves will thank you.
And if you need more help, Clevyr offers an entire suite of web application and network security solutions to steer you in the right direction. Even more, if you have any specific questions about the topics covered here, give us a call at Clevyr (844) 425-3897 or drop us a message at [email protected].