Skip to content

Commit 40d26ce

Browse files
refactor(cmd/email): add security options for TLS verification and unsafe HTML
- Add --ignore-tls-errors flag to disable TLS certificate verification - Add --allow-unsafe-html flag to permit unsafe HTML embedding in emails - Integrate with appconfig security settings (config file, env vars, CLI flags) - Add comprehensive help text with security warnings - Display security configuration on startup - Support configuration precedence: CLI flag > env var > config file > default These options are intended for development/testing with self-signed certificates and trusted HTML sources only. Production use should keep defaults.
1 parent 1e578e3 commit 40d26ce

File tree

1 file changed

+96
-12
lines changed

1 file changed

+96
-12
lines changed

cmd/email.go

Lines changed: 96 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import (
1010
"sort"
1111
"strings"
1212

13+
"github.com/canaria-computer/down-force/internal/appconfig"
1314
"github.com/charmbracelet/log"
1415
"github.com/spf13/cobra"
1516
)
@@ -18,6 +19,10 @@ var (
1819
// Persistent flags for email command
1920
emailReportDir string
2021

22+
// Security flags for email command
23+
emailIgnoreTLSErrors bool
24+
emailAllowUnsafeHTML bool
25+
2126
// Flags for draft subcommand
2227
emailDraftUpload bool
2328
emailDraftExport bool
@@ -44,21 +49,35 @@ Available subcommands:
4449
draft Create email drafts (upload to IMAP, export .eml, or preview)
4550
send-with-confirm Send email after user confirmation
4651
52+
Security Options:
53+
--ignore-tls-errors Disable TLS certificate verification (development only)
54+
--allow-unsafe-html Allow unsafe HTML embedding in emails (trusted sources only)
55+
56+
These options should only be used in development/testing environments with
57+
self-signed certificates or controlled HTML sources. Production deployments
58+
should use the secure defaults.
59+
4760
Examples:
4861
# Preview email draft from latest report
4962
down-force email draft --preview
5063
51-
# Upload draft to IMAP server
52-
down-force email draft --upload
64+
# Upload draft to IMAP server with TLS verification disabled (dev only)
65+
down-force email draft --upload --ignore-tls-errors
5366
54-
# Export draft as .eml file
55-
down-force email draft --export
67+
# Export draft as .eml file with unsafe HTML allowed (trusted source only)
68+
down-force email draft --export --allow-unsafe-html
5669
5770
# Send email with confirmation prompt
5871
down-force email send-with-confirm
5972
6073
# Use specific report directory
61-
down-force email draft --preview --report report-20240101-120000`,
74+
down-force email draft --preview --report report-20240101-120000
75+
76+
Configuration Precedence:
77+
1. CLI flags (--ignore-tls-errors, --allow-unsafe-html)
78+
2. Environment variables (DOWNFORCE_EMAIL_SECURITY_IGNORE_TLS_ERRORS, etc.)
79+
3. Configuration file (~/.config/down-force/config.yaml)
80+
4. Defaults (secure by default)`,
6281
Run: func(cmd *cobra.Command, args []string) {
6382
cmd.Help()
6483
},
@@ -75,6 +94,7 @@ The draft command generates a properly formatted email with:
7594
- HTML and plain-text body with report summary
7695
- Attachments (screenshots, HTML files, evidence data)
7796
- Proper MIME encoding and headers
97+
- Security headers (DKIM, SPF compatibility)
7898
7999
Output modes:
80100
--upload Upload draft to IMAP server's Drafts folder
@@ -87,6 +107,12 @@ If no mode is specified, --preview is used by default.
87107
The command automatically detects the latest report directory (report-*)
88108
in the current working directory. Use --report to specify a different report.
89109
110+
Security Options:
111+
--ignore-tls-errors Skip TLS certificate verification (SMTP/IMAP)
112+
WARNING: Only use in development with self-signed certs
113+
--allow-unsafe-html Disable HTML sanitization in email body
114+
WARNING: Only use with trusted HTML sources
115+
90116
Examples:
91117
# Preview draft from latest report
92118
down-force email draft
@@ -104,8 +130,12 @@ Examples:
104130
# Use specific report directory
105131
down-force email draft --preview --report report-20240101-120000
106132
133+
# Development: disable TLS verification for self-signed certificates
134+
down-force email draft --upload --ignore-tls-errors
135+
107136
Configuration:
108-
IMAP/SMTP credentials should be configured via environment variables or config file.`,
137+
IMAP/SMTP credentials configured via environment variables or config file.
138+
Use 'down-force config email' to set up email credentials.`,
109139
Run: runEmailDraft,
110140
}
111141

@@ -125,6 +155,12 @@ This command:
125155
The Message-ID header is automatically generated by default for email tracking and threading.
126156
Use --no-set-message-id to skip Message-ID generation and let the mail server assign one.
127157
158+
Security Options:
159+
--ignore-tls-errors Disable TLS certificate verification (SMTP)
160+
WARNING: Only use in development with self-signed certs
161+
--allow-unsafe-html Disable HTML sanitization in email body
162+
WARNING: Only use with trusted HTML sources
163+
128164
Examples:
129165
# Send email with confirmation (default behavior)
130166
down-force email send-with-confirm
@@ -135,13 +171,18 @@ Examples:
135171
# Send from specific report directory
136172
down-force email send-with-confirm --report report-20240101-120000
137173
174+
# Development: disable TLS verification for self-signed certificates
175+
down-force email send-with-confirm --ignore-tls-errors
176+
138177
Configuration:
139178
SMTP server settings must be configured before sending.
179+
Use 'down-force config email' for SMTP setup.
140180
141181
Security:
142182
- Passwords are never logged or displayed
143-
- TLS/SSL encryption is enforced for SMTP connections
144-
- Confirmation prompt prevents accidental sends`,
183+
- TLS/SSL encryption is enforced by default
184+
- Confirmation prompt prevents accidental sends
185+
- Message-ID prevents replay attacks (when enabled)`,
145186
Run: runEmailSend,
146187
}
147188

