The Basics of Security Concepts to Protect Your Web Service

Introduction

Nowadays, “security” is a buzzword. In a time where data is extremely important to protect. Forget about the gold or even cryptocurrencies, for a moment. The growth of interest in our data, and consequently its theft, is driven largely by Data Science, Machine Learning, Deep Learning, and even BI, and experienced with cyber attacks. With so much personal information about our customers, we must think more about security and how to store this new type of “gold”.

Data policies like  GPDR (General Data Protection Regulation) aim to protect user’s personal data within any system that they are using. If their information is shared with another company, etc, it must be done with their consent. We can even see a clause that stipulates that companies must notify users of a data breach within 72 hours of discovering the problem. In this regulation, the penalties could reach €20 million or 4% of annual global turnover.

Data protection is crucial and there is no better way to illustrate this than the  Equifax data breach, which impacted the personal information of approximately 147 million people in September of 2017. Equifax is one of the three largest consumer credit reporting agencies in the US and suffered a huge data breach all because of a little issue that could have been easily fixed. More on that in a bit. In the wake of their scandal, Equifax will have to pay up to $700 million in fines as part of a settlement with federal authorities over this data breach.

Another company discovered a hacker who had stolen almost $250K in products without paying for them. This company just discovered the fraud in the next financial cycle (one month later), where they could see money missing. Unfortunately, they decided to invest in security only right after this situation. I’m telling you these stories to illustrate the gravity of these situations to you, because any data breach could affect your company in ways you don’t ever want.

In this post, we will go through the basics of security to protect your web application or service. These concepts could be applied in any web service besides languages, but my examples will be more focused on Javascript (Node.JS) with Express and Sequelize ORM.

1. Don’t trust in your client

There is no way of knowing whether our users have good intentions or not so, we can’t trust any data inputted by our customer. This means that we need to check every input. We can do it with a blacklist or a whitelist.

In a blacklist, we have bad inputs that are deemed unacceptable as user inputs.  In a whitelist, we have inputs that we allow to exist. Let’s take a look at an example.

We know that eval() is a function that executes strings as commands in Javascript. Surely, a user with good intentions wouldn’t use this kind of content as an email. So, we will replace every eval() to be empty.

This can be helpful, however with every new threat we have to check our code and clean it up. So for this stage, whitelists are more reliable than blacklists. We have awesome libraries that help us to create quick whitelists checks in our routes, for example, Hapi/JOI. Look at this example,  where we check the inputs for user authentication:

This example above is awesome because this library will guarantee us two things:

  1. A good whitelist with good standards. If the input doesn’t fit with our standards, the new Error() will be triggered.
  2. Protection against Parameter Injection, which means that the hacker tries to send more parameters to our routes. If there exists any different parameter besides email and password , the new Error() will be triggered;

About Parameter Injection, I once witnessed a large company get hacked with this technique by an ethical hacker. These were his steps:

  • He found the profile page;
  • He saw that the profile page was using the PATCH request, i.e. the application was sending a request to update the profile data;
  • He tried to add some new parameters on this request and one of them was isAdmin: true;
  • His regular user turned into an admin user.

In our example, the only parameters allowed are email and password, and they must adhere to our standards. Don’t forget to use whitelists, they’re very helpful! They can help against Parameter Injection and XSS.

2. Use bind-params in your SQL statements

You’ve probably heard about SQL Injections, and how powerful they  can be. If you haven’t heard about them then I suggest you read about them. In addition, check OWASP Top Ten Attacks. But essentially, an attacker tries to change the queries that the system makes and gets access to the entire database.

I will never forget the day I was talking about  SQL Injection breach with one of my co-workers. . He challenged me to access a system that he made for his friend through a SQL Injection attack. This system didn’t use the bind params, so I got the admin user and I put in the password field a well-known SQL Injection command to bypass the password for any user, and voilá! I got admin access. Now, thinking about this story, I fell that I should have bet a beer with him.

