Improper path sanitization allows remote read of sensitive system resources in pufferpanel/pufferpanel

Valid

Reported on

Jun 25th 2022


In pufferpanel/files.go there is an EnsureAccess method that accepts a source string and prefix argument. This function attempts to validate that the path being requested is within the scope of the server's operating directory. However, there is a logic bug in this function that improperly passes the provided source argument into filepath.Abs() thus defeating the call to findFullPath. As a result, the check using strings.HasPrefix() always passes in the original source string, rather than the path that is found from findFullPath.

This vulnerability has existed since the inception of the 2.0 branch.

Impact

This vulnerability allows malicious server instances to easily allow remote file access, even when the server process is run within isolation (e.g. Docker) due to the filesystem handling logic. As a result, I can trigger the equivalent of ln -s /etc/passwd passwd.json, even inside a container, and when the PufferPanel instance goes to resolve the file it will improperly resolve it to the host machine's /etc/passwd file.

Occurrences

As a proof of concept, instantiate a server process (even inside of a Docker container), or manually simulate the creation of a symlink in a server's data directory that points to a resource outside the server's data directory.

For example,

ln -s /etc/passwd passwd.json

Then, in the panel's file manager open passwd.json and see the contents of the host's /etc/passwd file.

In addition, I can create a generic symlink for /etc in the directory. While the panel appears to think this symlink is a file (and shows a bunch of JSON when attempting to open it), this actually opens a much more insidious approach. Once that is linked, I can use the download endpoint to request any file within the host's /etc directory and download it.

For example, requesting https://example.com/proxy/daemon/server/2e64f362/file/etc/adduser.conf.

We are processing your report and will contact the pufferpanel team within 24 hours. a year ago
We created a GitHub Issue asking the maintainers to create a SECURITY.md a year ago
We have contacted a member of the pufferpanel team and are waiting to hear back a year ago
pufferpanel/pufferpanel maintainer has acknowledged this report a year ago
pufferpanel/pufferpanel maintainer validated this vulnerability a year ago
Dane Everitt has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
We have sent a fix follow up to the pufferpanel team. We will try again in 7 days. a year ago
Joshua Taylor marked this as fixed in 2.5.1 with commit 3e8417 a year ago
Joshua Taylor has been awarded the fix bounty
This vulnerability will not receive a CVE
files.go#L46 has been validated
to join this conversation