lib/model, lib/versioner: Prevent symlink attack via versioning (fixes #4286)
Prior to this, the following is possible: - Create a symlink "foo -> /somewhere", it gets synced - Delete "foo", it gets versioned - Create "foo/bar", it gets synced - Delete "foo/bar", it gets versioned in "/somewhere/bar" With this change, versioners should never version symlinks.
This commit is contained in:
@@ -27,6 +27,8 @@ type External struct {
|
||||
}
|
||||
|
||||
func NewExternal(folderID, folderPath string, params map[string]string) Versioner {
|
||||
cleanSymlinks(folderPath)
|
||||
|
||||
command := params["command"]
|
||||
|
||||
s := External{
|
||||
@@ -41,13 +43,16 @@ func NewExternal(folderID, folderPath string, params map[string]string) Versione
|
||||
// Archive moves the named file away to a version archive. If this function
|
||||
// returns nil, the named file does not exist any more (has been archived).
|
||||
func (v External) Archive(filePath string) error {
|
||||
_, err := osutil.Lstat(filePath)
|
||||
info, err := osutil.Lstat(filePath)
|
||||
if os.IsNotExist(err) {
|
||||
l.Debugln("not archiving nonexistent file", filePath)
|
||||
return nil
|
||||
} else if err != nil {
|
||||
return err
|
||||
}
|
||||
if info.Mode()&os.ModeSymlink != 0 {
|
||||
panic("bug: attempting to version a symlink")
|
||||
}
|
||||
|
||||
l.Debugln("archiving", filePath)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user