Security is challenging. It’s a moving target, and it takes a lot of effort to stay on top of things. So how can you build a business and stay on top of a changing security landscape? Primarily, you need to recognize you’re not an expert and do everything you can to stay aware of problems and nip them in the bud. Just like you wouldn’t forget to do your taxes, you don’t want to forget your security maintenance.
Chances are good that if you’re building a business, your expertise lies in an area other than security. People can spend a lifetime dedicated to understanding the intricacies of security. You won’t have time to become an expert, but you can’t afford to look the other way. How to handle it? There are some basic concepts to keep in mind.
Just like for any other kind of software defects, you’ll need a combination of tools to both prevent issues in the first place, and discover and react to issues that manage to slip through. A well-balanced attack on the key points will get you a long way.
For the most current and accurate overview around securing web applications, visit the Open Web Application Security Project (OWASP). It’s a solid starting point for anything related to securing web applications.
Like most other issues tackled in this book, you won’t learn you everything you need to know about security from a single chapter, but you can get an understanding of just how much you don’t know, and how to minimize the gaps in your knowledge. Our goal here is to help you recognize some problems in advance so you know where to spend time and upgrade your skills.
Automation and Scanning
First, you’ll need to find and use relevant automation to help catch fundamental security issues. These tools vary from simple open source libraries you can add to your stack or release process, all the way to advanced services that you pay to regularly monitor your production environment for known issues.
The simplest tools for automated scanning are static analysis tools that go through your code and look for common mistakes that can introduce security problems. These tools can be added to your test suite or run at specific times to help you proactively catch some categories of mistakes. This way, you can reduce the number of security issues that make it into production. By adding these tools to your continuous integration process, every time you commit new code they automatically check to see if you introduced any obvious security holes. They can’t catch everything, but they’re the best first step to minimizing issues.
The other approach is tools that automatically scan your production application at regular intervals. Just like tools that monitor uptime, these tools will run through a list of known vulnerabilities and generic security issues, and use them to probe your site. Then they put together a series of issues and recommendations for how to best fix the problems.
You can visit the OWASP site for a current list of vulnerability scanning tools to find one that works for your technology stack and platform.
Closely Monitor Dependencies
You’ll probably use a variety of open-source or third-party libraries in your code. Invariably, some of these will have security problems of their own, and the teams will be actively releasing and announcing fixes. Closely follow blogs and mailing lists for any third-party code you’re using.
The two best ways to do this are to rely on tools that scan your codebase for dependencies and cross-reference their findings with known vulnerabilities to identify outdated or insecure versions of third-party code. Dependency Check by OWASP is a good example, but you may need to research and find the relevant modern equivalent for your technology stack. Gemnasium is a popular hosted dependency monitoring service for a variety of languages and frameworks.
The other key step for monitoring dependencies may sound overwhelming at first, but if you make it part of your process of adding third-party code to your application, it becomes fairly easy to stay on top of. Every time you add another external piece, take a moment to look for their security news feeds or mailing list, and subscribe. Keep in mind that this isn’t limited to code that’s directly in your codebase–you’ll need to monitor news for any software you run on your servers as well. If you don’t subscribe to the relevant mailing lists and feeds, it’s only a matter of time until a critical vulnerability is announced and you miss it.
Bug Bounties and Responsible Disclosure
One of the best ways to improve security is to create a bug bounty program and official security page to encourage responsible disclosure. This gives white-hat hackers a formal way to test for security issues and report them to you. Once you’ve created a page, you can submit to various places that catalog companies offering bug bounties, and the reports will come in. The BugCrowd bug bounty list is a great place to start.
You can also set up a formal bug bounty program through sites like Bugcrowd and HackerOne. These services aren’t free, but they can make managing your bug bounty program much easier if you have the cash to spend. On the surface it may seem expensive, but it’s something worth considering sooner rather than later.
The good news is that you don’t have to pay cash for bug bounties. Just offering to acknowledge people on your security page is often enough. Of course, the better your reward, the more likely you are to entice the really good testers to look for vulnerabilities. Similarly, the less lucrative your reward, the fewer experienced penetration testers you’ll attract.
Unfortunately, bug bounty programs are a double-edged sword, and it can be time-consuming to sift through the reports because the vast majority of them are likely to be garbage. While there are a lot of really helpful people who will professionally inform you of vulnerabilities and work with you to put the right fix in place, many more are unprofessional, and some even make vague threats demanding you acknowledge them even if their report is useless or inaccurate. So make sure you launch the security program during a week when you have set aside time to sort through the first wave of reports. Or, better yet, launch it almost immediately after you launch your product. It takes time to fix issues, but it’s much better than the alternative.
Also inevitable is that many testers will run automated scanners and tools against your site regularly. While the first pass of these tools is likely to uncover some minor issues, they can generally cause a variety of problems from performance to rapid-fire exceptions in your app. In our guidelines for Sifter, I explicitly state that any vulnerabilities discovered with the use of automated tools used without advanced coordination with us are not eligible for acknowledgment.
To that end, it’s helpful to create a very specific set of guidelines about what is and isn’t valid. By explicitly stating that, for example, subdomain sites hosted by third parties are not eligible, you can reduce some of the noise in the reports. It helps filter out the lazy people, and also helps make it clear when you’re communicating with people who are making a worthwhile effort. With Sifter, 80% of our reports were from people who never even tried to create an account and login to test the application. They just copied and pasted our marketing site URL into their scanner and hoped to find something.
No matter the approach you take with a bug bounty program, I suggest starting small, and growing and improving it as your business grows. It’s impossible to perfect every aspect of your business on day one, but by taking a stab, you’ll learn what you have left to do, and you can work on it over time.
Professional Security Audits
A bug bounty program is a great way to get started with penetration testing, but it’s no substitute for hiring professionals. While external testers can poke and prod, they’ll never be able to investigate as deeply as someone you work closely with. They can review system architecture, security practices, release management, and much more.
Hiring professionals is expensive, and when you have no revenue it’s probably overkill. However, like anything else, there’s a range of options available as your business grows. As soon as you have the revenue, contract with someone to do the basics. Then, as the business develops, you’ll be able to expand and improve by bringing in larger or more experienced teams. Whatever you decide to do, don’t dismiss professional expertise.
Social Engineering Awareness
Despite your best efforts on the technical side of security, there’s always the chance that someone can use social engineering to subvert all of your defenses. This can take many forms, so it’s impossible to cover all of the scenarios, but some awareness can be beneficial.
Perhaps someone tries to gain access to an account by saying an account holder no longer works at the company. Of course, you’ll receive legitimate requests like this, so how can you tell which is which? Create processes for validating that people are who they say they are. Depending on your requirements and the likelihood of your application being a target, you might require people to send in photos of ID, or other verification methods.
With SaaS, another option is to let users handle it within their own organization. For example, if an employee leaves, and their email address is associated with a SaaS account, most smaller companies can temporarily set up that person’s email address to forward to another company account. They can then reset the password and take over the account. This ensures that the user goes through the proper channels within their own company, and it’s much more likely that the company is better equipped to validate who should and shouldn’t have access.
Regardless of your situation, these are the kinds of processes it’s best to document, both for your reference and any future team members who may be helping with support. It may seem excessive, but recording these processes in a central location is precisely the the type of work that covers its cost.
TLS and SSL
Next is TLS and SSL. It’s becoming both more important and easier to set up secure communication for your website and application. Installing a certificate isn’t the end of the story, though. Don’t assume that just because you see a lock in your browser address bar that you’re good to go. These are complex tools that interact with your web server in important ways, and it’s easy to do it wrong. So what can you do?
Regularly test your TLS/SSL configuration using something like Qualys SSL Server Test to help grade your particular installation and let you know if measures up. Use HSTS, as well as the most modern and secure versions of relevant standards. This usually involves custom configuration to your web server–a good system administrator will be able to help you stay on top of things. Like most technology, this is a moving target and the standards are constantly improving. Today’s best practice is tomorrow’s outdated standard.
Data Encryption at Rest
Encrypting data at rest is becoming an increasingly popular topic. While it has become common to salt and hash passwords, almost all other data stored in databases is available in plain text. If someone gets access to the database, they get access to the data. If that data is encrypted, though, they would also have to get the keys for the data to be useful. As hacks increase and systems become more exposed, more and more customers are requesting additional layers of security, and the value of encrypting data at rest is increasing.
Like any other security practice, encrypting data at rest makes accessing the data less convenient. For things like backups, this is a minor trade-off and obviously worth it. However, building encryption at rest into your production architecture is a bit more complicated. Some data stores and frameworks make it easier, but it’s not a common practice yet.
Moreover, encrypting data is really just the tip of the iceberg. You’ll also need to implement tools and processes for securely storing the keys, rotating them, controlling access, and how to respond if a key is compromised. Fortunately, OWASP has some solid guidance about cryptographic storage to help you decide what’s right for your application. It’s a complex topic, but this additional awareness could help you move in the right direction.
If you’re building a web application, people will need to log in and authenticate. Unless you’re a security expert, this is one scenario where you don’t want to roll your own. Look to frameworks and libraries built by experts, and bake them into your application.
These days, it’s almost a given that you’ll want to include two-factor or multi-factor authentication (2FA/MFA). Duo and Authy are two of the more popular providers for implementing multi-factor authentication. Explore your options, but seriously consider providing multi-factor authentication within your application.
When you implement MFA, keep in mind that you’ll also want to do what you can to anticipate and handle support requests where someone is locked out of their account. Your first line of defense could be to provide one-time use passwords that users download when they first set up MFA. It’s virtually inevitable that people will have problems logging in with MFA, and these are the kind of situations that some would use social engineering to exploit. Once you implement it, do your research, and give some serious thought to exhaustive controls for helping users when they become locked out of their account.
It should go without saying, but you must securely hash your passwords. If you’re storing passwords in plain text, you should not be building a web application. There’s simply no excuse for plain text password storage. OWASP offers details on best practices for password hashing and all popular frameworks provide the tools to make it easy to implement.
Storing passwords securely is one thing, but almost as important is ensuring that people use strong passwords. That means not limiting the length of the passwords or which characters can be used in a password. These days, storage isn’t an issue, and password managers do a great job handling the complexity of passwords.
On that note, take some time to ensure that your password reset and login forms work seamlessly with password managers. In general, this means using the right field types and labeling them correctly in your markup. The easier it is to create an account with a strong password through a password manager, the more secure your users’ accounts will be.
The last note on passwords concerns password resets. For something that sounds simple, they’re surprisingly easy to get wrong. Since your passwords are securely hashed, you’ll have to email people a URL to change their password. It’s imperative you design these password reset URLs to expire. Depending on your security requirements, you may want them to expire in an hour, but in most cases, twenty-four hours is quick enough. Similarly, these URLs need to be valid once only. After they’re used to reset a password, they should cease to work. Most authentication frameworks have this functionality built in, but this is still worth mentioning.
There are countless subtle implementation details around handling passwords, and the full details are outside of the scope of this book. Just recognize that however much you think you know about handling passwords, it’s not enough. Passwords are a fundamental part of your overall security, and you can never do enough to keep them safe.
Authorization is about granular permissions. If authentication tells you who someone is, authorization lets you know what they’re allowed to do. One of the best principles is to keep it as simple as possible while still getting the job done. Advanced and complex permissions are ripe for mistakes in granting permission, and it’s too easy for the wrong person to end up with the wrong permissions. The most advanced authorization system in the world doesn’t matter if it creates confusion and errors in the process of granting permission.
It’s best not to think of every possible permission and then create a granular system for managing it. Instead, think about your customers and how their roles correspond to your system. You can always create more granular controls down the road, but in the beginning you likely have a few tiers of permissions. For instance, you may want to limit user management to a certain group of users, and you might want to restrict access to account-level functionality like billing and cancellation. Keep it high-level at first, and don’t worry about highly granular permissions until there’s overwhelming demand from customers.
Similarly, if your system involves multiple users, design it to support multiple users. Having users share a login is asking for trouble. I’ve encountered dozens of systems for really serious software that failed for years to have multiuser systems, and they inevitably created problems and challenges in sharing user names and passwords.
Finally, remember to revalidate passwords for sensitive actions. For instance, when someone goes to cancel an account or change their password, you’ll need to ask for the password before they continue. Otherwise, if someone left their computer open, anyone could come along and cancel their account or change their password. So build a facility for revalidating passwords, and make it easy to add in front of any sensitive requests.
Session Management for Users
If you’ve never built a system for managing authentication and authorization for a web application, spend some time on this stuff. The technology side combined with user experience and security requirements can create a complex system with endless permutations.
How long should a session last before you log someone out? When they log out, should it only be their current session or all sessions on all machines? Do users need to be able to see and manage all active sessions for their user account? What activities should require the user to reenter their password?
You probably don’t need to provide advanced session management tools right out of the gate, but it’s worth keeping in mind. Or, if your application has high security requirements, you’ll want to record all sessions tied to a specific user. This involves capturing the IP address, user agent, and operating system information so users can identify any sessions that aren’t their own. In general, this level of logging is a good security practice anyway.
You should have some throttling capabilities for your application. At a minimum, throttle requests to your login, password reset, and billing-related forms. These are the most common targets, and while throttling can’t completely protect your application, it’s a key support in mitigating attacks.
At the simplest level, this functionality is often built into your web server. However, depending on your stack, it may not be easy to add more advanced throttling controls. For instance, if a team of people are sharing a single internet connection, they may appear to your application as a single user. As a result, less discerning throttling tactics could lock out the users if they all happen to be using your application at the same time and look to be the same user making too many requests. Throttling is important, but it’s tricky to get right.
Storing and Updating Secrets
Your team will inevitably have technical secrets that need to be safely stored. There will be quite a few of these, and it’s worth designing your system to handle them early on. Where are they stored? How do they get pushed to newly provisioned machines? Who has access? How are they rotated? (You are rotating them regularly, right?)
The most common mistake is to accidentally commit these secrets to source control. Even when they are deleted, and the commits updated, the original version is still there in source control because that’s what it’s designed to do. Ensure early on that sensitive files are ignored by version control. That way, you can avoid committing them in the first place.
Create a process for rotating secrets periodically. For example, when someone leaves the company, ensure that secrets are changed and updated. You might be tempted to create this process the first time you have to use it, but that would be a mistake. When it comes time to use the process, you don’t want to have to think about it under pressure. Sit down ahead of time to think about and establish the process so you’re prepared.
Payments and PCI
The PCI Security Standards Council has established standards for security around payments and data protection. Hopefully, you’ll be using a PCI-compliant payment provider, and your PCI obligations will be minimal. But it’s still important that you understand PCI compliance and how it relates to your business. You’ll probably only need to document some basic processes and controls. Again, these manual processes may seem like something that can be put off, but you’ll benefit if you make time for them and document them now. Your payments provider should offer clear guidance on how to handle this process.
Security is one of the most dynamic skill sets in the technology industry, and while you can learn the fundamentals, nothing is going to beat leaning on experts. You can’t expect to learn everything and become a security expert, but you can and should stay aware of the security landscape and the implications for your application and customers.
Actively learn and keep up on your own. You don’t have to know how to fix a problem, but you should be aware and knowledgeable about whether a problem affects you. Then, if you have a security expert available, you can enlist them to help patch the problem.
Stay on top of it. Keep up with news and take steps to stay educated about current industry trends and practices.