Reputation: 68406
Say I have a Node.JS server app and I want to block users that failed to log in 3 consecutive times, what is the correctly way to do that?
Should I handle the blocking part in the server app, basically after the user has connected but has not yet logged in, or is there some lower level stage where I am supposed to do it, so it doesn't even reach my Node.JS app?
Upvotes: 16
Views: 21980
Reputation: 1156
First thing that can come to mind after detecting an attack is to block an attacker’s IP address.
IP blocking is not the right way to prevent users after the number of incorrect logins.
But that’s not a very good way of deterring an attack, because:
There are several different techniques for security to stop this types of attacks,
You can manage logs of failed logins for a user account and calculate how many failed attempts are done from the same IP within the last N minutes based on that you can temporarily Deactivate the account of the user.
After failing to log in the account, you can start showing captcha when the user tries to login after 3 failed or add security questions.
Send email to the user regarding failed attempts and the method to recover the account by changing the password.
Upvotes: 1
Reputation: 14155
You should think about what should happens if:
And some users have static IP address (they can not change it).
Solution
Because of this I would block the account and IP address(es), and then I would send an email to the account owner with a link wich will deblock the account and this without the require of the password changing. The account owner should also answer about deblocking of IP address(es), because he knows his IP address(es).
The preferable solution would be to block an IP address at a lower level – before it gets to Node.JS because all networking happens in the operating system kernel and the kernel can block it more efficiently and sooner in the connection than Node.JS could do it.
But at first to answer your question...
var blackList =
[
'77.88.99.1',
'88.77.99.1'
];
var http = require('http');
var server = http.createServer(function(req, res)
{
var ip = req.ip
|| req.connection.remoteAddress
|| req.socket.remoteAddress
|| req.connection.socket.remoteAddress;
if(blackList.indexOf(ip) > -1)
{
res.end(); // exit if it is a black listed ip
}
}).listen(80, '127.0.0.1');
And Node.js http.Server
has a connection
event. You could do it also on this way:
server.on('connection', function(socket)
{
// console.log(socket.remoteAddress);
// Put your logic here
});
Sometime it is necessary to block incoming connection or traffic from specific remote host. iptables is administration tool for IPv4 packet filtering and NAT under Linux kernel. Following tip will help you to block attacker or spammers IP address.
How do I block specific incoming ip address?
Following iptable rule will drop incoming connection from host/IP
202.54.20.22
:iptables -A INPUT -s 202.54.20.22 -j DROP iptables -A OUTPUT -d 202.54.20.22 -j DROP
A simple shell script to block lots of IP address
If you have lots of IP address use the following shell script:
A) Create a text file:
# vi /root/ip.blocked
Now append IP address:
# Ip address block file 202.54.20.22 202.54.20.1/24 #65.66.36.87
B) Create a script as follows or add following script line to existing iptables shell script:
BLOCKDB="/root/ip.blocked" IPS=$(grep -Ev "^#" $BLOCKDB) for i in $IPS do iptables -A INPUT -s $i -j DROP iptables -A OUTPUT -d $i -j DROP done
C) Save and close the file.
© Source Linux Iptables block incoming access to selected or specific ip address
Upvotes: 14
Reputation: 952
Blocking the IP address after the user failed to log in 3 consecutive times is not a good idea. Because
So what you can do to increase the security of your application without blocking the IP address? The solution is
After failing to log in the account, you can start showing reCaptcha while the user tries to login after 3 failed attempts.
You can temporarily Deactivate the account of the user in your app if the username (or email that specifically points to any account in your application database) and send the email regarding changing the password to recover back the account or something else according to your application.
There is one more idea to block the IP address if you really want to blog the IP address after 3 failed attempts you can do these steps:
Upvotes: 1
Reputation: 2315
Why do you want to block a user?
As a Security Researcher, I will give you a general answer that is not specificity for NodeJS.
IP blocking is almost ineffective because it can be easily changed.
If you block the user the attacker can easily disrupt part of the usability of your site by brute-forcing on other users or specific users to disable their accounts.
I personally use a challenge system to cover both conditions
Finally, before doing the login request, first check the user's IP, in your blacklist (10 times should be enough). If the IP was allowed then check requested user failed logins (5 times should be good) and if one of these checks fails just send a challenge back and stop login action.
You can use a secure captcha or anything else. If the client solves it correctly, do login action for it. and make sure you reset incorrect login count for users. But for IP don't do it instantly and reset it daily, weekly, or monthly.
So, any IP after 10 times of incorrect login should face with challenge and at user level after 5 incorrect logins with any IP address must pass the challenge
This way, you won't make any issues for normal users and also preventing the attacker to brute-force.
Upvotes: 14
Reputation: 13823
In your case
to block users that failed to log in
The correct way is not to do that at all.
IP blocking is more about DoS protection, or legal requirements.
So if you block by IP
(Also why to block an IP but not an account?)
But if you wanna do it anyway, then I guess that your're asking not about "how?" exactly you should do it, but "where?"
Should I handle the blocking part in the server app, basically after the user has connected but has not yet logged in, or is there some lower level stage where I am supposed to do it, so it doesn't even reach my nodejs app?
Well, that depends.
so it doesn't even reach my nodejs app
Upvotes: 1
Reputation: 74
You can get IP of the client
const remoteAddresParams = req._remoteAddress.split(':');
const IP = remoteAddresParams[remoteAddresParams.length -1];
then you can create a your own middleware , the code below may be incorrect but you get the idea.
e-g
app.use((req, res, next) => {
const blockedIPs = ['1.1.1.1', '0.0.0.0'];
const remoteAddresParams = req._remoteAddress.split(':');
const clientIP = remoteAddresParams[remoteAddresParams.length -1];
isClientBlocked= blockedIPs.any(ip => ip.toString() === clientIP.toString());
res.status(403)
res.json({success: 0, message: 'you are blocked for some reason'})
});
`
Upvotes: 1
Reputation: 229
If you are using Express in your app, then you can use express-ipfilter or similar package in order to block access by ip.
Simple example will look like this:
// Init dependencies
const express = require('express')
const ipfilter = require('express-ipfilter').IpFilter
// Blacklist the following IPs
const ips = ['127.0.0.1']
// Create the server
app.use(ipfilter(ips))
app.listen(3000)
You can store the list of ips in memory or some kind of storage like Redis, and add ips dynamically (ex. when user failed to log in 3 consecutive times). You might also want to block ips only for certain period of time (ex. one hour).
Upvotes: 1
Reputation: 15797
It seems this logic should be implemented by the same component responsible for the login; otherwise some communication between the two components would be required.
If the login check is performed in the Node.js server app, it is the right place to perform the new check as well.
Upvotes: 1
Reputation: 564
I think it user should see blocked message when they again try to login.
As other user from same IP address with correct credentials must be able to login into the system.
Upvotes: 1