d1c0ca5260
This wonderfully large commit replaces basically everything under the `server/filesystem` package, re-implementing essentially everything. This is related to https://github.com/pterodactyl/wings/security/advisories/GHSA-494h-9924-xww9 If any vulnerabilities related to symlinks persist after this commit, I will be very upset. Signed-off-by: Matthew Penner <me@matthewp.io>
44 lines
1.6 KiB
Go
44 lines
1.6 KiB
Go
package filesystem
|
|
|
|
import (
|
|
"path/filepath"
|
|
"strings"
|
|
|
|
"emperror.dev/errors"
|
|
)
|
|
|
|
// Checks if the given file or path is in the server's file denylist. If so, an Error
|
|
// is returned, otherwise nil is returned.
|
|
func (fs *Filesystem) IsIgnored(paths ...string) error {
|
|
for _, p := range paths {
|
|
//sp, err := fs.SafePath(p)
|
|
//if err != nil {
|
|
// return err
|
|
//}
|
|
// TODO: update logic to use unixFS
|
|
if fs.denylist.MatchesPath(p) {
|
|
return errors.WithStack(&Error{code: ErrCodeDenylistFile, path: p, resolved: p})
|
|
}
|
|
}
|
|
return nil
|
|
}
|
|
|
|
// Generate a path to the file by cleaning it up and appending the root server path to it. This
|
|
// DOES NOT guarantee that the file resolves within the server data directory. You'll want to use
|
|
// the fs.unsafeIsInDataDirectory(p) function to confirm.
|
|
func (fs *Filesystem) unsafeFilePath(p string) string {
|
|
// Calling filepath.Clean on the joined directory will resolve it to the absolute path,
|
|
// removing any ../ type of resolution arguments, and leaving us with a direct path link.
|
|
//
|
|
// This will also trim the existing root path off the beginning of the path passed to
|
|
// the function since that can get a bit messy.
|
|
return filepath.Clean(filepath.Join(fs.Path(), strings.TrimPrefix(p, fs.Path())))
|
|
}
|
|
|
|
// Check that that path string starts with the server data directory path. This function DOES NOT
|
|
// validate that the rest of the path does not end up resolving out of this directory, or that the
|
|
// targeted file or folder is not a symlink doing the same thing.
|
|
func (fs *Filesystem) unsafeIsInDataDirectory(p string) bool {
|
|
return strings.HasPrefix(strings.TrimSuffix(p, "/")+"/", strings.TrimSuffix(fs.Path(), "/")+"/")
|
|
}
|