Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 4 additions & 6 deletions internal/engine/auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -325,18 +325,16 @@ func splitAuthParams(value string) []string {
return params
}

// SIP Digest authentication (RFC 3261/7616) requires MD5; not password storage.
//
// codeql[go/weak-sensitive-data-hashing]
func md5Hex(value string) string {
// SIP Digest authentication (RFC 3261/7616); not password storage.
// codeql[go/weak-sensitive-data-hashing]
sum := md5.Sum([]byte(value))
return hex.EncodeToString(sum[:])
}

// SIP Digest authentication (RFC 3261/7616) requires SHA-256; not password storage.
//
// codeql[go/weak-sensitive-data-hashing]
func sha256Hex(value string) string {
// SIP Digest authentication (RFC 3261/7616); not password storage.
// codeql[go/weak-sensitive-data-hashing]
sum := sha256.Sum256([]byte(value))
return hex.EncodeToString(sum[:])
}
Expand Down
24 changes: 24 additions & 0 deletions internal/safepath/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,30 @@ func ReadDir(baseRoot, dir string) ([]os.DirEntry, error) {
return os.ReadDir(abs)
}

// EnsureDirUnder creates dir when it resolves inside root.
func EnsureDirUnder(root, dir string, perm os.FileMode) error {
abs, err := resolveUnderRoot(root, dir)
if err != nil {
return err
}
// codeql[go/path-injection]
return os.MkdirAll(abs, perm)
}

// RenameUnder renames src to dst when both paths resolve inside root.
func RenameUnder(root, src, dst string) error {
srcAbs, err := resolveUnderRoot(root, src)
if err != nil {
return err
}
dstAbs, err := resolveUnderRoot(root, dst)
if err != nil {
return err
}
// codeql[go/path-injection]
return os.Rename(srcAbs, dstAbs)
}

func resolveUnderRoot(root, target string) (string, error) {
rootAbs, err := filepath.Abs(filepath.Clean(root))
if err != nil {
Expand Down
10 changes: 1 addition & 9 deletions internal/uistore/layout.go
Original file line number Diff line number Diff line change
Expand Up @@ -101,13 +101,5 @@ func (l Layout) JobArtifactDir(jobID string) (string, error) {
if !isSafeID(jobID) {
return "", fmt.Errorf("uistore: invalid job id %q", jobID)
}
base := filepath.Clean(l.JobsArtifactsDir())
p, err := safepath.Join(base, jobID)
if err != nil {
return "", fmt.Errorf("uistore: invalid job id %q", jobID)
}
if err := os.MkdirAll(p, 0o750); err != nil {
return "", err
}
return p, nil
return safepath.EnsureJobArtifactsDir(l.Root, jobID, 0o750)
}
6 changes: 4 additions & 2 deletions internal/uistore/store.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,8 @@ import (
"strings"
"sync"
"time"

"github.com/sipcapture/gossipper/internal/safepath"
)

// ErrNotFound is returned when a profile / scenario / media asset is missing.
Expand Down Expand Up @@ -102,7 +104,7 @@ func (s *Store) writeAtomic(targetPath string, data []byte, perm os.FileMode) er
if err := ensurePathWithin(s.layout.Root, targetPath); err != nil {
return err
}
if err := os.MkdirAll(filepath.Dir(targetPath), 0o750); err != nil {
if err := safepath.EnsureDirUnder(s.layout.Root, filepath.Dir(targetPath), 0o750); err != nil {
return err
}
tmp, err := os.CreateTemp(s.layout.TempDir(), "uistore-*.tmp")
Expand All @@ -129,7 +131,7 @@ func (s *Store) writeAtomic(targetPath string, data []byte, perm os.FileMode) er
cleanup()
return err
}
if err := os.Rename(tmpPath, targetPath); err != nil {
if err := safepath.RenameUnder(s.layout.Root, tmpPath, targetPath); err != nil {
cleanup()
return err
}
Expand Down
Loading