HIGH container escapechijwt tokens

Container Escape in Chi with Jwt Tokens

Container Escape in Chi with Jwt Tokens — how this specific combination creates or exposes the vulnerability

A container escape in a service built with the Chi router typically involves an attacker who has compromised an application process inside a container leveraging a server-side request forgery (SSRF) or path traversal to reach the container runtime socket. When the application also uses JWT tokens for authorization, the interaction can amplify impact if token validation is weak or if the runtime exposes administrative endpoints that accept tokens from the container host. For example, a handler that forwards requests to a metadata service or a local Kubernetes API might inadvertently allow an authenticated request with a valid JWT token to trigger a call to the Docker socket (/var/run/docker.sock), enabling an attacker to create privileged containers or mount host paths. This becomes a container escape when the attacker uses the valid JWT token to access an endpoint that the developer assumed was internal and therefore safe, but the runtime exposes it to the container’s network namespace. Chi’s composable middleware makes it straightforward to define routes that chain handlers; if one of those handlers performs unchecked HTTP calls or file operations based on claims in a JWT token, an attacker can chain an input validation flaw with a misconfigured network to achieve escape. Common patterns include insecure use of http.Client to reach http://localhost:15000 or the Docker API, where the service trusts JWT-based client certificates or bearer tokens without revalidating scope or audience. In secure designs, JWT tokens should never implicitly grant host-level operations; the container boundary must be enforced by runtime policies, not by token validity alone. middleBrick’s scans detect endpoints that accept JWT tokens and then interact with host services, highlighting risks where authentication bypasses network isolation. Attack patterns such as path traversal (e.g., ../../../var/run/docker.sock) combined with a trusted JWT can lead to container escapes, exposing sensitive host resources. The interplay of Chi routing, JWT handling, and container networking creates a scenario where an authenticated request can traverse trust boundaries that should have been enforced by the container runtime.

Jwt Tokens-Specific Remediation in Chi — concrete code fixes

To mitigate container escape risks when using JWT tokens in Chi, enforce strict validation, avoid forwarding tokens to internal services, and isolate runtime interactions behind network policies. Below are concrete code examples that demonstrate secure handling of JWT tokens in a Chi application.

1. Validate JWT tokens with strict claims and audience scope

Always verify the issuer, audience, and expiration before using claims. Do not trust tokens for host-level operations.

package main

import (
	"context"
	"net/http"

	"github.com/dgrijalva/jwt-go"
	"github.com/go-chi/chi/v5"
	"github.com/go-chi/chi/v5/middleware"
)

type Claims struct {
	Scope string `json:"scope"`
	jwt.StandardClaims
}

func validateToken(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		auth := r.Header.Get("Authorization")
		if auth == "" {
			http.Error(w, "missing authorization", http.StatusUnauthorized)
			return
		}
		tokenStr := auth[len("Bearer "):]
		token, err := jwt.ParseWithClaims(tokenStr, &Claims{}, func(token *jwt.Token) (interface{}, error) {
			// Use a secure key source in production
			return []byte("secret-key"), nil
		})
		if err != nil || !token.Valid {
			http.Error(w, "invalid token", http.StatusUnauthorized)
			return
		}
		claims, ok := token.Claims.(*Claims)
		if !ok || claims.Audience != "my-api" || claims.Scope != "container:read" {
			http.Error(w, "insufficient scope", http.StatusForbidden)
			return
		}
		ctx := context.WithValue(r.Context(), "claims", claims)
		next.ServeHTTP(w, r.WithContext(ctx))
	})
}

func handler(w http.ResponseWriter, r *http.Request) {
	claims := r.Context().Value("claims").(*Claims)
	http.Fprintf(w, "Hello %s, scope: %s", claims.Subject, claims.Scope)
}

func main() {
	r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(validateToken)
	r.Get("/hello", handler)
	http.ListenAndServe(":8080", r)
}

2. Avoid forwarding requests to host services when authenticated with JWT

Do not construct URLs from user input or JWT claims that point to internal endpoints such as the Docker API. If you must call internal services, use a predefined allowlist and enforce network segmentation.

package main

import (
	"context"
	"fmt"
	"net/http"
	"net/url"

	"github.com/go-chi/chi/v5"
)

func safeProxy() http.HandlerFunc {
	allowedHost := "https://api.example.com"
	return func(w http.ResponseWriter, r *http.Request) {
		base, err := url.Parse(allowedHost)
		if err != nil {
			http.Error(w, "internal error", http.StatusInternalServerError)
			return
		}
		reqURL := base.JoinPath(r.URL.Path)
		req, err := http.NewRequestWithContext(r.Context(), r.Method, reqURL.String(), r.Body)
		if err != nil {
			http.Error(w, "bad request", http.StatusBadRequest)
			return
		}
		// Copy only safe headers; do not forward Authorization if not intended
		req.Header.Set("X-Forwarded-For", r.Header.Get("X-Forwarded-For"))
		resp, err := http.DefaultClient.Do(req)
		if err != nil {
			http.Error(w, "upstream error", http.StatusBadGateway)
			return
		}
		defer resp.Body.Close()
		for k, vv := range resp.Header {
			for _, v := range vv {
				w.Header().Add(k, v)
			}
		}
		w.WriteHeader(resp.StatusCode)
		// copy body omitted for brevity
	}
}

func main() {
	r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Get("/proxy/*", safeProxy())
	http.ListenAndServe(":8080", r)
}

3. Enforce network policies to protect runtime sockets

Even with proper JWT validation, ensure that containers do not have access to the Docker socket unless explicitly required. Use Kubernetes Pod Security Standards or Docker runtime options to restrict socket access. Do not mount /var/run/docker.sock into application containers unless the container is dedicated to orchestration tasks and the JWT scope is tightly limited to that role.

4. Use middleware to reject tokens with excessive claims

Implement a Chi middleware that inspects JWT claims and rejects tokens that grant broad or host-related permissions. This prevents attackers from using a valid token to escalate to container operations.

package main

import (
	"net/http"

	"github.com/go-chi/chi/v5"
)

func jwtScopeMiddleware(next http.Handler) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		claims, ok := r.Context().Value("claims").(*Claims)
		if !ok {
			http.Error(w, "unauthorized", http.StatusUnauthorized)
			return
		}
		// Example: reject tokens that imply host-level operations
		if claims.Scope == "" || claims.Scope == "*" {
			http.Error(w, "token scope too broad", http.StatusForbidden)
			return
		}
		next.ServeHTTP(w, r)
	})
}

func main() {
	r := chi.NewRouter()
	r.Use(middleware.RequestID)
	r.Use(middleware.RealIP)
	r.Use(jwtScopeMiddleware)
	r.Use(validateToken)
	r.Get("/safe", func(w http.ResponseWriter, r *http.Request) {
		w.Write([]byte("ok"))
	})
	http.ListenAndServe(":8080", r)
}

Frequently Asked Questions

Why should JWT tokens never be used to authorize calls to the Docker socket?
Using JWT tokens to authorize calls to the Docker socket can enable container escape if an attacker compromises token validation or routes. Tokens should define application-level permissions only; host-level operations must be controlled by runtime policies like Pod Security Standards and network isolation, not by token claims.
How does middleBrick help detect risks related to JWT tokens and container interactions?
middleBrick scans API endpoints that accept JWT tokens and identifies interactions with host services, such as calls to internal endpoints or the Docker socket. It highlights findings where authentication does not align with network boundaries, providing remediation guidance to validate tokens strictly and avoid forwarding requests to runtime interfaces.