···7575 })
7676}
77777878+// ccRecipient returns ", addr" if NEOMD_TEST_CC is set, empty string otherwise.
7979+// Used to optionally CC test emails to a live inbox for manual inspection.
8080+func (e testEnv) ccRecipient() string {
8181+ if cc := os.Getenv("NEOMD_TEST_CC"); cc != "" {
8282+ return ", " + cc
8383+ }
8484+ return ""
8585+}
8686+7887func (e testEnv) smtpConfig() smtp.Config {
7988 return smtp.Config{
8089 Host: e.smtpHost,
···968977969978*sent from [neomd](https://neomd.ssp.sh)*`
970979971971- err := smtp.Send(env.smtpConfig(), env.user+", simon@ssp.sh", "", "", subject, body, []string{realDoc, fakeImg})
980980+ err := smtp.Send(env.smtpConfig(), env.user+env.ccRecipient(), "", "", subject, body, []string{realDoc, fakeImg})
972981 if err != nil {
973982 t.Fatalf("Send: %v", err)
974983 }
···1041105010421051 // Send normally — the HTML will contain the markdown-rendered content.
10431052 // To also test raw HTML injection, we build a custom message with injected tags.
10441044- raw, err := smtp.BuildMessage(env.from, env.user+", simon@ssp.sh", "", subject, body, nil, "")
10531053+ raw, err := smtp.BuildMessage(env.from, env.user+env.ccRecipient(), "", subject, body, nil, "")
10451054 if err != nil {
10461055 t.Fatalf("BuildMessage: %v", err)
10471056 }
···10591068 rawStr = rawStr[:idx] + injection + rawStr[idx:]
10601069 }
1061107010621062- allRecipients := []string{env.user, "simon@ssp.sh"}
10711071+ allRecipients := []string{env.user}
10721072+ if cc := env.ccRecipient(); cc != "" {
10731073+ allRecipients = append(allRecipients, strings.TrimPrefix(cc, ", "))
10741074+ }
10631075 if err := smtp.SendRaw(env.smtpConfig(), allRecipients, []byte(rawStr)); err != nil {
10641076 t.Fatalf("SendRaw: %v", err)
10651077 }
+2-2
internal/render/html.go
···6868// SanitizeForBrowser injects a restrictive CSP into raw HTML to block scripts
6969// and frames while allowing images. For use when opening untrusted email HTML.
7070func SanitizeForBrowser(html string) string {
7171- // Skip if CSP already present (e.g. from htmlTemplate via ToHTML).
7272- if strings.Contains(html, "Content-Security-Policy") {
7171+ // Skip if our exact CSP is already present (e.g. from htmlTemplate via ToHTML).
7272+ if strings.Contains(html, browserCSP) {
7373 return html
7474 }
7575 // Insert after <head> if present, otherwise prepend.