mirror of
https://github.com/superseriousbusiness/gotosocial.git
synced 2025-10-29 08:42:26 -05:00
[security] Implement allowFiles fs for better isolation of ffmpeg / ffprobe (#3251)
* [chore] Implement readOneFile fs * further isolation * remove fmt call * tweaks
This commit is contained in:
parent
e10aa76612
commit
cd93a5baf3
2 changed files with 104 additions and 31 deletions
|
|
@ -22,13 +22,60 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"path"
|
||||
|
||||
"codeberg.org/gruf/go-bytesize"
|
||||
"codeberg.org/gruf/go-iotools"
|
||||
"codeberg.org/gruf/go-mimetypes"
|
||||
)
|
||||
|
||||
// file represents one file
|
||||
// with the given flag and perms.
|
||||
type file struct {
|
||||
abs string
|
||||
flag int
|
||||
perm os.FileMode
|
||||
}
|
||||
|
||||
// allowFiles implements fs.FS to allow
|
||||
// access to a specified slice of files.
|
||||
type allowFiles []file
|
||||
|
||||
// Open implements fs.FS.
|
||||
func (af allowFiles) Open(name string) (fs.File, error) {
|
||||
for _, file := range af {
|
||||
var (
|
||||
abs = file.abs
|
||||
flag = file.flag
|
||||
perm = file.perm
|
||||
)
|
||||
|
||||
// Allowed to open file
|
||||
// at absolute path.
|
||||
if name == file.abs {
|
||||
return os.OpenFile(abs, flag, perm)
|
||||
}
|
||||
|
||||
// Check for other valid reads.
|
||||
thisDir, thisFile := path.Split(file.abs)
|
||||
|
||||
// Allowed to read directory itself.
|
||||
if name == thisDir || name == "." {
|
||||
return os.OpenFile(thisDir, flag, perm)
|
||||
}
|
||||
|
||||
// Allowed to read file
|
||||
// itself (at relative path).
|
||||
if name == thisFile {
|
||||
return os.OpenFile(abs, flag, perm)
|
||||
}
|
||||
}
|
||||
|
||||
return nil, os.ErrPermission
|
||||
}
|
||||
|
||||
// getExtension splits file extension from path.
|
||||
func getExtension(path string) string {
|
||||
for i := len(path) - 1; i >= 0 && path[i] != '/'; i-- {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue