> ## 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.

# Secure

> HTTPS enforcement and comprehensive security middleware.

## 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

```go theme={null}
import "github.com/go-mizu/mizu/middlewares/secure"
```

## Quick Start

```go theme={null}
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

```go theme={null}
// Redirect all HTTP to HTTPS
app.Use(secure.New())
```

### Production Configuration

```go theme={null}
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

```go theme={null}
app.Use(secure.WithOptions(secure.Options{
    IsDevelopment: true, // Disables all security features
}))
```

### Behind a Proxy

```go theme={null}
app.Use(secure.WithOptions(secure.Options{
    SSLRedirect: true,
    ProxyHeaders: []string{
        "X-Forwarded-Proto",
        "X-Forwarded-SSL",
    },
}))
```

### Custom SSL Host

```go theme={null}
// Redirect to different host
app.Use(secure.WithOptions(secure.Options{
    SSLRedirect: true,
    SSLHost:     "secure.example.com",
}))
```

### Temporary Redirect

```go theme={null}
// Use 307 for testing, preserves method
app.Use(secure.WithOptions(secure.Options{
    SSLRedirect:          true,
    SSLTemporaryRedirect: true,
}))
```

### Frame Options

```go theme={null}
// Allow framing from same origin
app.Use(secure.WithOptions(secure.Options{
    FrameDeny:          false,
    CustomFrameOptions: "SAMEORIGIN",
}))
```

### Environment-Based Configuration

```go theme={null}
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

```go theme={null}
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

```go theme={null}
// New creates middleware with default options
func New() mizu.Middleware

// WithOptions creates middleware with custom options
func WithOptions(opts Options) mizu.Middleware
```

## Headers Set

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:

1. **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

2. **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

3. **Security Header Application**: Sets headers conditionally based on:
   * Connection security (HTTPS vs HTTP)
   * Configuration options
   * Development mode (bypasses all security when IsDevelopment is true)

### Header Construction

**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:

```go theme={null}
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

### Performance Optimization

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

1. **HSTS Commitment** - Once set, browsers remember for max-age duration
2. **SSL Certificate** - Ensure valid certificate before enabling HSTS
3. **Subdomains** - Only enable STSIncludeSubdomains if all subdomains support HTTPS
4. **Preload** - Apply at hstspreload.org for browser built-in list

### HSTS Timeline

```go theme={null}
// 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/](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](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                                   |

## Related Middlewares

* [helmet](/middlewares/helmet) - Detailed security headers
* [redirect](/middlewares/redirect) - URL redirection
