From 013d810678d75bcb7570f1f8ccb1d2fa74ee7284 Mon Sep 17 00:00:00 2001 From: Jacky Date: Tue, 30 Jul 2024 14:40:52 +0800 Subject: [PATCH] fix: uncontrolled data used in path expression --- api/certificate/certificate.go | 7 +++++-- api/config/modify.go | 2 +- app/src/version.json | 2 +- internal/cert/cert_info.go | 6 ++++++ internal/cert/payload.go | 6 +++--- internal/chatbot/context.go | 5 +++++ internal/helper/tar.go | 3 +++ 7 files changed, 24 insertions(+), 7 deletions(-) diff --git a/api/certificate/certificate.go b/api/certificate/certificate.go index 99af9be7..a2dd0c68 100644 --- a/api/certificate/certificate.go +++ b/api/certificate/certificate.go @@ -4,6 +4,7 @@ import ( "github.com/0xJacky/Nginx-UI/api" "github.com/0xJacky/Nginx-UI/internal/cert" "github.com/0xJacky/Nginx-UI/internal/cosy" + "github.com/0xJacky/Nginx-UI/internal/helper" "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/0xJacky/Nginx-UI/internal/notification" "github.com/0xJacky/Nginx-UI/model" @@ -25,7 +26,8 @@ type APICertificate struct { func Transformer(certModel *model.Cert) (certificate *APICertificate) { var sslCertificationBytes, sslCertificationKeyBytes []byte var certificateInfo *cert.Info - if certModel.SSLCertificatePath != "" { + if certModel.SSLCertificatePath != "" && + helper.IsUnderDirectory(certModel.SSLCertificatePath, nginx.GetConfPath()) { if _, err := os.Stat(certModel.SSLCertificatePath); err == nil { sslCertificationBytes, _ = os.ReadFile(certModel.SSLCertificatePath) if !cert.IsCertificate(string(sslCertificationBytes)) { @@ -36,7 +38,8 @@ func Transformer(certModel *model.Cert) (certificate *APICertificate) { certificateInfo, _ = cert.GetCertInfo(certModel.SSLCertificatePath) } - if certModel.SSLCertificateKeyPath != "" { + if certModel.SSLCertificateKeyPath != "" && + helper.IsUnderDirectory(certModel.SSLCertificateKeyPath, nginx.GetConfPath()) { if _, err := os.Stat(certModel.SSLCertificateKeyPath); err == nil { sslCertificationKeyBytes, _ = os.ReadFile(certModel.SSLCertificateKeyPath) if !cert.IsPrivateKey(string(sslCertificationKeyBytes)) { diff --git a/api/config/modify.go b/api/config/modify.go index dec01f86..5631a260 100644 --- a/api/config/modify.go +++ b/api/config/modify.go @@ -47,7 +47,7 @@ func EditConfig(c *gin.Context) { return } - if _, err := os.Stat(path); os.IsNotExist(err) { + if !helper.FileExists(path) { c.JSON(http.StatusNotFound, gin.H{ "message": "file not found", }) diff --git a/app/src/version.json b/app/src/version.json index fbc4bfe3..d8879cdb 100644 --- a/app/src/version.json +++ b/app/src/version.json @@ -1 +1 @@ -{"version":"2.0.0-beta.29","build_id":152,"total_build":356} \ No newline at end of file +{"version":"2.0.0-beta.29","build_id":154,"total_build":358,"status_hash":"4f53cda18c2baa0c0354bb5f9a3ecbe5ed12ab4d8e11ba873c2f11161202b945"} \ No newline at end of file diff --git a/internal/cert/cert_info.go b/internal/cert/cert_info.go index 75402ac7..9ad105d6 100644 --- a/internal/cert/cert_info.go +++ b/internal/cert/cert_info.go @@ -3,6 +3,8 @@ package cert import ( "crypto/x509" "encoding/pem" + "github.com/0xJacky/Nginx-UI/internal/helper" + "github.com/0xJacky/Nginx-UI/internal/nginx" "github.com/pkg/errors" "os" "time" @@ -16,6 +18,10 @@ type Info struct { } func GetCertInfo(sslCertificatePath string) (info *Info, err error) { + if !helper.IsUnderDirectory(sslCertificatePath, nginx.GetConfPath()) { + err = errors.New("ssl certificate path is not under the nginx conf path") + return + } certData, err := os.ReadFile(sslCertificatePath) if err != nil { err = errors.Wrap(err, "error read certificate") diff --git a/internal/cert/payload.go b/internal/cert/payload.go index 51712340..3f27a6bb 100644 --- a/internal/cert/payload.go +++ b/internal/cert/payload.go @@ -53,15 +53,15 @@ func (c *ConfigPayload) GetKeyType() certcrypto.KeyType { func (c *ConfigPayload) mkCertificateDir() (err error) { dir := c.getCertificateDirPath() - if _, err = os.Stat(dir); os.IsNotExist(err) { + if !helper.FileExists(dir) { err = os.MkdirAll(dir, 0755) if err == nil { return nil } } - // For windows, replace # with * (issue #403) - c.CertificateDir = strings.ReplaceAll(c.CertificateDir, "#", "*") + // For windows, replace * with # (issue #403) + c.CertificateDir = strings.ReplaceAll(c.CertificateDir, "*", "#") if _, err = os.Stat(c.CertificateDir); os.IsNotExist(err) { err = os.MkdirAll(c.CertificateDir, 0755) if err == nil { diff --git a/internal/chatbot/context.go b/internal/chatbot/context.go index a2739d80..f2703815 100644 --- a/internal/chatbot/context.go +++ b/internal/chatbot/context.go @@ -33,6 +33,11 @@ func (c *includeContext) extractIncludes(filename string) { return } + if !helper.IsUnderDirectory(filename, nginx.GetConfPath()) { + logger.Error("File is not under the nginx conf path: ", filename) + return + } + // Read the file content content, err := os.ReadFile(filename) if err != nil { diff --git a/internal/helper/tar.go b/internal/helper/tar.go index 2b07da1d..1b8b65c7 100644 --- a/internal/helper/tar.go +++ b/internal/helper/tar.go @@ -7,6 +7,7 @@ import ( "io" "os" "path/filepath" + "strings" ) func UnTar(dst, src string) (err error) { @@ -37,6 +38,8 @@ func UnTar(dst, src string) (err error) { return errors.Wrap(err, "unTar tr.Next() error") case hdr == nil: return + case strings.Contains(hdr.Name, ".."): + return } dstFileDir := filepath.Join(dst, hdr.Name)