lua: prevent configuration files from being executed as scripts

This commit is contained in:
Meo597
2026-10-15 01:34:40 +08:00
parent e04191e65b
commit 796bbd763a
4 changed files with 267 additions and 10 deletions
+50
View File
@@ -0,0 +1,50 @@
package platform
import (
"io"
"os"
"path/filepath"
)
type configFile struct {
path string
info os.FileInfo
}
var configFiles []configFile
// ReadConfigFile reads a config source and records local regular files.
func ReadConfigFile(file *os.File) ([]byte, error) {
info, err := file.Stat()
if err != nil {
return nil, err
}
path := ""
if info.Mode().IsRegular() && file != os.Stdin {
path, err = filepath.Abs(file.Name())
if err != nil {
return nil, err
}
path, err = filepath.EvalSymlinks(path)
if err != nil {
return nil, err
}
}
data, err := io.ReadAll(file)
if err != nil {
return nil, err
}
if info.Mode().IsRegular() {
configFiles = append(configFiles, configFile{path: path, info: info})
}
return data, nil
}
func isConfigFile(path string, info os.FileInfo) bool {
for _, file := range configFiles {
if file.path == path || os.SameFile(file.info, info) {
return true
}
}
return false
}
+15 -8
View File
@@ -113,11 +113,18 @@ func ResolveLuaFile(path string) (string, error) {
}
}
}
path, err := resolveFile(paths)
path, info, err := resolveFile(paths)
if err != nil {
return "", err
}
return resolveLuaTarget(path)
path, err = resolveLuaTarget(path)
if err != nil {
return "", err
}
if isConfigFile(path, info) {
return "", fmt.Errorf("Lua file was loaded as a configuration file: %s", path)
}
return path, nil
}
func resolveLuaTarget(path string) (string, error) {
@@ -131,12 +138,12 @@ func resolveLuaTarget(path string) (string, error) {
return path, nil
}
func resolveFile(paths []string) (string, error) {
func resolveFile(paths []string) (string, os.FileInfo, error) {
var tried []string
for _, path := range paths {
path, err := filepath.Abs(path)
if err != nil {
return "", fmt.Errorf("failed to resolve file path: %w", err)
return "", nil, fmt.Errorf("failed to resolve file path: %w", err)
}
tried = append(tried, path)
info, err := os.Stat(path)
@@ -144,12 +151,12 @@ func resolveFile(paths []string) (string, error) {
continue
}
if err != nil {
return "", fmt.Errorf("failed to inspect file %q: %w", path, err)
return "", nil, fmt.Errorf("failed to inspect file %q: %w", path, err)
}
if !info.Mode().IsRegular() {
return "", fmt.Errorf("file is not a regular file: %s", path)
return "", nil, fmt.Errorf("file is not a regular file: %s", path)
}
return path, nil
return path, info, nil
}
return "", fmt.Errorf("file not found; tried %q: %w", tried, os.ErrNotExist)
return "", nil, fmt.Errorf("file not found; tried %q: %w", tried, os.ErrNotExist)
}