Token Leakage in Chi with Jwt Tokens
Token Leakage in Chi with Jwt Tokens — how this specific combination creates or exposes the vulnerability
Token leakage in Chi applications that use JWT tokens typically occurs when tokens are handled outside secure contexts or transmitted over non-encrypted channels. Chi, a lightweight HTTP web framework for the Crystal language, does not inherently manage token lifecycle; developers must implement secure storage and transmission practices. If JWT tokens are embedded in URLs, logged server-side, or transmitted without TLS, they become discoverable through logs, browser history, or network traffic. This is especially risky when endpoints do not enforce strict transport layer protections or when debugging endpoints expose headers in error messages.
JWT tokens carry identity and authorization claims, so exposure can lead to account takeover or privilege escalation. In Chi routes that accept tokens via headers, missing validation on token format or absence can cause the application to process requests as authenticated when they are not. MiddleBrick’s checks for Data Exposure and Authentication align with this risk, identifying whether tokens are leaked through verbose responses or weak transport configurations. An unauthenticated scan can detect whether token-bearing responses are transmitted over non-encrypted channels or reflected in server responses, providing a security risk score and findings mapped to OWASP API Top 10 and relevant compliance frameworks.
Developers using Chi must ensure JWT tokens are transmitted only via HTTPS and stored in secure, HttpOnly cookies or secure client-side storage with strict SameSite and Secure flags. Tokens should never appear in query strings or logs. MiddleBrick’s scan can verify whether endpoints leak tokens in plain text or allow enumeration via error handling, helping teams identify insecure routing or middleware configurations before deployment.
Jwt Tokens-Specific Remediation in Chi — concrete code fixes
To remediate token leakage in Chi, enforce HTTPS for all routes and ensure JWT tokens are never transmitted in URLs. Use secure cookies for token storage when possible, and validate token presence and structure before processing requests. Below are concrete code examples for a Chi application that sets and verifies JWT tokens securely.
using HTTP::Server::Router
using JWT::Mac
# Secure token generation and setting via HttpOnly cookie
def generate_token(payload : Hash(String, JSON::Any)) : String
secret = ENV.fetch("JWT_SECRET", "fallback_secret_key_change_in_prod")
JWT::Mac.generate(HMAC-SHA256, secret, payload)
end
router = HTTP::Server::Router.new
router.post("/login") do |context|
username = context.request.query_params["username"]? || ""
password = context.request.query_params["password"]? || ""
if username == "admin" && password == "secure_password"
token = generate_token({ "sub" => username, "role" => "admin" })
context.response.headers["Set-Cookie"] = "token=#{token}; HttpOnly; Secure; SameSite=Strict; Path=/"
context.response.content_type = "application/json"
context.response.print({ "status" => "authenticated" }.to_json)
else
context.response.status_code = 401
context.response.print({ "error" => "invalid_credentials" }.to_json)
end
end
# Middleware to verify token from secure cookie
router.before do |context|
excluded = ["/login"]
unless excluded.includes?(context.request.path)
cookie_header = context.request.headers["Cookie"]? || ""
token = cookie_header.split("; ").find_map { |c| c.split("=").last if c.starts_with?("token") }
unless token && verify_token(token)
context.response.status_code = 401
context.response.print({ "error" => "unauthorized" }.to_json)
context.response.finish
end
end
end
def verify_token(token : String) : Bool
secret = ENV.fetch("JWT_SECRET", "fallback_secret_key_change_in_prod")
begin
JWT::Mac.verify(HMAC-SHA256, secret, token)
true
rescue
false
end
end
router.get("/secure-data") do |context|
context.response.content_type = "application/json"
context.response.print({ "data" => "protected_resource" }.to_json)
end
HTTP::Server.new([router]).listen(8080)
This example avoids placing tokens in query parameters and uses HttpOnly, Secure, SameSite cookies to reduce exposure via JavaScript or network interception. The verification middleware ensures that only requests with valid tokens can access protected routes, aligning with Authentication and Data Exposure checks. Transport security must be enforced at the infrastructure level with TLS to prevent interception. MiddleBrick scans can confirm that such secure patterns are in place and flag any endpoints that accept tokens in less safe locations.