fixing sec issues
Some checks failed
CloudSave/pipeline/head There was a failure building this commit
Some checks failed
CloudSave/pipeline/head There was a failure building this commit
This commit is contained in:
@@ -63,9 +63,15 @@ func (p *SyncCmd) Execute(_ context.Context, f *flag.FlagSet, _ ...interface{})
|
||||
|
||||
pg := progressbar.New(-1)
|
||||
destroyPg := func() {
|
||||
pg.Finish()
|
||||
pg.Clear()
|
||||
pg.Close()
|
||||
if err := pg.Finish(); err != nil {
|
||||
slog.Error("failed to finish progressbar", "err", err)
|
||||
}
|
||||
if err := pg.Clear(); err != nil {
|
||||
slog.Error("failed to clear progressbar", "err", err)
|
||||
}
|
||||
if err := pg.Close(); err != nil {
|
||||
slog.Error("failed to close progressbar", "err", err)
|
||||
}
|
||||
}
|
||||
|
||||
pg.Describe(fmt.Sprintf("[%s] Checking status...", g.Name))
|
||||
|
||||
@@ -30,7 +30,7 @@ func main() {
|
||||
}
|
||||
|
||||
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())
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func save(store map[string]credential) error {
|
||||
Store: store,
|
||||
}
|
||||
|
||||
f, err := os.OpenFile(filepath.Join(datastorePath, "credential.json"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0740)
|
||||
f, err := os.OpenFile(filepath.Join(datastorePath, "credential.json"), os.O_CREATE|os.O_TRUNC|os.O_WRONLY, 0600)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to open datastore: %w", err)
|
||||
}
|
||||
|
||||
@@ -76,6 +76,7 @@ func NewServer(documentRoot string, srv *data.Service, creds map[string]string,
|
||||
s.Server = &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", port),
|
||||
Handler: router,
|
||||
ReadHeaderTimeout: 2,
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -66,7 +66,9 @@ func run(updateChan <-chan struct{}) {
|
||||
for {
|
||||
<-updateChan
|
||||
if r, ok := repo.(*repository.EagerRepository); ok {
|
||||
r.Reload()
|
||||
if err := r.Reload(); err != nil {
|
||||
fatal("failed to reload data: "+err.Error(), 1)
|
||||
}
|
||||
}
|
||||
h, err := htpasswd.Open(filepath.Join(documentRoot, ".htpasswd"))
|
||||
if err != nil {
|
||||
|
||||
@@ -74,13 +74,19 @@ var (
|
||||
// NewServer start the http server
|
||||
func NewServer(c config.Configuration) *HTTPServer {
|
||||
dashboardTemplate := template.New("dashboard")
|
||||
dashboardTemplate.Parse(DashboardHTMLPage)
|
||||
if _, err := dashboardTemplate.Parse(DashboardHTMLPage); err != nil {
|
||||
panic("failed to load template 'dashboard': " + err.Error())
|
||||
}
|
||||
|
||||
detailledTemplate := template.New("detailled")
|
||||
detailledTemplate.Parse(DetailledHTMLPage)
|
||||
if _, err := detailledTemplate.Parse(DetailledHTMLPage); err != nil {
|
||||
panic("failed to load template 'detailled': " + err.Error())
|
||||
}
|
||||
|
||||
systemTemplate := template.New("system")
|
||||
systemTemplate.Parse(SystemHTMLPage)
|
||||
if _, err := systemTemplate.Parse(SystemHTMLPage); err != nil {
|
||||
panic("failed to load template 'system': " + err.Error())
|
||||
}
|
||||
|
||||
s := &HTTPServer{
|
||||
Config: c,
|
||||
@@ -101,6 +107,7 @@ func NewServer(c config.Configuration) *HTTPServer {
|
||||
s.Server = &http.Server{
|
||||
Addr: fmt.Sprintf(":%d", c.Server.Port),
|
||||
Handler: router,
|
||||
ReadHeaderTimeout: 2,
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
@@ -6,7 +6,10 @@ pipeline {
|
||||
steps {
|
||||
sh '''
|
||||
go install github.com/securego/gosec/v2/cmd/gosec@v2.22.8
|
||||
/var/lib/jenkins/go/bin/gosec ./...
|
||||
go install honnef.co/go/tools/cmd/staticcheck@v0.6.1
|
||||
|
||||
/var/lib/jenkins/go/bin/staticcheck ./...
|
||||
/var/lib/jenkins/go/bin/gosec -exclude="G401,G501,G103" ./...
|
||||
'''
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -5,10 +5,17 @@ import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"io"
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
const (
|
||||
// Tune these to your app’s 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")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user