1
0
mirror of https://github.com/axllent/mailpit.git synced 2025-08-15 20:13:16 +02:00

Chore: Security improvements (gosec)

This commit is contained in:
Ralph Slooten
2024-02-17 12:38:30 +13:00
parent b2a0d73572
commit 26a2095674
10 changed files with 44 additions and 16 deletions

View File

@@ -154,13 +154,17 @@ func initConfigFromEnv() {
// UI // UI
config.UIAuthFile = os.Getenv("MP_UI_AUTH_FILE") config.UIAuthFile = os.Getenv("MP_UI_AUTH_FILE")
auth.SetUIAuth(os.Getenv("MP_UI_AUTH")) if err := auth.SetUIAuth(os.Getenv("MP_UI_AUTH")); err != nil {
logger.Log().Errorf(err.Error())
}
config.UITLSCert = os.Getenv("MP_UI_TLS_CERT") config.UITLSCert = os.Getenv("MP_UI_TLS_CERT")
config.UITLSKey = os.Getenv("MP_UI_TLS_KEY") config.UITLSKey = os.Getenv("MP_UI_TLS_KEY")
// SMTP // SMTP
config.SMTPAuthFile = os.Getenv("MP_SMTP_AUTH_FILE") config.SMTPAuthFile = os.Getenv("MP_SMTP_AUTH_FILE")
auth.SetSMTPAuth(os.Getenv("MP_SMTP_AUTH")) if err := auth.SetSMTPAuth(os.Getenv("MP_SMTP_AUTH")); err != nil {
logger.Log().Errorf(err.Error())
}
config.SMTPTLSCert = os.Getenv("MP_SMTP_TLS_CERT") config.SMTPTLSCert = os.Getenv("MP_SMTP_TLS_CERT")
config.SMTPTLSKey = os.Getenv("MP_SMTP_TLS_KEY") config.SMTPTLSKey = os.Getenv("MP_SMTP_TLS_KEY")
if getEnabledFromEnv("MP_SMTP_TLS_REQUIRED") { if getEnabledFromEnv("MP_SMTP_TLS_REQUIRED") {

View File

@@ -179,13 +179,17 @@ func VerifyConfig() error {
} }
if UIAuthFile != "" { if UIAuthFile != "" {
UIAuthFile = filepath.Clean(UIAuthFile)
if !isFile(UIAuthFile) { if !isFile(UIAuthFile) {
return fmt.Errorf("[ui] HTTP password file not found: %s", UIAuthFile) return fmt.Errorf("[ui] HTTP password file not found: %s", UIAuthFile)
} }
b, err := os.ReadFile(UIAuthFile) b, err := os.ReadFile(UIAuthFile)
if err != nil { if err != nil {
return err return err
} }
if err := auth.SetUIAuth(string(b)); err != nil { if err := auth.SetUIAuth(string(b)); err != nil {
return err return err
} }
@@ -196,6 +200,8 @@ func VerifyConfig() error {
} }
if UITLSCert != "" { if UITLSCert != "" {
UITLSCert = filepath.Clean(UITLSCert)
if !isFile(UITLSCert) { if !isFile(UITLSCert) {
return fmt.Errorf("[ui] TLS certificate not found: %s", UITLSCert) return fmt.Errorf("[ui] TLS certificate not found: %s", UITLSCert)
} }
@@ -210,6 +216,8 @@ func VerifyConfig() error {
} }
if SMTPTLSCert != "" { if SMTPTLSCert != "" {
SMTPTLSCert = filepath.Clean(SMTPTLSCert)
if !isFile(SMTPTLSCert) { if !isFile(SMTPTLSCert) {
return fmt.Errorf("[smtp] TLS certificate not found: %s", SMTPTLSCert) return fmt.Errorf("[smtp] TLS certificate not found: %s", SMTPTLSCert)
} }
@@ -226,6 +234,8 @@ func VerifyConfig() error {
} }
if SMTPAuthFile != "" { if SMTPAuthFile != "" {
SMTPAuthFile = filepath.Clean(SMTPAuthFile)
if !isFile(SMTPAuthFile) { if !isFile(SMTPAuthFile) {
return fmt.Errorf("[smtp] password file not found: %s", SMTPAuthFile) return fmt.Errorf("[smtp] password file not found: %s", SMTPAuthFile)
} }
@@ -324,8 +334,10 @@ func parseRelayConfig(c string) error {
return nil return nil
} }
c = filepath.Clean(c)
if !isFile(c) { if !isFile(c) {
return fmt.Errorf("[smtp] relay configuration not found: %s", SMTPRelayConfigFile) return fmt.Errorf("[smtp] relay configuration not found: %s", c)
} }
data, err := os.ReadFile(c) data, err := os.ReadFile(c)

View File

@@ -63,7 +63,7 @@ func doHead(link string, followRedirects bool) (int, error) {
tr := &http.Transport{} tr := &http.Transport{}
if config.AllowUntrustedTLS { if config.AllowUntrustedTLS {
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} // #nosec
} }
client := http.Client{ client := http.Client{

View File

@@ -5,6 +5,7 @@ import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"os" "os"
"path/filepath"
"regexp" "regexp"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
@@ -39,7 +40,7 @@ func Log() *logrus.Logger {
} }
if LogFile != "" { if LogFile != "" {
file, err := os.OpenFile(LogFile, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0664) file, err := os.OpenFile(filepath.Clean(LogFile), os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0664) // #nosec
if err == nil { if err == nil {
log.Out = file log.Out = file
} else { } else {

View File

@@ -712,7 +712,9 @@ func DeleteAllMessages() error {
vacuumDb() vacuumDb()
dbLastAction = time.Now() dbLastAction = time.Now()
SettingPut("DeletedSize", "0") if err := SettingPut("DeletedSize", "0"); err != nil {
logger.Log().Warnf("[db] %s", err.Error())
}
logMessagesDeleted(total) logMessagesDeleted(total)

View File

@@ -160,21 +160,21 @@ func DeleteSearch(search string) error {
delIDs[i] = id delIDs[i] = id
} }
sqlDelete1 := `DELETE FROM mailbox WHERE ID IN (?` + strings.Repeat(",?", len(ids)-1) + `)` sqlDelete1 := `DELETE FROM mailbox WHERE ID IN (?` + strings.Repeat(",?", len(ids)-1) + `)` // #nosec
_, err = tx.Exec(sqlDelete1, delIDs...) _, err = tx.Exec(sqlDelete1, delIDs...)
if err != nil { if err != nil {
return err return err
} }
sqlDelete2 := `DELETE FROM mailbox_data WHERE ID IN (?` + strings.Repeat(",?", len(ids)-1) + `)` sqlDelete2 := `DELETE FROM mailbox_data WHERE ID IN (?` + strings.Repeat(",?", len(ids)-1) + `)` // #nosec
_, err = tx.Exec(sqlDelete2, delIDs...) _, err = tx.Exec(sqlDelete2, delIDs...)
if err != nil { if err != nil {
return err return err
} }
sqlDelete3 := `DELETE FROM message_tags WHERE ID IN (?` + strings.Repeat(",?", len(ids)-1) + `)` sqlDelete3 := `DELETE FROM message_tags WHERE ID IN (?` + strings.Repeat(",?", len(ids)-1) + `)` // #nosec
_, err = tx.Exec(sqlDelete3, delIDs...) _, err = tx.Exec(sqlDelete3, delIDs...)
if err != nil { if err != nil {

View File

@@ -178,8 +178,8 @@ func GithubUpdate(repo, appName, currentVersion string) (string, error) {
} }
if runtime.GOOS != "windows" { if runtime.GOOS != "windows" {
/* #nosec G302 */ err := os.Chmod(newExec, 0755) // #nosec
if err := os.Chmod(newExec, 0755); err != nil { if err != nil {
return "", err return "", err
} }
} }

View File

@@ -35,7 +35,7 @@ func ProxyHandler(w http.ResponseWriter, r *http.Request) {
tr := &http.Transport{} tr := &http.Transport{}
if config.AllowUntrustedTLS { if config.AllowUntrustedTLS {
tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} tr.TLSClientConfig = &tls.Config{InsecureSkipVerify: true} // #nosec
} }
client := &http.Client{ client := &http.Client{
@@ -108,7 +108,9 @@ func ProxyHandler(w http.ResponseWriter, r *http.Request) {
// relay status code - WriteHeader must come after Header.Set() // relay status code - WriteHeader must come after Header.Set()
w.WriteHeader(resp.StatusCode) w.WriteHeader(resp.StatusCode)
w.Write(body) if _, err := w.Write(body); err != nil {
logger.Log().Warnf("[proxy] %s", err.Error())
}
} }
// AbsoluteURL will return a full URL regardless whether it is relative or absolute // AbsoluteURL will return a full URL regardless whether it is relative or absolute

View File

@@ -13,6 +13,7 @@ import (
"strings" "strings"
"sync/atomic" "sync/atomic"
"text/template" "text/template"
"time"
"github.com/axllent/mailpit/config" "github.com/axllent/mailpit/config"
"github.com/axllent/mailpit/internal/auth" "github.com/axllent/mailpit/internal/auth"
@@ -94,12 +95,18 @@ func Listen() {
logger.Log().Infof("[http] starting on %s", config.HTTPListen) logger.Log().Infof("[http] starting on %s", config.HTTPListen)
server := &http.Server{
Addr: config.HTTPListen,
ReadTimeout: 30 * time.Second,
WriteTimeout: 30 * time.Second,
}
if config.UITLSCert != "" && config.UITLSKey != "" { if config.UITLSCert != "" && config.UITLSKey != "" {
logger.Log().Infof("[http] accessible via https://%s%s", logger.CleanHTTPIP(config.HTTPListen), config.Webroot) logger.Log().Infof("[http] accessible via https://%s%s", logger.CleanHTTPIP(config.HTTPListen), config.Webroot)
logger.Log().Fatal(http.ListenAndServeTLS(config.HTTPListen, config.UITLSCert, config.UITLSKey, nil)) logger.Log().Fatal(server.ListenAndServeTLS(config.UITLSCert, config.UITLSKey))
} else { } else {
logger.Log().Infof("[http] accessible via http://%s%s", logger.CleanHTTPIP(config.HTTPListen), config.Webroot) logger.Log().Infof("[http] accessible via http://%s%s", logger.CleanHTTPIP(config.HTTPListen), config.Webroot)
logger.Log().Fatal(http.ListenAndServe(config.HTTPListen, nil)) logger.Log().Fatal(server.ListenAndServe())
} }
} }

View File

@@ -54,7 +54,7 @@ func Send(from string, to []string, msg []byte) error {
defer c.Close() defer c.Close()
if config.SMTPRelayConfig.STARTTLS { if config.SMTPRelayConfig.STARTTLS {
conf := &tls.Config{ServerName: config.SMTPRelayConfig.Host} conf := &tls.Config{ServerName: config.SMTPRelayConfig.Host} // #nosec
conf.InsecureSkipVerify = config.SMTPRelayConfig.AllowInsecure conf.InsecureSkipVerify = config.SMTPRelayConfig.AllowInsecure