Reputation: 23
Using expressjs with the morgan middleware for logging, I have noticed some frequent and alarming requests in the server logs.
Relevant logger code
var app = express();
app.use(morgan(':remote-addr - [:date[clf]] ":method :url HTTP/:http-version" :status :res[content-length] ":referrer" ":user-agent"'));
as such, examples of the logs are
::ffff:(redacted) - [Fri, 24 Jul 2015 04:16:32 GMT] "GET / HTTP/1.1" 200 29294 "-" "-"
::ffff:(redacted) - [Fri, 24 Jul 2015 04:17:30 GMT] "GET http://example.com/path.php HTTP/1.1" 200 34523 "-" "-"
::ffff:(redacted) - [Fri, 24 Jul 2015 04:17:36 GMT] "GET /path HTTP/1.1" 200 29294 "-" "-"
Unfortunately I have no clue how to reproduce such an error. Is this a potential vulnerability? Log forging? Where might I find further information?
Specifically, this line where the url is "GET http://example.com/path.php HTTP/1.1", where example.com is NOT my domain, nor is my server set up to make requests to this example.com. Normally just a path (ie, /example, /path, /) is displayed here. In addition, these lines typically appear as part of obvious vulnerability scans from external IPs, and the response of 200 worries me. Are the logs indicating an outbound request? Is someone somehow using my server as a proxy?
Upvotes: 0
Views: 1586
Reputation: 23
This issue can be reproduced by connecting to the server and sending TCP packets to form an HTTP request.
Assuming the server is deployed locally, this could be reproduced in ubuntu using netcat and sending an HTTP request such as
netcat localhost 8080
GET http://example.com/path.php HTTP/1.1
Since this is not a malformed HTTP request, nodejs correctly handles it, but as a result the url passed through nodejs is more than just a path, and contains whatever protocol and domain is given.
This could potentially crash some node, or express, applications that only expect the request url (or in the case of express, originalUrl) to resemble a path, as the express documentation and these stackoverflow answers one and two imply.
As for why it returns a 200, it would be application specific.
With this in mind, it is important not to assume that the request url, nor the request originalUrl in the case of express, is a path and begins with '/', and when it does not start with '/' it may not even contain the correct protocol or domain.
Express may, in v4 at least, "fix" request urls that do not start with a '/', but the originalUrl part of the request object is not changed. In any case, it still should not be assumed that the url begins with a '/'.
A simple way to avoid problematic requests like this in express is to place a middleware to handle this case near the top of the middleware stack. An example is given below. Placing this before the logger will prevent these errors from being logged, if that is desired.
app.use(function(req, res, next) {
if(req.url[0] !== '/' || req.originalUrl[0] !== '/') {
res.status(404).send('');
} else {
next();
}
});
Upvotes: 1