# Contact Form Email Backend - Implementation Guide ## Overview Complete backend implementation for a contact form with email delivery using SMTP (Gmail), featuring comprehensive security measures including CSRF protection, rate limiting, bot protection, and browser-only access. ## Features Implemented ### 1. Email Service (`internal/services/email.go`) - ✅ SMTP-based email sending with TLS support - ✅ Gmail App Password authentication - ✅ Email validation and sanitization - ✅ Header injection prevention - ✅ Configurable via environment variables - ✅ Comprehensive error handling and logging - ✅ Template-based email formatting ### 2. Contact Handler (`internal/handlers/contact.go`) - ✅ POST endpoint: `/api/contact` - ✅ Form field validation (email, name, company, subject, message) - ✅ Bot protection with honeypot field - ✅ Timing check (rejects forms submitted < 2 seconds) - ✅ HTMX-friendly responses - ✅ Detailed logging (without sensitive data) ### 3. Security Middleware #### Contact Rate Limiting (`internal/middleware/contact_rate_limit.go`) - ✅ 5 requests per hour per IP address - ✅ Automatic cleanup of expired entries - ✅ HTMX-friendly error responses - ✅ Configurable limits and windows #### CSRF Protection (`internal/middleware/csrf.go`) - ✅ Token generation and validation - ✅ 24-hour token TTL - ✅ Cookie-based token storage - ✅ Automatic token cleanup - ✅ Support for forms and AJAX requests #### Browser-Only Access (`internal/middleware/browser_only.go`) - ✅ Blocks curl, Postman, wget, and other HTTP clients - ✅ User-Agent validation - ✅ Referer/Origin header validation - ✅ Custom header requirement (HTMX or X-Browser-Request) - ✅ Comprehensive bot detection ### 4. Configuration (`internal/config/config.go`) - ✅ Email settings added to config struct - ✅ Environment variable support - ✅ Sensible defaults for development ### 5. HTMX Response Templates - ✅ `templates/partials/contact_success.html` - Success message with animation - ✅ `templates/partials/contact_error.html` - Error message with shake animation ### 6. Route Registration (`internal/routes/routes.go`) - ✅ Endpoint registered with full middleware chain - ✅ Proper middleware ordering ## Security Features ### Multi-Layer Protection ``` Request → Browser-Only → Contact Rate Limit → CSRF → Handler ``` 1. **Browser-Only Middleware** - Blocks non-browser clients (curl, Postman, etc.) - Validates User-Agent, Referer, and custom headers 2. **Contact Rate Limiting** - 5 submissions per hour per IP - Prevents spam and abuse 3. **CSRF Protection** - Validates security tokens - Prevents cross-site request forgery 4. **Bot Protection in Handler** - Honeypot field detection - Timing validation (min 2 seconds) 5. **Input Validation** - Email format validation - Length restrictions - Header injection prevention - XSS protection via sanitization ## Environment Configuration ### Required Variables ```bash # SMTP Configuration (Gmail) SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your-email@gmail.com SMTP_PASSWORD=your-app-password SMTP_FROM_EMAIL=your-email@gmail.com CONTACT_EMAIL=txeo.msx@gmail.com ``` ### Gmail App Password Setup 1. Enable 2FA in your Google account 2. Visit: https://myaccount.google.com/apppasswords 3. Generate an App Password for "Mail" 4. Use the generated password in `SMTP_PASSWORD` **Important**: Never use your regular Gmail password - always use an App Password. ## API Endpoint ### POST /api/contact **Request Format:** ```http POST /api/contact Content-Type: application/x-www-form-urlencoded HX-Request: true Referer: http://yourdomain.com/ email=user@example.com &name=John Doe &company=Acme Inc &subject=Partnership Inquiry &message=Hello, I would like to discuss... &website= &submit_time=1701360000000 &csrf_token=abc123... ``` **Required Fields:** - `email` - Valid email address (max 254 chars) - `message` - Message text (10-5000 chars) **Optional Fields:** - `name` - Sender name (max 100 chars) - `company` - Company name (max 100 chars) - `subject` - Email subject (max 200 chars) **Special Fields:** - `website` - Honeypot (must be empty) - `submit_time` - Unix timestamp in milliseconds - `csrf_token` - CSRF token from cookie **Success Response (200):** ```html

