When tar extraction fails, delete extraction folder

This commit is contained in:
tutman96 2025-01-04 21:43:37 +00:00
parent 2ffb463829
commit 5a05719106
2 changed files with 25 additions and 13 deletions

View File

@ -19,10 +19,10 @@ func init() {
_ = os.MkdirAll(pluginsExtractsFolder, 0755) _ = os.MkdirAll(pluginsExtractsFolder, 0755)
} }
func extractPlugin(filePath string) (*string, error) { func extractPlugin(filePath string) (string, error) {
file, err := os.Open(filePath) file, err := os.Open(filePath)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to open file for extraction: %v", err) return "", fmt.Errorf("failed to open file for extraction: %v", err)
} }
defer file.Close() defer file.Close()
@ -31,7 +31,7 @@ func extractPlugin(filePath string) (*string, error) {
if strings.HasSuffix(filePath, ".gz") { if strings.HasSuffix(filePath, ".gz") {
gzipReader, err := gzip.NewReader(file) gzipReader, err := gzip.NewReader(file)
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create gzip reader: %v", err) return "", fmt.Errorf("failed to create gzip reader: %v", err)
} }
defer gzipReader.Close() defer gzipReader.Close()
reader = gzipReader reader = gzipReader
@ -39,9 +39,21 @@ func extractPlugin(filePath string) (*string, error) {
destinationFolder := path.Join(pluginsExtractsFolder, uuid.New().String()) destinationFolder := path.Join(pluginsExtractsFolder, uuid.New().String())
if err := os.MkdirAll(destinationFolder, 0755); err != nil { if err := os.MkdirAll(destinationFolder, 0755); err != nil {
return nil, fmt.Errorf("failed to create extracts folder: %v", err) return "", fmt.Errorf("failed to create extracts folder: %v", err)
} }
if err := extractTarball(reader, destinationFolder); err != nil {
if err := os.RemoveAll(destinationFolder); err != nil {
return "", fmt.Errorf("failed to remove failed extraction folder: %v", err)
}
return "", fmt.Errorf("failed to extract tarball: %v", err)
}
return destinationFolder, nil
}
func extractTarball(reader io.Reader, destinationFolder string) error {
tarReader := tar.NewReader(reader) tarReader := tar.NewReader(reader)
for { for {
@ -50,34 +62,34 @@ func extractPlugin(filePath string) (*string, error) {
break break
} }
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to read tar header: %v", err) return fmt.Errorf("failed to read tar header: %v", err)
} }
// Prevent path traversal attacks // Prevent path traversal attacks
targetPath := filepath.Join(destinationFolder, header.Name) targetPath := filepath.Join(destinationFolder, header.Name)
if !strings.HasPrefix(targetPath, filepath.Clean(destinationFolder)+string(os.PathSeparator)) { if !strings.HasPrefix(targetPath, filepath.Clean(destinationFolder)+string(os.PathSeparator)) {
return nil, fmt.Errorf("tar file contains illegal path: %s", header.Name) return fmt.Errorf("tar file contains illegal path: %s", header.Name)
} }
switch header.Typeflag { switch header.Typeflag {
case tar.TypeDir: case tar.TypeDir:
if err := os.MkdirAll(targetPath, os.FileMode(header.Mode)); err != nil { if err := os.MkdirAll(targetPath, os.FileMode(header.Mode)); err != nil {
return nil, fmt.Errorf("failed to create directory: %v", err) return fmt.Errorf("failed to create directory: %v", err)
} }
case tar.TypeReg: case tar.TypeReg:
file, err := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY, os.FileMode(header.Mode)) file, err := os.OpenFile(targetPath, os.O_CREATE|os.O_WRONLY, os.FileMode(header.Mode))
if err != nil { if err != nil {
return nil, fmt.Errorf("failed to create file: %v", err) return fmt.Errorf("failed to create file: %v", err)
} }
defer file.Close() defer file.Close()
if _, err := io.Copy(file, tarReader); err != nil { if _, err := io.Copy(file, tarReader); err != nil {
return nil, fmt.Errorf("failed to extract file: %v", err) return fmt.Errorf("failed to extract file: %v", err)
} }
default: default:
return nil, fmt.Errorf("unsupported tar entry type: %v", header.Typeflag) return fmt.Errorf("unsupported tar entry type: %v", header.Typeflag)
} }
} }
return &destinationFolder, nil return nil
} }

View File

@ -89,7 +89,7 @@ func RpcPluginExtract(filename string) (*PluginManifest, error) {
return nil, fmt.Errorf("failed to delete uploaded file: %v", err) return nil, fmt.Errorf("failed to delete uploaded file: %v", err)
} }
manifest, err := readManifest(*extractFolder) manifest, err := readManifest(extractFolder)
if err != nil { if err != nil {
return nil, err return nil, err
} }
@ -109,7 +109,7 @@ func RpcPluginExtract(filename string) (*PluginManifest, error) {
return nil, fmt.Errorf("this version has already been uploaded: %s", manifest.Version) return nil, fmt.Errorf("this version has already been uploaded: %s", manifest.Version)
} }
install.ExtractedVersions[manifest.Version] = *extractFolder install.ExtractedVersions[manifest.Version] = extractFolder
pluginDatabase.Plugins[manifest.Name] = install pluginDatabase.Plugins[manifest.Name] = install
if err := pluginDatabase.Save(); err != nil { if err := pluginDatabase.Save(); err != nil {