From 410c957ddbd100e4a7cc113bcad720c77f9fca32 Mon Sep 17 00:00:00 2001 From: Ziemek Borowski Date: Wed, 6 May 2026 17:34:43 +0200 Subject: [PATCH] Potential fix for code scanning alert no. 2: Email content injection Co-authored-by: Copilot Autofix powered by AI <62310815+github-advanced-security[bot]@users.noreply.github.com> --- internal/serve/smtp_handler.go | 25 +++++++++++++++++++++++-- 1 file changed, 23 insertions(+), 2 deletions(-) diff --git a/internal/serve/smtp_handler.go b/internal/serve/smtp_handler.go index 40eeca3..3f8000c 100644 --- a/internal/serve/smtp_handler.go +++ b/internal/serve/smtp_handler.go @@ -4,6 +4,7 @@ import ( "context" "encoding/json" "net/http" + "strings" "time" "msgraphtool/internal/common/logger" @@ -19,6 +20,26 @@ type smtpSendRequest struct { Body string `json:"body,omitempty"` } +func sanitizeEmailSubjectInput(subject string) string { + subject = strings.ReplaceAll(subject, "\r", "") + subject = strings.ReplaceAll(subject, "\n", "") + return strings.TrimSpace(subject) +} + +func sanitizeEmailBodyInput(body string) string { + body = strings.ReplaceAll(body, "\r\n", "\n") + body = strings.ReplaceAll(body, "\r", "\n") + + var b strings.Builder + b.Grow(len(body)) + for _, r := range body { + if r == '\n' || r == '\t' || r >= 0x20 { + b.WriteRune(r) + } + } + return b.String() +} + func (s *Server) handleSMTPSendMail(w http.ResponseWriter, r *http.Request) { if s.smtpBase == nil { writeJSON(w, http.StatusServiceUnavailable, apiResponse{Status: "error", Message: "SMTP not configured (set SMTPHOST and related env vars)"}) @@ -61,8 +82,8 @@ func (s *Server) handleSMTPSendMail(w http.ResponseWriter, r *http.Request) { // Clone base config and overlay request content cfg := *s.smtpBase cfg.To = req.To - cfg.Subject = req.Subject - cfg.Body = req.Body + cfg.Subject = sanitizeEmailSubjectInput(req.Subject) + cfg.Body = sanitizeEmailBodyInput(req.Body) cfg.Action = smtp.ActionSendMail if req.From != "" { cfg.From = req.From