The Node Package Manager (NPM) is another feature that needs looking at, as there’s nothing to say that while a package is secure at version 1.2.5, it will still be secure at version 1.3.
Runtime server poisoning
In most web servers, every request will create a new child process, and then when the page has been sent to the client the process will terminate. However, since our Node server is running on a single thread, then if the thread is corrupted then the behaviour of the web server will change until it is restarted, as the thread doesn’t terminate, it keeps serving until the server is stopped.
There are several things that make these sorts of attacks scary.
- It is stealthy. There are no log records generated except maybe of the original request, and if executed correctly then there will be no noticable changes to the server.
- It goes past HTTPS, since the attack is targeted at the server itself then no matter how secure the transaction to the server is, the information is still accessible.
- It’s hard to protect against. In PHP, the attacker would have to rewrite the server files to achieve this behaviour and usually the server process s not allowed to modify those files whereas in Nide there is no generic security restrictions that would apply.
Upon sending malicious data to this function, we can execute any statements that we want. This is one of the more benign ways of altering the server behaviour since adding another path to the list of paths is all that is done. You can see what happens when we send the data via the image below.
Now since the web server has been changed, any GET request to ‘/url’ will instantly send text back saying, ‘corrupted’ and terminate the connection to the server. This makes the web page completely useless until the server has been restarted.
How could it be worse?
Well all we did is save the ‘live’ copy of the function, we could edit the function in the source file and then if we were running it with Nodemon, the server would restart and the original would have to be restored via Github or whatever you’re using.
How can it be prevented?
You can validate your params.req.* on the server side before using them.
Eval() is a bad command and should not be used, since it opens up so many security flaws.
Denial of service
One of the simplest forms of network attacks. Instead of trying to delete, steal or modify data, the aim of this attack is to prevent access to the service/resource/website. This is usually achieved by flooding the server with requests which it is then unable to handle and will become unresponsive and may crash. This is particularly effective in PHP as every request creates a new process. Node’s architecture makes it require less system resources per request which makes it rather resilient.
These are some benchmarking tests against a Node.js server giving a ‘Hello World’ page.
As you can see, Node was able to easily cope with a large number of requests on just 1 thread. There’s never a tonne you can do to stop a DDoS attack.
How can it be prevented?
Anything CPU heavy should be assigned to a worker thread. I will look into Cluster Master on Github and I’ll create an article about it before the end of the week. This will prevent the main thread from locking whilst more requests pile up.
Hash collisions (method to Denial of service)
What’s the problem?
An attacker can send malicious request to your server with HTTP requests containing thousands of parameter names with colliding hash values. When a server receives this request, it takes them a long time to find the variable you were actually looking for, as most web servers will automatically populate the POST and GET arrays. A request with a 3MB payload on a 1GHz CPU would be busy for around a whole minute, This is a big issue, since those requests can be sent often.
Here is a table showing the server types and what it takes to effectively stop a server.
|PHP||70-100kbit/s to keep one i7 core constantly busy
Gigabit connection can keep about 10,000 i7 cores busy
|ASP.NET||30kbit/s to keep one Core2 core constantly busy
Gigabit connection can keep about 30,000 Core2 cores busy
|Java Tomcat6||6 kbit/s can keep one i7 core constantly busy
Gigabit connection can keep about 100,000 i7 cores busy
|Python (32bit only)||20 kbit/s can keep one Core Duo core constantly busy
Gigabit connection can keep about 50,000 Core Duo cores busy.
|Ruby||850 bits/s can keep one i7 core busy
Gigabit connection can keep about 1,000,000 i7 cores busy
(Data taken from - http://blog.fortify.com/blog/2012/01/04/_
How can I prevent it?
I don’t actually currently know, but if anybody know’s then please comment.
Improving Application Security
As you will know, Node is still quite young and has no default configuration for security. This means without some planning, configuring and extensive testing then you just can’t know for sure that your site is secure. You need to run tests on every module that you install, and READ THE DOCUMENTATION.
Know what a module is used for
Just because it does what you require, doesn’t mean it’s a good choice. A module in it’s baby stages could provide huge entry points for attackers. The server was designed to be a scaling and non-blocking server, not a fortress.
Implementing heavy calculations or long intense processing in a Node.js server should not be done in the main thread. Due to Node.js’s single event loop this will clog the server and adversely affect the availability of the service. This is why long calculations or processes in the main thread must be avoided.
Don’t get me wrong, Node.js can be secured rather easily, although you have to actively work on it whilst developing. There is no catch-all for node security. You want proof that it can be secured? Look at all of them here or here! They include Microsoft, Yahoo and Ebay.