-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
[WIP] Problem: send mail don't work #3276
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: develop
Are you sure you want to change the base?
Conversation
Co-authored-by: fiftin <[email protected]>
Co-authored-by: fiftin <[email protected]>
return err | ||
} | ||
|
||
w, err := c.Data() |
Check failure
Code scanning / CodeQL
Email content injection Critical
untrusted input
Show autofix suggestion
Hide autofix suggestion
Copilot Autofix
AI 7 days ago
To fix this problem, the best approach is to explicitly validate and sanitize all user-supplied inputs that are used in email construction, especially the recipient email address and any other user-controlled fields incorporated into headers or the body. The primary concern is header injection due to newline \r
and \n
characters in the "To" address, as well as improper characters in other fields. For email addresses:
- Validate the email format before assignment and reject or sanitize any addresses containing newline or other illegal characters.
- Use a strong regular expression to make sure the email address matches a basic valid pattern and disallow newlines, carriage returns, and other forbidden symbols.
- Apply the same validation to any user-supplied fields used in subject or header construction.
- For content used in email body templates, consider escaping unsafe characters or using template escaping.
Changes required:
- In
api/projects/invites.go
, validaterequest.Email
before using it in the invite logic, ideally right after parsing the request. If invalid, return a400 Bad Request
error. - Optionally, additionally sanitize/validate inside the mailer logic, in
util/mailer/mailer.go
, but validation should always happen as early as possible. - Imports needed: add Go's
regexp
and/or"net/mail"
for validation, if not already present. - Add a helper validation function for email if not already present.
-
Copy modified lines R18-R24 -
Copy modified line R118
@@ -15,6 +15,13 @@ | ||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
// sanitizeEmailHeader strips any CRLF injection and trims spaces from email header values. | ||
func sanitizeEmailHeader(s string) string { | ||
s = strings.ReplaceAll(s, "\r", "") | ||
s = strings.ReplaceAll(s, "\n", "") | ||
return strings.TrimSpace(s) | ||
} | ||
|
||
const ( | ||
mailerBase = "MIME-version: 1.0\r\n" + | ||
"Content-Type: text/html; charset=UTF-8\r\n" + | ||
@@ -108,7 +115,7 @@ | ||
Body string | ||
}{ | ||
Date: tz.Now().Format(time.RFC1123), | ||
To: r.Replace(to), | ||
To: sanitizeEmailHeader(r.Replace(to)), | ||
From: r.Replace(from), | ||
Subject: r.Replace(subject), | ||
Body: content, |
-
Copy modified line R9 -
Copy modified lines R22-R30 -
Copy modified lines R86-R93
@@ -6,6 +6,7 @@ | ||
"encoding/hex" | ||
"fmt" | ||
"net/http" | ||
"net/mail" | ||
"time" | ||
|
||
"text/template" | ||
@@ -18,6 +19,15 @@ | ||
log "github.com/sirupsen/logrus" | ||
) | ||
|
||
// isValidEmail checks for valid email address and absence of CRLF injection. | ||
func isValidEmail(address string) bool { | ||
if strings.ContainsAny(address, "\r\n") { | ||
return false | ||
} | ||
_, err := mail.ParseAddress(address) | ||
return err == nil | ||
} | ||
|
||
// InviteMiddleware ensures an invite exists and loads it to the context | ||
func InviteMiddleware(next http.Handler) http.Handler { | ||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { | ||
@@ -73,6 +83,14 @@ | ||
return | ||
} | ||
|
||
// Validate email address if provided | ||
if request.Email != nil { | ||
if !isValidEmail(*request.Email) { | ||
helpers.WriteErrorStatus(w, "Invalid email address", http.StatusBadRequest) | ||
return | ||
} | ||
} | ||
|
||
if !request.Role.IsValid() { | ||
w.WriteHeader(http.StatusBadRequest) | ||
return |
Email Sending Fix Implementation
Fixed the root cause of email sending issues in Semaphore UI by improving the mailer logic and adding comprehensive logging.
Issues Found and Fixed:
EmailSecure=false
, code tried anonymous SMTP (no auth) which most servers rejectImplementation Completed:
Key Changes:
sendStartTls()
function for port 587 configurationsEmail Configuration Guide:
secure=true, useTls=false, port=587
(STARTTLS)secure=false, useTls=true, port=465
(Direct TLS)secure=false, useTls=false, port=25/1025
(Plain/Anonymous)Testing Status:
The fix ensures that when users provide email credentials, authentication will be properly used instead of falling back to anonymous SMTP which most servers reject.
Fixes #3202.
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.