The most simple solution is to use bind params. Bind params change the values inside of the database making it impossible to break the query and change to another one. Nowadays, most of the ORMs use bind params as default but pay attention to not make a custom query and execute it without bind params. For example, in Node.JS + Sequelize, if we want to use a custom query, we could do something like:

The image above shows two methods, the first method is an example with a custom query without bind params and the second is one with a custom query using bind params. You might’ve guessed right, the second method is the better one. If you have to use custom queries, then please, don’t forget to use the bind params. Also, ensure that your ORM uses them too. I know Sequelize does by watching the logs, and I know the most famous ORMs are using them, but if you’re the kind of person that loves to try new technologies and libraries, that’s a good point to start your decision if that ORM is good or not.

Therefore, don’t use any kind of query without bind params. SQL Injection is considered one of the most famous of the top ten attacks on web applications, and it was discovered in the ’90s. So, it shows how neglected the most developers and engineers have been. I still don’t know why we don’t teach the developers to use bind params since the first class to connect on the database and make queries.

3. Don’t expose sensitive data

How often does your web service handle sensitive data? If you never asked yourself this  question, probably your web service exposes more sensitive data than you think.

The first step is to apply an SSL/TLS certificate on our web service and use it as the default connection. We can’t accept HTTP connections anymore for systems that use our personal information! This certificate ensures that we have an encrypted connection between servers and customers, which almost mitigates “data sniffing” from a third party (Man in the Middle attack).

Next, ask yourself: how could we help hackers to access our information? Showing system errors to them!  Errors can sometimes display a lot of sensitive information such as the database system, table names, field names, constraint names, the language (Javascript, Java, Python, etc) and sometimes we can even see hosting information and passwords. When that happens, it gives to hackers a good guide to exploring the known security breaches for the technology, systems, frameworks, and language that your web service works with.

I can’t stress this one point enough: do not show errors to users. We need to intercept them and send them to programs like Rollbar or Sentry. These programs have great support for many languages not to mention it’s pretty simple to configure your exceptions to show a default message to the user and send the system error to those tracker programs.

In the end, it’s best to show to user a default error message or a described user-friendly error message (it depends on your web service and your business rules) instead of showing the whole system error. Do you don’t know what could be your default error message? Just try: “Internal Server Error”. It’s so much better and reliable when a system shows it rather than the whole system error.

4. Check your third-party libraries

Equifax will pay up to $700 million in fines. Could you imagine your company being responsible for a huge data breach like that? So, what happened on Equifax? Well, it’s not a complicated story to tell.

Equifax had a system that used Apache Struts. Two months before the attack, Apache Struts had announced a new patch to fix a specific vulnerability. Two months later, the hacker was exploiting this vulnerability which means that Equifax didn’t update their systems.

This was the result:

https://www.youtube.com/watch?v=e6fIuRqu6wc

https://www.youtube.com/watch?v=V38eMXbK7gg

To prevent this kind of problem, we have to look at our third-party libraries. Nowadays, it’s almost impossible to create any application without using any third-party library or framework. But one has to ask, who made that library? How well managed is it?. We are human beings and we make mistakes. Therefore, as a developer, it is your responsibility to manage the integrations you use. This means assess their risks, and understand the potential effects it can have on your system, and stay up to date on any updates. 

There’s a fantastic tool called Snyk, which keeps developers vigilant to failures, vulnerabilities, and problems with your integrations. Snyk has a huge database with a lot of contributors and when they find a new vulnerability, they warn all their customers which have Snyk set in their applications. Most of the time they fix the new vulnerabilities automatically with one command that you need to run. Also, Snyk warns you via your email.

Snyk is truly incredible! I, personally, love how companies are working hard to give significant value, especially when it comes to security. That’s why they got more than $1B of valuation. They also have free plans and priced plans. Currently, I use the free plan for my personal projects and they support a lot of languages and package managers.

5. Set some limits for the user

I’m very enthusiastic about cryptocurrencies and Bitcoin, and I talk more about the usage of blockchain on the Trio’s blog. I remember witnessing the exchange falling down because Bitcoin’s price was rising too fast. After the owner lost a lot of money, they decided to invest more in architecture and introduced a new feature to their APIs: limits to the client.

