mirror of
https://github.com/MetaCubeX/mihomo.git
synced 2025-12-19 16:30:07 +08:00
chore: better path checks
This commit is contained in:
parent
cad26ac6a8
commit
b4fe669848
@ -136,7 +136,11 @@ func NewSsh(option SshOption) (*Ssh, error) {
|
|||||||
if strings.Contains(option.PrivateKey, "PRIVATE KEY") {
|
if strings.Contains(option.PrivateKey, "PRIVATE KEY") {
|
||||||
b = []byte(option.PrivateKey)
|
b = []byte(option.PrivateKey)
|
||||||
} else {
|
} else {
|
||||||
b, err = os.ReadFile(C.Path.Resolve(option.PrivateKey))
|
path := C.Path.Resolve(option.PrivateKey)
|
||||||
|
if !C.Path.IsSafePath(path) {
|
||||||
|
return nil, fmt.Errorf("path is not subpath of home directory: %s", path)
|
||||||
|
}
|
||||||
|
b, err = os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|||||||
@ -81,7 +81,11 @@ func GetCertPool(customCA string, customCAString string) (*x509.CertPool, error)
|
|||||||
var certificate []byte
|
var certificate []byte
|
||||||
var err error
|
var err error
|
||||||
if len(customCA) > 0 {
|
if len(customCA) > 0 {
|
||||||
certificate, err = os.ReadFile(C.Path.Resolve(customCA))
|
path := C.Path.Resolve(customCA)
|
||||||
|
if !C.Path.IsSafePath(path) {
|
||||||
|
return nil, fmt.Errorf("path is not subpath of home directory: %s", path)
|
||||||
|
}
|
||||||
|
certificate, err = os.ReadFile(path)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("load ca error: %w", err)
|
return nil, fmt.Errorf("load ca error: %w", err)
|
||||||
}
|
}
|
||||||
|
|||||||
@ -16,6 +16,7 @@ import (
|
|||||||
|
|
||||||
type Path interface {
|
type Path interface {
|
||||||
Resolve(path string) string
|
Resolve(path string) string
|
||||||
|
IsSafePath(path string) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
// LoadTLSKeyPair loads a TLS key pair from the provided certificate and private key data or file paths, supporting fallback resolution.
|
// LoadTLSKeyPair loads a TLS key pair from the provided certificate and private key data or file paths, supporting fallback resolution.
|
||||||
@ -40,7 +41,12 @@ func LoadTLSKeyPair(certificate, privateKey string, path Path) (tls.Certificate,
|
|||||||
|
|
||||||
certificate = path.Resolve(certificate)
|
certificate = path.Resolve(certificate)
|
||||||
privateKey = path.Resolve(privateKey)
|
privateKey = path.Resolve(privateKey)
|
||||||
cert, loadErr := tls.LoadX509KeyPair(certificate, privateKey)
|
var loadErr error
|
||||||
|
if path.IsSafePath(certificate) && path.IsSafePath(privateKey) {
|
||||||
|
cert, loadErr = tls.LoadX509KeyPair(certificate, privateKey)
|
||||||
|
} else {
|
||||||
|
loadErr = fmt.Errorf("path is not subpath of home directory")
|
||||||
|
}
|
||||||
if loadErr != nil {
|
if loadErr != nil {
|
||||||
return tls.Certificate{}, fmt.Errorf("parse certificate failed, maybe format error:%s, or path error: %s", painTextErr.Error(), loadErr.Error())
|
return tls.Certificate{}, fmt.Errorf("parse certificate failed, maybe format error:%s, or path error: %s", painTextErr.Error(), loadErr.Error())
|
||||||
}
|
}
|
||||||
|
|||||||
@ -754,6 +754,9 @@ func parseGeneral(cfg *RawConfig) (*General, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func parseController(cfg *RawConfig) (*Controller, error) {
|
func parseController(cfg *RawConfig) (*Controller, error) {
|
||||||
|
if path := cfg.ExternalUI; path != "" && !C.Path.IsSafePath(path) {
|
||||||
|
return nil, fmt.Errorf("path is not subpath of home directory: %s", path)
|
||||||
|
}
|
||||||
return &Controller{
|
return &Controller{
|
||||||
ExternalController: cfg.ExternalController,
|
ExternalController: cfg.ExternalController,
|
||||||
ExternalUI: cfg.ExternalUI,
|
ExternalUI: cfg.ExternalUI,
|
||||||
|
|||||||
@ -84,7 +84,7 @@ func (p *path) IsSafePath(path string) bool {
|
|||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
return !strings.Contains(rel, "..")
|
return filepath.IsLocal(rel)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *path) GetPathByHash(prefix, name string) string {
|
func (p *path) GetPathByHash(prefix, name string) string {
|
||||||
|
|||||||
@ -373,10 +373,9 @@ func updateConfigs(w http.ResponseWriter, r *http.Request) {
|
|||||||
} else {
|
} else {
|
||||||
if req.Path == "" {
|
if req.Path == "" {
|
||||||
req.Path = C.Path.Config()
|
req.Path = C.Path.Config()
|
||||||
}
|
} else if !filepath.IsLocal(req.Path) {
|
||||||
if !filepath.IsAbs(req.Path) {
|
|
||||||
render.Status(r, http.StatusBadRequest)
|
render.Status(r, http.StatusBadRequest)
|
||||||
render.JSON(w, r, newError("path is not a absolute path"))
|
render.JSON(w, r, newError("path is not a valid absolute path"))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user