Is it okay to not send a response to urls that people are pentesting my node/express site?

Viewed 148

I log all 404s on my website. I keep getting them for pages I haven't linked to, and it's clearly someone (a bot) trying to find admin pages / secure files on my site such as /wp-admin.php;

router.get('/wp-admin.php', function(req, res, next) {});

I tried this and it doesn't seem to hold up the server, it just outputs something like this a minute later:

GET /wp-admin.php - - ms - -

Is there any detriment to adding routes such as that, where no response is sent, possibly wasting their time?

2 Answers
router.get('/wp-admin.php', function(req, res, next) {});

This will cause express to time out and close the connection. This will make Denial of Service attack easier for hackers and jam up your node server. You can always use some kind of rate limiters to prevent continuous request from a certain IP.

express-rate-limit is a can be used for this. It is simple express middleware

As noted in the already accepted answer, an Express route like that will leave you vulnerable.

I recommend going one step further and tearing down those requests using req.destroy.

I'm not sure of the implications of Express being included, here, though. For example, is the request body being read automatically by a middleware upstream of this request handler you've shown? If so, that would be an attack vector that makes the mitigation I'm suggesting useless.

Regardless, to demonstrate what I am suggesting with a vanilla HTTP server:

var h = require('http')

h.createServer(function(req, res) {
  // tear down the socket as soon as the request event is emitted
  req.destroy()
}).listen(8888, function() {
  // send a request to the server we just created
  var r = h.request({port: 8888})
  r.on('response', console.log.bind(console, 'on_response'))
  r.on('error', console.log.bind(console, 'on_error'))
  r.on('timeout', console.log.bind(console, 'on_timeout'))

  // abort will be emitted to the caller, but nothing else
  r.on('abort', console.log.bind(console, 'on_abort'))
  r.end()
})

You could also call socket.destroy in the connection event of the HTTP server if you're able to identify the calling agent as a bot (or whatever) somehow.

var h = require('http')

h.createServer(function(req, res) {
  res.send('foo')
}).on('connection', function(socket) {
  // pretend this ip address is the remote address of an attacker, for example
  if (socket.remoteAddress === '10.0.0.0') {
    socket.destroy()
  }
}).listen(8888, function() {
  // send a request to the server we just created
  var r = h.request({port: 8888})
  r.on('response', console.log.bind(console, 'on_response'))
  r.on('error', console.log.bind(console, 'on_error'))
  r.on('timeout', console.log.bind(console, 'on_timeout'))

  // abort will be emitted to the caller, but nothing else
  r.on('abort', console.log.bind(console, 'on_abort'))
  r.end()
})
Related