Message Sent Successfully!

Thank you for reaching out...

``` **Error Responses:** - **403 Forbidden** - Non-browser client, CSRF failure, or rate limit - **400 Bad Request** - Validation error - **429 Too Many Requests** - Rate limit exceeded ## Testing ### Test 1: Curl Request (Should Fail - 403) ```bash curl -X POST http://localhost:1999/api/contact \ -d "email=test@example.com&message=Test" \ -w "\nStatus: %{http_code}\n" ``` **Expected:** `Forbidden: Browser access only` (403) ### Test 2: Postman Request (Should Fail - 403) ```bash curl -X POST http://localhost:1999/api/contact \ -H "User-Agent: PostmanRuntime/7.32.0" \ -H "Referer: http://localhost:1999/" \ -d "email=test@example.com&message=Test" \ -w "\nStatus: %{http_code}\n" ``` **Expected:** `Forbidden: Browser access only` (403) ### Test 3: Browser-like Request (Should Fail - CSRF) ```bash curl -X POST http://localhost:1999/api/contact \ -H "User-Agent: Mozilla/5.0 (Macintosh)" \ -H "Referer: http://localhost:1999/" \ -H "HX-Request: true" \ -d "email=test@example.com&message=Test" \ -w "\nStatus: %{http_code}\n" ``` **Expected:** CSRF validation error (403) ### Test 4: Complete Browser Request Use the test HTML file: `test_contact_form.html` ```bash # Start server go run main.go # Open in browser open http://localhost:1999/test_contact_form.html # Fill and submit form # Should succeed if SMTP credentials are configured ``` ## Integration Example ### HTML Contact Form ```html
``` ### JavaScript (Fetch API) ```javascript // Get CSRF token from cookie const csrfToken = document.cookie .split('; ') .find(row => row.startsWith('csrf_token=')) ?.split('=')[1]; const submitTime = Date.now(); // Wait at least 2 seconds before allowing submit setTimeout(() => { fetch('/api/contact', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded', 'X-Browser-Request': 'true' }, body: new URLSearchParams({ email: 'user@example.com', name: 'John Doe', message: 'Hello!', website: '', // Honeypot submit_time: submitTime, csrf_token: csrfToken }) }) .then(response => response.text()) .then(html => { document.getElementById('response').innerHTML = html; }); }, 2000); ``` ## Email Template The email sent to `CONTACT_EMAIL` follows this format: ``` Subject: [CV Contact] {subject or "New Message"} New contact form submission: From: user@example.com Name: John Doe Company: Acme Inc Subject: Partnership Inquiry Message: Hello, I would like to discuss a potential partnership... --- IP: 192.168.1.1 Time: 2025-11-30 13:45:22 UTC ``` ## Monitoring & Logging ### Security Events Logged 1. **Blocked Requests** - Non-browser User-Agents - Missing Referer/Origin - Missing browser headers - CSRF validation failures - Rate limit exceeded - Honeypot triggered - Form submitted too fast 2. **Successful Submissions** - Email sent successfully (logs email address and IP) 3. **Errors** - SMTP connection failures - Email sending errors - Template rendering errors ### Log Format ``` 2025/11/30 13:45:22 SECURITY: Blocked non-browser User-Agent from IP 192.168.1.1: curl/7.88.1 2025/11/30 13:45:23 SECURITY: CSRF validation failed from IP 192.168.1.2 2025/11/30 13:45:24 Contact form submitted successfully from user@example.com (192.168.1.3) ``` ## Production Deployment ### Checklist - [ ] Configure SMTP credentials in environment - [ ] Set `CONTACT_EMAIL` to your email address - [ ] Enable HTTPS (middleware automatically enables HSTS) - [ ] Configure `ALLOWED_ORIGINS` if using custom domain - [ ] Set up log monitoring - [ ] Test email delivery - [ ] Monitor rate limit statistics - [ ] Set up email delivery monitoring - [ ] Configure email bounce handling - [ ] Review security headers ### Production Environment ```bash # Production .env GO_ENV=production SMTP_HOST=smtp.gmail.com SMTP_PORT=587 SMTP_USER=your-email@gmail.com SMTP_PASSWORD=your-app-password CONTACT_EMAIL=your-email@gmail.com ALLOWED_ORIGINS=yourdomain.com,www.yourdomain.com ``` ## Troubleshooting ### Email Not Sending 1. **Check SMTP credentials** - Verify App Password is correct - Ensure 2FA is enabled on Google account 2. **Check logs** - Look for SMTP connection errors - Verify email service initialization 3. **Test SMTP connection** ```bash telnet smtp.gmail.com 587 ``` ### Rate Limiting Issues 1. **IP address detection** - Check `X-Forwarded-For` header if behind proxy - Verify IP extraction in logs 2. **Adjust limits** - Modify `limit` and `window` in `contact_rate_limit.go` - Default: 5 requests per hour ### CSRF Token Issues 1. **Token not set** - Ensure cookie is being set on GET requests - Check browser cookie settings 2. **Token mismatch** - Verify token is passed in form or header - Check token expiration (24 hours) ## Files Modified/Created ### New Files - `internal/services/email.go` - Email service with SMTP - `internal/handlers/contact.go` - Contact form handler - `internal/middleware/contact_rate_limit.go` - Rate limiting - `internal/middleware/csrf.go` - CSRF protection - `internal/middleware/browser_only.go` - Browser validation - `templates/partials/contact_success.html` - Success template - `templates/partials/contact_error.html` - Error template - `test_contact_form.html` - Test page ### Modified Files - `internal/config/config.go` - Added email configuration - `internal/routes/routes.go` - Registered contact endpoint - `main.go` - Initialized contact handler and email service - `.env.example` - Added email configuration example ## Security Considerations ### What's Protected Against ✅ **CSRF Attacks** - Token validation ✅ **Rate Limiting Bypass** - IP-based limiting ✅ **Bot Submissions** - Honeypot + timing + User-Agent ✅ **Email Header Injection** - Newline filtering ✅ **XSS** - Input sanitization ✅ **External API Access** - Browser-only enforcement ✅ **Spam** - Rate limiting + bot protection ✅ **Brute Force** - Rate limiting ### What's NOT Protected Against ⚠️ **Distributed Attacks** - Single-IP rate limiting only ⚠️ **Sophisticated Bots** - May bypass basic User-Agent checks ⚠️ **Email Bombing** - Recipient rate limiting not implemented ### Recommended Additions for Production 1. **CAPTCHA** - Add reCAPTCHA or hCaptcha 2. **Email Verification** - Verify sender's email address 3. **Advanced Bot Detection** - Integrate with services like Cloudflare 4. **Distributed Rate Limiting** - Use Redis for multi-server deployments 5. **Email Queue** - Use background job processor for email sending 6. **Delivery Monitoring** - Track email delivery success/failure 7. **Spam Detection** - Content-based spam filtering ## License & Reusability This implementation is designed to be reusable across projects. Feel free to: - Copy the entire `services/email.go` for email functionality - Reuse middleware components independently - Adapt the contact handler for your needs - Modify rate limits and validation rules All code follows Go best practices and is production-ready. ## Support For issues or questions: - Check the logs for detailed error messages - Review security event logs for blocked requests - Test with the included `test_contact_form.html` - Verify SMTP credentials are correct --- **Implementation Date:** November 30, 2025 **Version:** 1.0.0 **Author:** Backend Craftsman