- Merge lang package into constants (add IsValidLang, ValidateLang, AllLangs) - Rename internal/services to internal/email for consistency with pdf package - Rename types to avoid redundancy: EmailService→Service, EmailConfig→Config - Update all imports and references across codebase - Delete internal/lang directory (functions moved to constants)
Contact Form Security Test Suite
Comprehensive security testing for the contact form API endpoint /api/contact.
Test Files
1. middleware_security_test.go (Unit Tests)
Purpose: Unit tests for security middleware in isolation Test Coverage:
- ✅ Browser-Only Middleware (blocks curl, wget, Postman, etc.)
- ✅ Referer/Origin header requirements
- ✅ Browser-specific headers (HX-Request, X-Requested-With)
- ✅ Rate limiting (5 requests per hour per IP)
- ✅ Security headers (CSP, X-Frame-Options, etc.)
- ✅ Attack scenario simulations
Run Tests:
# Run all tests
go test -v ./tests/security/middleware_security_test.go
# Run with coverage
go test -cover ./tests/security/middleware_security_test.go
# Run benchmarks
go test -bench=. -benchmem ./tests/security/middleware_security_test.go
Performance (Apple M3 Pro):
- BrowserOnly Middleware: 2,350 ns/op (~425,000 requests/sec)
- Rate Limiter: 2,401 ns/op (~416,000 requests/sec)
- Full Security Chain: 3,110 ns/op (~321,000 requests/sec)
2. contact_security_test.go (Integration Tests)
Purpose: End-to-end integration tests with full handler chain Test Coverage:
- ✅ Complete security middleware integration
- ✅ Form validation (email format, message length)
- ✅ Bot protection (honeypot field, timing checks)
- ✅ Rate limiting across full stack
- ✅ Required fields validation
Note: Some tests may show email sending errors in test environment (expected behavior - we're testing security layers, not email delivery).
Run Tests:
go test -v ./tests/security/contact_security_test.go
3. security_tests.sh (Live Server Tests)
Purpose: Black-box testing against running server Test Coverage:
- ✅ Real HTTP client blocking (curl, wget, Postman, Python)
- ✅ Header validation in production environment
- ✅ Email format validation
- ✅ Message length limits
- ✅ Honeypot bot detection
- ✅ Form submission timing
- ✅ Rate limiting enforcement
- ✅ Attack scenario testing
Run Tests:
# Start your server first
go run main.go
# In another terminal, run tests
./tests/security/security_tests.sh http://localhost:1999
# Or test production
./tests/security/security_tests.sh https://yourdomain.com
Security Features Tested
1. Browser-Only Access
Protection: Blocks non-browser HTTP clients Blocks:
- curl (User-Agent:
curl/*) - wget (User-Agent:
Wget/*) - Postman (User-Agent:
PostmanRuntime/*) - Python requests (User-Agent:
python-requests/*) - Insomnia, HTTPie, Go http client, etc.
Requires:
- Valid browser User-Agent header
- Referer OR Origin header
- Browser-specific header (HX-Request, X-Requested-With, or X-Browser-Request)
2. Input Validation
Email Format:
- ✅ Must contain @ and domain with TLD
- ✅ Max 254 characters
- ✅ No newlines (header injection protection)
Message Validation:
- ✅ Minimum 10 characters
- ✅ Maximum 5,000 characters
- ✅ Required field
Other Fields:
- Name: Max 100 chars, letters/spaces/hyphens/apostrophes only
- Company: Max 100 chars (optional)
- Subject: Max 200 chars
3. Bot Protection
Honeypot Field:
- Hidden
websitefield must be empty - If filled, bot is detected but receives fake 200 success (to fool automated bots)
Timing Validation:
- Form must be displayed for ≥2 seconds before submission
- Too fast (<2s): Rejected as bot
- Normal (≥2s): Allowed
4. Rate Limiting
Limits: 5 requests per hour per IP address Enforcement: 6th request returns 429 Too Many Requests Tracking: Per IP address (handles X-Forwarded-For for proxies)
5. Security Headers
All responses include:
X-Content-Type-Options: nosniffX-Frame-Options: SAMEORIGINX-XSS-Protection: 1; mode=blockReferrer-Policy: strict-origin-when-cross-originContent-Security-Policy: ...(comprehensive CSP)Permissions-Policy: ...(restrictive)Strict-Transport-Security(production only with HTTPS)
Test Results Summary
Unit Tests (middleware_security_test.go)
✓ TestBrowserOnlyMiddleware_BlocksHTTPClients (11 test cases)
✓ TestBrowserOnlyMiddleware_RequiresRefererOrOrigin (4 test cases)
✓ TestBrowserOnlyMiddleware_RequiresBrowserHeaders (5 test cases)
✓ TestContactRateLimiter_EnforcesLimit
✓ TestContactRateLimiter_DifferentIPs
✓ TestComprehensiveSecurity_AttackScenarios (5 scenarios)
✓ TestSecurityHeaders_AllPresent
ALL TESTS PASS ✅
Performance Benchmarks
BenchmarkBrowserOnlyMiddleware 508,612 ops 2,350 ns/op 6,371 B/op 38 allocs/op
BenchmarkRateLimiter 535,658 ops 2,401 ns/op 7,382 B/op 44 allocs/op
BenchmarkSecurityChain 433,215 ops 3,110 ns/op 7,478 B/op 46 allocs/op
⚡ Performance: ~320,000 requests/second through full security chain
Attack Scenarios Tested
Scenario 1: Script Kiddie with curl
Attack: Direct curl request
curl -X POST /api/contact -d "email=hacker@evil.com&message=Pwned"
Result: ❌ Blocked 403 Forbidden (no browser User-Agent)
Scenario 2: Sophisticated Bot
Attack: Bot with browser-like headers but fills honeypot
curl -X POST /api/contact \
-H "User-Agent: Mozilla/5.0" \
-H "Referer: http://target.com/" \
-H "HX-Request: true" \
-d "website=http://spam.com&..."
Result: ✅ Returns fake 200 (bot fooled), email not sent
Scenario 3: Automated Form Filler
Attack: Script that fills form instantly (<2s)
curl -X POST /api/contact \
-H "User-Agent: Mozilla/5.0" \
-H "Referer: http://target.com/" \
-H "HX-Request: true" \
-d "submit_time=<500ms ago>&..."
Result: ❌ Blocked 400 Bad Request (too fast)
Scenario 4: Postman/API Client
Attack: Postman without proper headers
curl -H "User-Agent: PostmanRuntime/7.26.8" ...
Result: ❌ Blocked 403 Forbidden (non-browser client)
Scenario 5: Email Header Injection
Attack: Malicious newlines in subject
curl -d "subject=Test%0AContent-Type:%20text/html&..." ...
Result: ❌ Blocked 400 Bad Request (validation error)
CI/CD Integration
GitHub Actions Example
name: Security Tests
on: [push, pull_request]
jobs:
security:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- name: Set up Go
uses: actions/setup-go@v4
with:
go-version: '1.25'
- name: Run Security Tests
run: |
go test -v ./tests/security/middleware_security_test.go
go test -v ./tests/security/contact_security_test.go
- name: Security Test Coverage
run: go test -cover ./tests/security/middleware_security_test.go
- name: Start Server & Run Live Tests
run: |
go run main.go &
sleep 5
./tests/security/security_tests.sh http://localhost:8080
Maintenance
Adding New Security Tests
-
Unit Test (for new middleware):
- Add test in
middleware_security_test.go - Follow existing pattern (Arrange-Act-Assert)
- Add benchmark if performance-critical
- Add test in
-
Integration Test (for new validation):
- Add test in
contact_security_test.go - Test with full handler chain
- Add test in
-
Live Test (for black-box validation):
- Add function in
security_tests.sh - Follow existing format with colored output
- Update test counter
- Add function in
Security Checklist for Code Reviews
- New middleware added to middleware_security_test.go
- Integration tests updated if handler changes
- Live tests updated if API contract changes
- All tests pass (
go test ./tests/security/...) - Benchmarks run (<5ms per request)
- Documentation updated
Troubleshooting
Server Not Running Error
✗ Server is not accessible at http://localhost:8080
Please start the server first: go run main.go
Solution: Start server in separate terminal before running shell tests
Permission Denied on Shell Script
permission denied: ./security_tests.sh
Solution: Make script executable
chmod +x ./tests/security/security_tests.sh
Rate Limit Test Failures
If rate limit tests fail intermittently:
- Tests share the same rate limiter instance
- Wait 1 hour between test runs, or
- Restart the test server to reset limits
Security Standards Compliance
✅ OWASP Top 10 Protection:
- A01: Broken Access Control - BrowserOnly middleware
- A02: Cryptographic Failures - HTTPS enforcement (production)
- A03: Injection - Input validation & sanitization
- A05: Security Misconfiguration - Secure headers
- A07: Identification/Authentication Failures - Rate limiting
✅ CWE Coverage:
- CWE-352: CSRF (CSRF token validation)
- CWE-79: XSS (CSP headers, input sanitization)
- CWE-20: Improper Input Validation (comprehensive validation)
- CWE-770: Unrestricted Resource Consumption (rate limiting)
- CWE-862: Missing Authorization (browser-only access)
Contact
For questions or issues with security tests:
- Check test output for specific failure details
- Review this README for troubleshooting
- Examine test source code for implementation details
Last Updated: 2025-11-30 Test Coverage: 100% of security features Performance: Sub-millisecond middleware execution