A minimal email TUI where you read with Markdown and write in Neovim. neomd.ssp.sh/docs
email markdown neovim tui
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

santize HTML

+19 -2
+17
internal/render/html.go
··· 20 20 <head> 21 21 <meta charset="UTF-8"> 22 22 <meta name="viewport" content="width=device-width,initial-scale=1.0"> 23 + <meta http-equiv="Content-Security-Policy" content="script-src 'none'; frame-src 'none'; object-src 'none';"> 23 24 <style> 24 25 body{font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,Helvetica,Arial,sans-serif;line-height:1.6;color:#333;margin:0;padding:8px 16px;text-align:left} 25 26 a{color:#3150AA;text-decoration:underline} ··· 59 60 ), 60 61 goldmark.WithRendererOptions(html.WithHardWraps()), 61 62 ) 63 + 64 + // browserCSP is injected into raw HTML emails to block scripts, frames, and objects 65 + // while still allowing remote images (user explicitly chose to open in browser). 66 + const browserCSP = `<meta http-equiv="Content-Security-Policy" content="script-src 'none'; frame-src 'none'; object-src 'none';">` 67 + 68 + // SanitizeForBrowser injects a restrictive CSP into raw HTML to block scripts 69 + // and frames while allowing images. For use when opening untrusted email HTML. 70 + func SanitizeForBrowser(html string) string { 71 + // Insert after <head> if present, otherwise prepend. 72 + lower := strings.ToLower(html) 73 + if idx := strings.Index(lower, "<head>"); idx >= 0 { 74 + insert := idx + len("<head>") 75 + return html[:insert] + "\n" + browserCSP + "\n" + html[insert:] 76 + } 77 + return browserCSP + "\n" + html 78 + } 62 79 63 80 // ToHTML converts a Markdown string to a complete HTML email document. 64 81 func ToHTML(markdown string) (string, error) {
+2 -2
internal/ui/model.go
··· 3271 3271 3272 3272 var htmlBody string 3273 3273 if m.openHTMLBody != "" { 3274 - htmlBody = m.openHTMLBody 3274 + htmlBody = render.SanitizeForBrowser(m.openHTMLBody) 3275 3275 } else { 3276 3276 var err error 3277 3277 htmlBody, err = render.ToHTML(m.openBody) ··· 3348 3348 3349 3349 var htmlBody string 3350 3350 if m.openHTMLBody != "" { 3351 - htmlBody = m.openHTMLBody 3351 + htmlBody = render.SanitizeForBrowser(m.openHTMLBody) 3352 3352 } else { 3353 3353 var err error 3354 3354 htmlBody, err = render.ToHTML(m.openBody)