Documentation Index
Fetch the complete documentation index at: https://docs.go-mizu.dev/llms.txt
Use this file to discover all available pages before exploring further.
Overview
The secure middleware enforces HTTPS connections and adds security headers. It’s a comprehensive security solution that combines SSL redirect with security header management.
Use it when you need:
- Automatic HTTP to HTTPS redirect
- Security headers in one middleware
- Flexible security configuration
- Development/production toggle
Installation
import "github.com/go-mizu/mizu/middlewares/secure"
Quick Start
app := mizu.New()
// Default security settings
app.Use(secure.New())
Configuration
Options
| Option | Type | Default | Description |
|---|
SSLRedirect | bool | true | Redirect HTTP to HTTPS |
SSLHost | string | "" | Host for SSL redirect |
SSLTemporaryRedirect | bool | false | Use 307 instead of 301 |
STSSeconds | int64 | 0 | HSTS max-age (0 = disabled) |
STSIncludeSubdomains | bool | false | HSTS includeSubDomains |
STSPreload | bool | false | HSTS preload |
ForceSTSHeader | bool | false | Send HSTS on HTTP |
ContentTypeNosniff | bool | true | X-Content-Type-Options |
FrameDeny | bool | true | X-Frame-Options: DENY |
CustomFrameOptions | string | "" | Custom X-Frame-Options |
XSSProtection | string | "1; mode=block" | X-XSS-Protection |
ContentSecurityPolicy | string | "" | CSP header |
ReferrerPolicy | string | "" | Referrer-Policy |
IsDevelopment | bool | false | Disable all features |
ProxyHeaders | []string | ["X-Forwarded-Proto"] | Headers for HTTPS detection |
Examples
Basic HTTPS Redirect
// Redirect all HTTP to HTTPS
app.Use(secure.New())
Production Configuration
app.Use(secure.WithOptions(secure.Options{
SSLRedirect: true,
STSSeconds: 31536000, // 1 year
STSIncludeSubdomains: true,
STSPreload: true,
ContentTypeNosniff: true,
FrameDeny: true,
ContentSecurityPolicy: "default-src 'self'",
ReferrerPolicy: "strict-origin-when-cross-origin",
}))
Development Mode
app.Use(secure.WithOptions(secure.Options{
IsDevelopment: true, // Disables all security features
}))
Behind a Proxy
app.Use(secure.WithOptions(secure.Options{
SSLRedirect: true,
ProxyHeaders: []string{
"X-Forwarded-Proto",
"X-Forwarded-SSL",
},
}))
Custom SSL Host
// Redirect to different host
app.Use(secure.WithOptions(secure.Options{
SSLRedirect: true,
SSLHost: "secure.example.com",
}))
Temporary Redirect
// Use 307 for testing, preserves method
app.Use(secure.WithOptions(secure.Options{
SSLRedirect: true,
SSLTemporaryRedirect: true,
}))
Frame Options
// Allow framing from same origin
app.Use(secure.WithOptions(secure.Options{
FrameDeny: false,
CustomFrameOptions: "SAMEORIGIN",
}))
Environment-Based Configuration
func setupSecurity(app *mizu.App) {
isDev := os.Getenv("ENV") == "development"
app.Use(secure.WithOptions(secure.Options{
IsDevelopment: isDev,
SSLRedirect: !isDev,
STSSeconds: 31536000,
STSIncludeSubdomains: true,
ContentTypeNosniff: true,
FrameDeny: true,
}))
}
Full Security Setup
app.Use(secure.WithOptions(secure.Options{
// SSL
SSLRedirect: true,
SSLTemporaryRedirect: false,
// HSTS
STSSeconds: 31536000,
STSIncludeSubdomains: true,
STSPreload: true,
// Security Headers
ContentTypeNosniff: true,
FrameDeny: true,
XSSProtection: "1; mode=block",
ContentSecurityPolicy: "default-src 'self'; script-src 'self'",
ReferrerPolicy: "strict-origin-when-cross-origin",
// Proxy support
ProxyHeaders: []string{"X-Forwarded-Proto"},
}))
API Reference
Functions
// New creates middleware with default options
func New() mizu.Middleware
// WithOptions creates middleware with custom options
func WithOptions(opts Options) mizu.Middleware
The middleware sets these headers based on configuration:
| Header | Condition | Value |
|---|
Strict-Transport-Security | STSSeconds > 0 | max-age=X; includeSubDomains; preload |
X-Content-Type-Options | ContentTypeNosniff | nosniff |
X-Frame-Options | FrameDeny or Custom | DENY or custom |
X-XSS-Protection | XSSProtection set | Configured value |
Content-Security-Policy | CSP set | Configured policy |
Referrer-Policy | ReferrerPolicy set | Configured policy |
Technical Details
Implementation Overview
The secure middleware implements a comprehensive security layer that:
-
HTTPS Detection: Checks for secure connections via:
- Direct TLS connection (r.TLS != nil)
- Proxy headers (X-Forwarded-Proto, X-Forwarded-SSL, etc.)
- Case-insensitive header matching using strings.EqualFold
-
SSL Redirection: When HTTP is detected and SSLRedirect is enabled:
- Constructs HTTPS URL:
https:// + host + requestURI
- Uses SSLHost if specified, otherwise uses request host
- Returns 301 (permanent) or 307 (temporary) redirect based on SSLTemporaryRedirect
-
Security Header Application: Sets headers conditionally based on:
- Connection security (HTTPS vs HTTP)
- Configuration options
- Development mode (bypasses all security when IsDevelopment is true)
Strict-Transport-Security (HSTS):
max-age=<STSSeconds>[; includeSubDomains][; preload]
- Only set on HTTPS connections unless ForceSTSHeader is true
- Requires STSSeconds > 0 to be enabled
X-Frame-Options:
- Priority: CustomFrameOptions > FrameDeny > none
- FrameDeny sets “DENY”, CustomFrameOptions allows “SAMEORIGIN” or other values
Default Headers (when using New()):
- X-Content-Type-Options: nosniff
- X-Frame-Options: DENY
- X-XSS-Protection: 1; mode=block
- SSLRedirect: enabled
Proxy Support
The middleware checks proxy headers in order:
for _, header := range opts.ProxyHeaders {
if strings.EqualFold(r.Header.Get(header), "https") {
isSSL = true
break
}
}
Common proxy headers:
- X-Forwarded-Proto (default)
- X-Forwarded-SSL
- Front-End-Https
The middleware uses a custom itoa function instead of strconv.Itoa for integer-to-string conversion:
- Avoids heap allocations
- Uses fixed-size array [20]byte for conversion
- Handles negative numbers and zero efficiently
Security Considerations
- HSTS Commitment - Once set, browsers remember for max-age duration
- SSL Certificate - Ensure valid certificate before enabling HSTS
- Subdomains - Only enable STSIncludeSubdomains if all subdomains support HTTPS
- Preload - Apply at hstspreload.org for browser built-in list
HSTS Timeline
// Start with short duration
app.Use(secure.WithOptions(secure.Options{
STSSeconds: 3600, // 1 hour for testing
}))
// Increase gradually
// STSSeconds: 86400 // 1 day
// STSSeconds: 604800 // 1 week
// STSSeconds: 31536000 // 1 year (production)
Best Practices
- Start with short HSTS duration, increase gradually
- Test thoroughly before enabling preload
- Use
IsDevelopment flag for local development
- Configure
ProxyHeaders when behind load balancers
Testing
The secure middleware includes comprehensive test coverage for all features:
| Test Case | Description | Expected Behavior |
|---|
TestNew | Default middleware with SSL redirect | Redirects HTTP to HTTPS with 301 status, Location header set to https://example.com/ |
TestWithOptions_NoSSLRedirect | Middleware with SSL redirect disabled but security headers enabled | Returns 200 OK, sets X-Content-Type-Options: nosniff, X-Frame-Options: DENY, X-XSS-Protection: 1; mode=block |
TestWithOptions_HSTS | HSTS configuration with all options enabled | Sets Strict-Transport-Security header with max-age=31536000; includeSubDomains; preload |
TestWithOptions_CustomFrameOptions | Custom frame options instead of default DENY | Sets X-Frame-Options: SAMEORIGIN |
TestWithOptions_CSP | Content Security Policy configuration | Sets Content-Security-Policy: default-src ‘self’ |
TestWithOptions_ReferrerPolicy | Referrer policy configuration | Sets Referrer-Policy: strict-origin-when-cross-origin |
TestWithOptions_SSLHost | SSL redirect to custom host with temporary redirect | Redirects with 307 status to https://secure.example.com/path?q=1 |
TestWithOptions_ProxyHeader | Request behind proxy with X-Forwarded-Proto: https | Does not redirect (200 OK) since connection is detected as HTTPS via proxy header |
TestWithOptions_IsDevelopment | Development mode enabled | Bypasses all security features, returns 200 OK without redirect or headers |