In the exchange, to guarantee a good performance, they send a new result every minute. If you request the same route several times in that same minute, you’ll get the same cached result. It’s a great way to ensure more performance and to decrease the chances of your server falling down. Of course, we have to study and analyze the business impacts by caching the response to every minute.

Also, using a layer to protect your service from DDoS attacks such as Cloudflare is a great option, and we can combine their solution with a good architecture on our APIs, This is actually what this exchange did, they combined a cached result with Cloudflare DDoS protection.

6. Read the security section in the manual of your library

Apparently, we are reading less and less, generation after generation. Also, we’re facing problems with paying attention for extended periods of time.. As a software engineer, I know that “patience”, “attention”, and “reading” are keywords in our daily routine.mSo it’s especially important that we discipline ourselves and read the  documentation from our frameworks and third libraries, including the “Security Section”.

By using Express, I’ve noticed that we have a section called “Advanced Topics” and “Security Best Practices”.

This is awesome, but I know that most software engineers that have installed Express haven’t read the Express documentation, and probably, never bothered diving into the “Advanced Topics” section, much less the “Security Best Practices” page.

To my surprise, when I decided to implement Express in one of my APIs, I saw this section and found that Express offers wonderful documentation on how to protect your web service with Express. With that documentation, I was able to learn how to use Express in a way that did not compromise my system in the future. 

7. Don’t be paranoid and don’t neglect to study security

After studying about security for my applications and web services, I started to go a little crazy! I couldn’t finish my tasks on time because I was thinking too much about all of the potential  security breaches in my code. We have to remember that even big organizations like the CIA, Sony, eBay, Yahoo, JP Morgan Chase, Netshoes, Dropbox, YouTube and other, have been hacked. Considering that, don’t be so paranoid about your services, after all, if the hackers really want to hack your application, they probably will find a way. It’s just in their nature. The question is: how much time do you need to identify that a hacker bypassed your security barriers? With good logs and strong alerts strategy, we can identify breaches sooner and thus act on them quicker.

This is not an excuse to tell yourself that it’s pointless because hackers will win. Developers and Cyber security professionals work to build as many walls, mazes, traps and other defenses for hackers to become discouraged at and leave their system alone. So it’s best to make the hacker’s job as hard as possible in hopes that they move on to their next target. 

Also, don’t neglect to study security. This post is covering the most basics security techniques that we should be learning in college or in beginner tutorials on the Internet. Most developers are not interested in protecting their services at a basic level. That’s a problem.

Therefore, don’t be paranoid but don’t neglect to study and invest time in protecting your applications. A good resource to study is the OWASP page, especially the projects page. You can download the “Lab” projects to start them locally and hack them by yourself. These projects have security breaches implemented on purpose. It’s so funny to learn in this way, where you can be a hacker and the software engineer trying to stop the hacker (you) at the same moment. The Node.JS project to learn is called NodeGoat and there’s a tutorial guide to help you to hack and protect a project. There are other projects in other languages as well, it's worth taking a look at them.

The only way to truly find ways to stop a hacker is to think like one and break your own system. This is the fundamental idea of penetration testing 

8. Logs and Monitoring

There are some situations where we need to audit our data to answer some kind of questions like: “Who edited this line?”, “What is making our server too slow?”, etc.

We can’t answer these questions if we don’t have good logs. That could be dangerous to any company, including if a company needs to identify a user with bad intentions. Imagine the following situation: Someone hacked your web service to process payments from the clients. Your boss asks: “How did the hacker pass through our security barriers?”

This could be a tough question if you don’t have good logs to  start your investigation with. I doubt any executive is trying to hear the excuse that there weren’t any logs and therefore their is no way of knowing. That wouldn’t get you very far.  So, don’t neglect your logs and make sure you have a system in place to keep track of them..

Conclusion

I hope this post helped introduce you to some basic steps to protect your web service and your web application.  It’s important to start thinking about cybersecurity with our web applications and applying what we learn through research and practice to guarantee a safer system.