This commit is contained in:
parent
951fdc00c4
commit
1790e1f4f6
@ -329,8 +329,10 @@ func secureManagerConfigDirectory(root string) (string, error) {
|
||||
}
|
||||
// 目录权限 0700 是配置目录的最低要求;G302 将目录误判为文件。
|
||||
// #nosec G302
|
||||
if err := os.Chmod(directory, 0700); err != nil {
|
||||
return "", err
|
||||
if info.Mode().Perm() != 0700 {
|
||||
if err := os.Chmod(directory, 0700); err != nil {
|
||||
return "", err
|
||||
}
|
||||
}
|
||||
return directory, nil
|
||||
}
|
||||
|
||||
@ -38,6 +38,10 @@ func ExportProjectTLS(root, destination string) error {
|
||||
if err != nil || resolvedSource != sourceDirectory {
|
||||
return ErrUnsafeSSLFile
|
||||
}
|
||||
sourceInfo, err := os.Stat(sourceDirectory)
|
||||
if err != nil || !sourceInfo.IsDir() || sourceInfo.Mode().Perm()&0022 != 0 {
|
||||
return ErrUnsafeSSLFile
|
||||
}
|
||||
storage, err := os.OpenRoot(sourceDirectory)
|
||||
if err != nil {
|
||||
return ErrUnsafeSSLFile
|
||||
@ -45,7 +49,7 @@ func ExportProjectTLS(root, destination string) error {
|
||||
defer storage.Close()
|
||||
read := func(name string) ([]byte, error) {
|
||||
info, err := storage.Lstat(name)
|
||||
if err != nil || !info.Mode().IsRegular() || info.Size() > maxManagedSSLFileSize || info.Mode().Perm()&0077 != 0 {
|
||||
if err != nil || !info.Mode().IsRegular() || hasMultipleInfoLinks(info) || info.Size() > maxManagedSSLFileSize || info.Mode().Perm()&0077 != 0 {
|
||||
return nil, ErrUnsafeSSLFile
|
||||
}
|
||||
file, err := storage.Open(name)
|
||||
@ -54,7 +58,7 @@ func ExportProjectTLS(root, destination string) error {
|
||||
}
|
||||
defer file.Close()
|
||||
opened, err := file.Stat()
|
||||
if err != nil || !os.SameFile(info, opened) || !opened.Mode().IsRegular() || opened.Mode().Perm()&0077 != 0 {
|
||||
if err != nil || !os.SameFile(info, opened) || !opened.Mode().IsRegular() || hasMultipleInfoLinks(opened) || opened.Mode().Perm()&0077 != 0 {
|
||||
return nil, ErrUnsafeSSLFile
|
||||
}
|
||||
data, err := io.ReadAll(io.LimitReader(file, maxManagedSSLFileSize+1))
|
||||
@ -62,7 +66,7 @@ func ExportProjectTLS(root, destination string) error {
|
||||
return nil, ErrUnsafeSSLFile
|
||||
}
|
||||
after, err := file.Stat()
|
||||
if err != nil || !os.SameFile(opened, after) || after.Size() != int64(len(data)) || !opened.ModTime().Equal(after.ModTime()) || after.Mode().Perm()&0077 != 0 {
|
||||
if err != nil || !os.SameFile(opened, after) || hasMultipleInfoLinks(after) || after.Size() != int64(len(data)) || !opened.ModTime().Equal(after.ModTime()) || after.Mode().Perm()&0077 != 0 {
|
||||
return nil, ErrUnsafeSSLFile
|
||||
}
|
||||
return data, nil
|
||||
@ -96,7 +100,7 @@ func ExportProjectTLS(root, destination string) error {
|
||||
defer output.Close()
|
||||
name := filepath.Base(destination)
|
||||
if info, err := output.Lstat(name); err == nil {
|
||||
if !info.Mode().IsRegular() || info.Mode().Perm()&0077 != 0 {
|
||||
if !info.Mode().IsRegular() || hasMultipleInfoLinks(info) || info.Mode().Perm()&0077 != 0 {
|
||||
return ErrUnsafeSSLFile
|
||||
}
|
||||
previous, err := output.ReadFile(name)
|
||||
|
||||
@ -81,6 +81,16 @@ func TestExportProjectTLSKeepsOldBundleOnInvalidInput(t *testing.T) {
|
||||
if err := ExportProjectTLS(root, filepath.Join(link, "tls.pem")); err == nil {
|
||||
t.Fatal("linked output directory accepted")
|
||||
}
|
||||
hardLink := filepath.Join(t.TempDir(), "linked.key")
|
||||
if err := os.Link(ref.PrivateKeyPath, hardLink); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := ExportProjectTLS(root, destination); err == nil {
|
||||
t.Fatal("hard-linked private key accepted")
|
||||
}
|
||||
if err := os.Remove(hardLink); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(ref.PrivateKeyPath, []byte("invalid"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
@ -2,7 +2,15 @@
|
||||
|
||||
package config
|
||||
|
||||
import "syscall"
|
||||
import (
|
||||
"os"
|
||||
"syscall"
|
||||
)
|
||||
|
||||
func hasMultipleInfoLinks(info os.FileInfo) bool {
|
||||
stat, ok := info.Sys().(*syscall.Stat_t)
|
||||
return !ok || stat.Nlink != 1
|
||||
}
|
||||
|
||||
func hasMultipleFileLinks(path string) bool {
|
||||
var stat syscall.Stat_t
|
||||
|
||||
@ -2,6 +2,12 @@
|
||||
|
||||
package config
|
||||
|
||||
import "os"
|
||||
|
||||
func hasMultipleInfoLinks(info os.FileInfo) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
func hasMultipleFileLinks(path string) bool {
|
||||
return false
|
||||
}
|
||||
|
||||
@ -15,7 +15,7 @@ NoNewPrivileges=true
|
||||
PrivateTmp=true
|
||||
ProtectHome=true
|
||||
ProtectSystem=strict
|
||||
ReadWritePaths=/etc/nginx/smail /opt/smail/data /var/log/nginx
|
||||
ReadWritePaths=/etc/nginx/smail /var/log/nginx
|
||||
TimeoutStartSec=30
|
||||
Restart=on-failure
|
||||
RestartSec=5
|
||||
|
||||
Loading…
Reference in New Issue
Block a user