fixing sec issues
Some checks failed
CloudSave/pipeline/head There was a failure building this commit

This commit is contained in:
2025-09-07 01:14:19 +02:00
parent b3232e79d5
commit af11e843a4
13 changed files with 88 additions and 37 deletions

View File

@@ -258,7 +258,7 @@ func (l Service) PullCurrent(id, path string, cli *client.Client) error {
}
}
if err := os.MkdirAll(path, 0740); err != nil {
if err := os.MkdirAll(path, 0600); err != nil {
return fmt.Errorf("failed to create destination directory: %w", err)
}

View File

@@ -9,6 +9,7 @@ import (
"errors"
"fmt"
"io"
"log/slog"
"mime/multipart"
"net/http"
"net/url"
@@ -220,7 +221,7 @@ func (c *Client) Pull(gameID, archivePath string) error {
req.SetBasicAuth(c.username, c.password)
f, err := os.OpenFile(archivePath+".part", os.O_CREATE|os.O_WRONLY, 0740)
f, err := os.OpenFile(archivePath+".part", os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
@@ -275,20 +276,24 @@ func (c *Client) PullBackup(gameID, uuid, archivePath string) error {
req.SetBasicAuth(c.username, c.password)
f, err := os.OpenFile(archivePath+".part", os.O_CREATE|os.O_WRONLY, 0740)
f, err := os.OpenFile(archivePath+".part", os.O_CREATE|os.O_WRONLY, 0600)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
res, err := cli.Do(req)
if err != nil {
f.Close()
if err := f.Close(); err != nil {
slog.Error("failed to close file", "err", err)
}
return fmt.Errorf("cannot connect to remote: %w", err)
}
defer res.Body.Close()
if res.StatusCode != http.StatusOK {
f.Close()
if err := f.Close(); err != nil {
slog.Error("failed to close file", "err", err)
}
return fmt.Errorf("cannot connect to remote: server return code: %s", res.Status)
}
@@ -299,10 +304,14 @@ func (c *Client) PullBackup(gameID, uuid, archivePath string) error {
defer bar.Close()
if _, err := io.Copy(io.MultiWriter(f, bar), res.Body); err != nil {
f.Close()
if err := f.Close(); err != nil {
slog.Error("failed to close file", "err", err)
}
return fmt.Errorf("an error occured while copying the file from the remote: %w", err)
}
f.Close()
if err := f.Close(); err != nil {
slog.Error("failed to close file", "err", err)
}
if err := os.Rename(archivePath+".part", archivePath); err != nil {
return fmt.Errorf("failed to move temporary data: %w", err)
@@ -431,9 +440,15 @@ func (c *Client) push(u, archivePath string, m repository.Metadata) error {
return fmt.Errorf("failed to copy data: %w", err)
}
writer.WriteField("name", m.Name)
writer.WriteField("version", strconv.Itoa(m.Version))
writer.WriteField("date", m.Date.Format(time.RFC3339))
if err := writer.WriteField("name", m.Name); err != nil {
return err
}
if err := writer.WriteField("version", strconv.Itoa(m.Version)); err != nil {
return err
}
if err := writer.WriteField("date", m.Date.Format(time.RFC3339)); err != nil {
return err
}
if err := writer.Close(); err != nil {
return err

View File

@@ -32,7 +32,7 @@ func init() {
}
datastorepath = filepath.Join(roaming, "cloudsave", "data")
err = os.MkdirAll(datastorepath, 0740)
err = os.MkdirAll(datastorepath, 0600)
if err != nil {
panic("cannot make the datastore:" + err.Error())
}
@@ -62,7 +62,7 @@ func Set(gameID, url string) error {
URL: url,
}
f, err := os.OpenFile(filepath.Join(datastorepath, gameID, "remote.json"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0740)
f, err := os.OpenFile(filepath.Join(datastorepath, gameID, "remote.json"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600)
if err != nil {
return err
}

View File

@@ -117,7 +117,7 @@ func (bi BackupIdentifier) Key() string {
func NewLazyRepository(dataRootPath string) (*LazyRepository, error) {
if m, err := os.Stat(dataRootPath); err != nil {
if errors.Is(err, os.ErrNotExist) {
if err := os.MkdirAll(dataRootPath, 0740); err != nil {
if err := os.MkdirAll(dataRootPath, 0600); err != nil {
return nil, fmt.Errorf("failed to make the directory: %w", err)
}
} else {
@@ -137,8 +137,8 @@ func NewLazyRepository(dataRootPath string) (*LazyRepository, error) {
func (l *LazyRepository) Mkdir(id Identifier) error {
path := l.DataPath(id)
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
slog.Debug("making directory", "path", path, "id", id, "perm", "0740")
return os.MkdirAll(path, 0740)
slog.Debug("making directory", "path", path, "id", id, "perm", "0600")
return os.MkdirAll(path, 0600)
}
return nil
}
@@ -182,7 +182,7 @@ func (l *LazyRepository) WriteBlob(ID Identifier) (io.Writer, error) {
path := l.DataPath(ID)
slog.Debug("loading write buffer...", "id", ID)
dst, err := os.OpenFile(filepath.Join(path, "data.tar.gz"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0740)
dst, err := os.OpenFile(filepath.Join(path, "data.tar.gz"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
return nil, fmt.Errorf("failed to open destination file: %w", err)
}
@@ -195,7 +195,7 @@ func (l *LazyRepository) WriteMetadata(id GameIdentifier, m Metadata) error {
path := l.DataPath(id)
slog.Debug("writing metadata", "id", id, "metadata", m)
dst, err := os.OpenFile(filepath.Join(path, "metadata.json"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0740)
dst, err := os.OpenFile(filepath.Join(path, "metadata.json"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
return fmt.Errorf("failed to open destination file: %w", err)
}
@@ -292,7 +292,7 @@ func (l *LazyRepository) ResetLastScan(id GameIdentifier) error {
path := l.DataPath(id)
slog.Debug("resetting last scan datetime for", "id", id)
f, err := os.OpenFile(filepath.Join(path, ".last_run"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0740)
f, err := os.OpenFile(filepath.Join(path, ".last_run"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
return fmt.Errorf("failed to open file: %w", err)
}
@@ -325,7 +325,7 @@ func (l *LazyRepository) ReadBlob(id Identifier) (io.ReadSeekCloser, error) {
func (l *LazyRepository) SetRemote(id GameIdentifier, url string) error {
path := l.DataPath(id)
src, err := os.OpenFile(filepath.Join(path, "remote.json"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0740)
src, err := os.OpenFile(filepath.Join(path, "remote.json"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
if err != nil {
return fmt.Errorf("failed to open remote description: %w", err)
}

View File

@@ -5,10 +5,17 @@ import (
"compress/gzip"
"fmt"
"io"
"log/slog"
"os"
"path/filepath"
)
const (
// Tune these to your apps needs
maxCompressedUpload = 500 << 20 // 500 MiB compressed
maxUncompressedOutput = 1000 << 20 // 100 MiB after inflate
)
func Untar(file io.Reader, path string) error {
gzr, err := gzip.NewReader(file)
if err != nil {
@@ -49,26 +56,35 @@ func Untar(file io.Reader, path string) error {
// if its a dir and it doesn't exist create it
case tar.TypeDir:
if _, err := os.Stat(target); err != nil {
if err := os.MkdirAll(target, 0755); err != nil {
if err := os.MkdirAll(target, 0600); err != nil {
return err
}
}
// if it's a file create it
case tar.TypeReg:
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, os.FileMode(header.Mode))
f, err := os.OpenFile(target, os.O_CREATE|os.O_RDWR, header.FileInfo().Mode())
if err != nil {
return err
}
limited := &io.LimitedReader{R: gzr, N: maxUncompressedOutput}
// copy over contents
if _, err := io.Copy(f, tr); err != nil {
if _, err := io.Copy(f, limited); err != nil {
return err
}
// manually close here after each file operation; defering would cause each file close
// to wait until all operations have completed.
f.Close()
if err := f.Close(); err != nil {
slog.Error("failed to close file", "err", err)
}
if limited.N == 0 {
// Limit exhausted → likely bomb
return fmt.Errorf("payload too large after decompression")
}
}
}
}

View File

@@ -14,6 +14,7 @@ func FileMD5(fp string) (string, error) {
}
defer f.Close()
hasher := md5.New()
if _, err := io.Copy(hasher, f); err != nil {
return "", err