Clickjacking in Chi (Go)
Clickjacking in Chi with Go — how this specific combination creates or exposes the vulnerability
Clickjacking is a client-side injection attack where an attacker tricks a user into clicking a transparent or disguised element within a page. In Chi, a common Go HTTP router, this often arises when middleware or handlers do not enforce frame-embedding protections. Chi itself does not set any frame-related headers, so if your application relies solely on Chi for request routing without adding security headers, browsers may render your pages inside an <iframe> on a malicious site. This enables attackers to layer invisible UI elements over your forms or links, causing users to perform unintended actions such as changing email addresses or confirming transactions.
Because Chi encourages modular middleware use, developers might omit a dedicated security middleware, leaving endpoints vulnerable. For example, a handler built with Chi that serves an HTML form without Content-Security-Policy frame-ancestors or X-Frame-Options allows any site to embed the page. When combined with social engineering, this can lead to unauthorized actions on behalf of the authenticated user. The risk is especially pronounced in SPAs or APIs that render server-side views, where developers assume Chi’s routing is sufficient for security.
Additionally, if your Chi application embeds third-party widgets or iframes, improper configuration can expose your UI to being framed by external domains. Attackers can craft a page that embeds your route (e.g., /transfer) inside an iframe and overlay buttons to trigger POST requests via CSRF, leveraging the absence of anti-CSRF tokens or SameSite cookies. In this context, Clickjacking in Chi with Go is not a flaw in Chi itself but a consequence of missing defenses around framing and embedding when building handlers and middleware stacks.
Go-Specific Remediation in Chi — concrete code fixes
Remediation centers on ensuring your Chi routes set appropriate HTTP headers and that templates avoid exposing interactive elements inside iframes. Below are concrete Go examples using chi/v5 that you can drop into your application.
1. Enforce X-Frame-Options and Content-Security-Policy
Add middleware that sets headers on every response. This prevents the browser from rendering your pages inside an untrusted frame.
// middleware/security.go
package middleware
import (
"net/http"
)
// SecureHeaders wraps a http.Handler to add security headers.
func SecureHeaders(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
// Prevent embedding in any frame
w.Header().Set("X-Frame-Options", "DENY")
// Modern alternative: restrict who can frame this page
w.Header().Set("Content-Security-Policy", "frame-ancestors 'self'")
next.ServeHTTP(w, r)
})
}
Apply this middleware to your Chi router:
// main.go
package main
import (
"net/http"
"github.com/go-chi/chi/v5"
"github.com/go-chi/chi/v5/middleware"
"yourproject/middleware"
)
func main() {
r := chi.NewRouter()
// Use built-in logging/recovery first
r.Use(middleware.Logger)
r.Use(middleware.Recoverer)
// Add security headers
r.Use(middleware.SecureHeaders)
r.Get("/transfer", func(w http.ResponseWriter, r *http.Request) {
w.Write([]byte(``))
})
http.ListenAndServe(":8080", r)
}
2. Avoid leaking handlers into third-party frames via CSP frame-ancestors
If you serve pages that include third-party widgets, be explicit about allowed parents. Use a policy that is as restrictive as possible.
w.Header().Set("Content-Security-Policy", "frame-ancestors 'self' https://trusted.example.com")
For APIs that return HTML snippets or server-rendered views, ensure you don’t embed user-controlled content directly into iframes without validating the parent origin. Combine SecureHeaders with CSRF protection (e.g., chi’s csrf middleware) to mitigate clickjacking-assisted CSRF.
3. Template-level precautions
In your HTML templates, avoid including interactive controls inside elements that could be overlaid. While this is more of a frontend concern, Go’s html/template auto-escaping helps prevent injection that could facilitate UI manipulation. Ensure you don’t output user content into srcdoc or allow arbitrary attributes that could be abused in an embedded context.