Sanitize path api params

- fix path traversal complains by CodeQL
This commit is contained in:
André Roth
2024-10-10 18:54:03 +02:00
parent ce2966e547
commit 57639c4adf
4 changed files with 30 additions and 15 deletions

View File

@@ -8,6 +8,7 @@ import (
"strings"
"sync"
"github.com/aptly-dev/aptly/utils"
"github.com/gin-gonic/gin"
"github.com/saracen/walker"
)
@@ -72,7 +73,7 @@ func apiFilesUpload(c *gin.Context) {
return
}
path := filepath.Join(context.UploadPath(), c.Params.ByName("dir"))
path := filepath.Join(context.UploadPath(), utils.PathSanitize(c.Params.ByName("dir")))
err := os.MkdirAll(path, 0777)
if err != nil {
@@ -128,7 +129,7 @@ func apiFilesListFiles(c *gin.Context) {
list := []string{}
listLock := &sync.Mutex{}
root := filepath.Join(context.UploadPath(), c.Params.ByName("dir"))
root := filepath.Join(context.UploadPath(), utils.PathSanitize(c.Params.ByName("dir")))
err := filepath.Walk(root, func(path string, _ os.FileInfo, err error) error {
if err != nil {
@@ -164,7 +165,7 @@ func apiFilesDeleteDir(c *gin.Context) {
return
}
err := os.RemoveAll(filepath.Join(context.UploadPath(), c.Params.ByName("dir")))
err := os.RemoveAll(filepath.Join(context.UploadPath(), utils.PathSanitize(c.Params.ByName("dir"))))
if err != nil {
AbortWithJSONError(c, 500, err)
return
@@ -179,12 +180,14 @@ func apiFilesDeleteFile(c *gin.Context) {
return
}
if !verifyPath(c.Params.ByName("name")) {
dir := utils.PathSanitize(c.Params.ByName("dir"))
name := utils.PathSanitize(c.Params.ByName("name"))
if !verifyPath(name) {
AbortWithJSONError(c, 400, fmt.Errorf("wrong file"))
return
}
err := os.Remove(filepath.Join(context.UploadPath(), c.Params.ByName("dir"), c.Params.ByName("name")))
err := os.Remove(filepath.Join(context.UploadPath(), dir, name))
if err != nil {
if err1, ok := err.(*os.PathError); !ok || !os.IsNotExist(err1.Err) {
AbortWithJSONError(c, 500, err)

View File

@@ -9,6 +9,7 @@ import (
"github.com/aptly-dev/aptly/deb"
"github.com/aptly-dev/aptly/pgp"
"github.com/aptly-dev/aptly/task"
"github.com/aptly-dev/aptly/utils"
"github.com/gin-gonic/gin"
)
@@ -43,9 +44,10 @@ func getSigner(options *SigningOptions) (pgp.Signer, error) {
return signer, nil
}
// Replace '_' with '/' and double '__' with single '_'
func parseEscapedPath(path string) string {
// Replace '_' with '/' and double '__' with single '_', PathSanitize
func slashEscape(path string) string {
result := strings.Replace(strings.Replace(path, "_", "/", -1), "//", "_", -1)
result = utils.PathSanitize(result)
if result == "" {
result = "."
}
@@ -86,7 +88,7 @@ func apiPublishList(c *gin.Context) {
// POST /publish/:prefix
func apiPublishRepoOrSnapshot(c *gin.Context) {
param := parseEscapedPath(c.Params.ByName("prefix"))
param := slashEscape(c.Params.ByName("prefix"))
storage, prefix := deb.ParsePrefix(param)
var b struct {
@@ -113,6 +115,8 @@ func apiPublishRepoOrSnapshot(c *gin.Context) {
return
}
b.Distribution = utils.PathSanitize(b.Distribution)
signer, err := getSigner(&b.Signing)
if err != nil {
AbortWithJSONError(c, 500, fmt.Errorf("unable to initialize GPG signer: %s", err))
@@ -248,9 +252,9 @@ func apiPublishRepoOrSnapshot(c *gin.Context) {
// PUT /publish/:prefix/:distribution
func apiPublishUpdateSwitch(c *gin.Context) {
param := parseEscapedPath(c.Params.ByName("prefix"))
param := slashEscape(c.Params.ByName("prefix"))
storage, prefix := deb.ParsePrefix(param)
distribution := c.Params.ByName("distribution")
distribution := utils.PathSanitize(c.Params.ByName("distribution"))
var b struct {
ForceOverwrite bool
@@ -373,7 +377,7 @@ func apiPublishDrop(c *gin.Context) {
force := c.Request.URL.Query().Get("force") == "1"
skipCleanup := c.Request.URL.Query().Get("SkipCleanup") == "1"
param := parseEscapedPath(c.Params.ByName("prefix"))
param := slashEscape(c.Params.ByName("prefix"))
storage, prefix := deb.ParsePrefix(param)
distribution := c.Params.ByName("distribution")

View File

@@ -343,8 +343,8 @@ func apiReposPackageFromDir(c *gin.Context) {
return
}
dirParam := c.Params.ByName("dir")
fileParam := c.Params.ByName("file")
dirParam := utils.PathSanitize(c.Params.ByName("dir"))
fileParam := utils.PathSanitize(c.Params.ByName("file"))
if fileParam != "" && !verifyPath(fileParam) {
AbortWithJSONError(c, 400, fmt.Errorf("wrong file"))
return
@@ -620,8 +620,8 @@ func apiReposIncludePackageFromDir(c *gin.Context) {
var sources []string
var taskName string
dirParam := c.Params.ByName("dir")
fileParam := c.Params.ByName("file")
dirParam := utils.PathSanitize(c.Params.ByName("dir"))
fileParam := utils.PathSanitize(c.Params.ByName("file"))
if fileParam != "" && !verifyPath(fileParam) {
AbortWithJSONError(c, 400, fmt.Errorf("wrong file"))
return