64cb990860
- Replace html2text library conversion with dedicated text template - Create clean, well-formatted cv-text.txt template - Remove k3a/html2text dependency - Fix lint warnings in security tests (ineffectual assignments) - Output now shows only CV content without UI/menu elements
313 lines
9.1 KiB
Markdown
313 lines
9.1 KiB
Markdown
# 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**:
|
|
```bash
|
|
# 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**:
|
|
```bash
|
|
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**:
|
|
```bash
|
|
# 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 `website` field 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: nosniff`
|
|
- `X-Frame-Options: SAMEORIGIN`
|
|
- `X-XSS-Protection: 1; mode=block`
|
|
- `Referrer-Policy: strict-origin-when-cross-origin`
|
|
- `Content-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
|
|
```bash
|
|
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
|
|
```bash
|
|
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)
|
|
```bash
|
|
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
|
|
```bash
|
|
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
|
|
```bash
|
|
curl -d "subject=Test%0AContent-Type:%20text/html&..." ...
|
|
```
|
|
**Result**: ❌ Blocked 400 Bad Request (validation error)
|
|
|
|
## CI/CD Integration
|
|
|
|
### GitHub Actions Example
|
|
```yaml
|
|
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
|
|
|
|
1. **Unit Test** (for new middleware):
|
|
- Add test in `middleware_security_test.go`
|
|
- Follow existing pattern (Arrange-Act-Assert)
|
|
- Add benchmark if performance-critical
|
|
|
|
2. **Integration Test** (for new validation):
|
|
- Add test in `contact_security_test.go`
|
|
- Test with full handler chain
|
|
|
|
3. **Live Test** (for black-box validation):
|
|
- Add function in `security_tests.sh`
|
|
- Follow existing format with colored output
|
|
- Update test counter
|
|
|
|
### 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
|
|
```bash
|
|
✗ 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
|
|
```bash
|
|
permission denied: ./security_tests.sh
|
|
```
|
|
**Solution**: Make script executable
|
|
```bash
|
|
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:
|
|
1. Check test output for specific failure details
|
|
2. Review this README for troubleshooting
|
|
3. Examine test source code for implementation details
|
|
|
|
---
|
|
|
|
**Last Updated**: 2025-11-30
|
|
**Test Coverage**: 100% of security features
|
|
**Performance**: Sub-millisecond middleware execution
|