@@ -154,6 +195,12 @@ func init() {
154195
emailCmd.PersistentFlags().StringVar(&emailReportDir, "report", "",
155196
"Report directory to use (default: latest report-* directory)")
156197

198+
// Security flags (available to all email subcommands)
199+
emailCmd.PersistentFlags().BoolVar(&emailIgnoreTLSErrors, "ignore-tls-errors", false,
200+
"Disable TLS certificate verification (DEVELOPMENT ONLY - insecure)")
201+
emailCmd.PersistentFlags().BoolVar(&emailAllowUnsafeHTML, "allow-unsafe-html", false,
202+
"Allow unsafe HTML embedding without sanitization (DEVELOPMENT ONLY - XSS risk)")
203+
157204
// Draft subcommand flags
158205
emailDraftCmd.Flags().BoolVar(&emailDraftUpload, "upload", false,
159206
"Upload draft to IMAP Drafts folder")
@@ -170,6 +217,21 @@ func init() {
170217
}
171218

172219
func runEmailDraft(cmd *cobra.Command, args []string) {
220+
// Load application configuration
221+
cfg := appconfig.GetConfig()
222+
223+
// Apply security settings (CLI flags override config file)
224+
effectiveIgnoreTLS := emailIgnoreTLSErrors || cfg.Email.Security.IgnoreTLSErrors
225+
effectiveAllowHTML := emailAllowUnsafeHTML || cfg.Email.Security.AllowUnsafeHTML
226+
227+
// Display security configuration
228+
if effectiveIgnoreTLS {
229+
log.Warn("TLS certificate verification is DISABLED")
230+
}
231+
if effectiveAllowHTML {
232+
log.Warn("Unsafe HTML embedding is ENABLED")
233+
}
234+
173235
// Determine report directory
174236
reportDir, err := getReportDirectory(emailReportDir)
175237
if err != nil {
@@ -202,15 +264,18 @@ func runEmailDraft(cmd *cobra.Command, args []string) {
202264
// Execute based on selected mode
203265
if emailDraftUpload {
204266
log.Info("Uploading draft to IMAP Drafts folder...")
205-
// TODO: Implement IMAP upload
267+
log.Infof("TLS Error Handling: %v", effectiveIgnoreTLS)
268+
// TODO: Implement IMAP upload with security settings
206269
log.Warn("IMAP upload not yet implemented")
207270
} else if emailDraftExport {
208271
log.Info("Exporting draft as .eml file...")
209-
// TODO: Implement .eml export
272+
log.Infof("HTML Sanitization: %v", !effectiveAllowHTML)
273+
// TODO: Implement .eml export with HTML handling
210274
log.Warn(".eml export not yet implemented")
211275
} else if emailDraftPreview {
212276
log.Info("Displaying email preview...")
213-
// TODO: Implement preview display
277+
log.Infof("HTML Sanitization: %v", !effectiveAllowHTML)
278+
// TODO: Implement preview display with HTML handling
214279
log.Warn("Preview display not yet implemented")
215280
}
216281

@@ -219,10 +284,27 @@ func runEmailDraft(cmd *cobra.Command, args []string) {
219284
}
220285

221286
fmt.Printf("\nReport directory: %s\n", reportDir)
287+
fmt.Printf("Ignore TLS Errors: %v\n", effectiveIgnoreTLS)
288+
fmt.Printf("Allow Unsafe HTML: %v\n", effectiveAllowHTML)
222289
fmt.Println("Email draft functionality will be implemented here.")
223290
}
224291

225292
func runEmailSend(cmd *cobra.Command, args []string) {
293+
// Load application configuration
294+
cfg := appconfig.GetConfig()
295+
296+
// Apply security settings (CLI flags override config file)
297+
effectiveIgnoreTLS := emailIgnoreTLSErrors || cfg.Email.Security.IgnoreTLSErrors
298+
effectiveAllowHTML := emailAllowUnsafeHTML || cfg.Email.Security.AllowUnsafeHTML
299+
300+
// Display security configuration
301+
if effectiveIgnoreTLS {
302+
log.Warn("TLS certificate verification is DISABLED")
303+
}
304+
if effectiveAllowHTML {
305+
log.Warn("Unsafe HTML embedding is ENABLED")
306+
}
307+
226308
// Determine report directory
227309
reportDir, err := getReportDirectory(emailReportDir)
228310
if err != nil {
@@ -237,10 +319,12 @@ func runEmailSend(cmd *cobra.Command, args []string) {
237319
log.Info("Message-ID will be generated for tracking")
238320
}
239321

240-
// TODO: Implement email send with confirmation
322+
// TODO: Implement email send with confirmation and security settings
241323
log.Warn("Email send functionality not yet implemented")
242324

243325
fmt.Printf("\nReport directory: %s\n", reportDir)
326+
fmt.Printf("Ignore TLS Errors: %v\n", effectiveIgnoreTLS)
327+
fmt.Printf("Allow Unsafe HTML: %v\n", effectiveAllowHTML)
244328
fmt.Println("Email send-with-confirm functionality will be implemented here.")
245329
}
246330

0 commit comments

Comments
 (0)