Jwt Misconfiguration in Echo Go
How Jwt Misconfiguration Manifests in Echo Go
Jwt misconfiguration in Echo Go applications typically manifests through several critical security vulnerabilities that stem from improper token handling, weak signing algorithms, or inadequate middleware configuration. The most common manifestation occurs when developers use weak signing algorithms like HS256 with exposed secrets or fail to validate token claims properly.
A classic Echo Go Jwt misconfiguration appears when middleware is improperly configured to accept any token without proper issuer validation. Consider this vulnerable pattern:
func main() {
e := echo.New()
// VULNERABLE: No issuer validation
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
SigningKey: []byte("weak-secret"),
Claims: &models.JwtCustomClaims{},
}))
e.Start(":1323")
}This configuration allows attackers to craft tokens using any issuer, potentially bypassing authorization controls. Another manifestation involves improper audience validation, where tokens meant for one service are accepted by another due to missing audience checks.
Echo Go's Jwt misconfiguration also appears in token refresh logic. Developers often implement insecure refresh mechanisms that don't validate the original token's claims or use predictable refresh tokens:
func refresh(c echo.Context) error {
// VULNERABLE: No validation of original token claims
oldToken := c.Get("user").(*jwt.Token)
newToken := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
"sub": oldToken.Claims.(jwt.MapClaims)["sub"],
"exp": time.Now().Add(time.Hour * 72).Unix(),
})
token, _ := newToken.SignedString([]byte("secret"))
return c.JSON(http.StatusOK, echo.Map{"token": token})
}The most dangerous Echo Go Jwt misconfiguration involves missing token expiration validation. When developers disable expiration checks or use very long expiration times, attackers can exploit stolen tokens indefinitely:
func validateToken(tokenString string, key interface{}) (*jwt.Token, error) {
// VULNERABLE: Missing expiration validation
token, err := jwt.ParseWithClaims(tokenString, &models.JwtCustomClaims{},
func(token *jwt.Token) (interface{}, error) {
return key, nil
})
return token, err
}Echo Go-Specific Detection
Detecting Jwt misconfiguration in Echo Go applications requires both static code analysis and runtime scanning. The most effective approach combines middleBrick's automated scanning with manual code review focused on Echo Go's Jwt middleware patterns.
middleBrick's Jwt misconfiguration detection for Echo Go specifically targets these patterns:
# Scan an Echo Go API endpoint
middlebrick scan https://api.example.com --output json
# Results will show Jwt-specific findings:
{
"jwt_misconfiguration": {
"severity": "high",
"finding": "Weak signing algorithm detected (HS256 with exposed secret)",
"remediation": "Use RS256 with private key stored in environment variables",
"line_numbers": [42, 58]
}
}Manual detection should focus on Echo Go's middleware configuration files. Look for these red flags in your main.go or middleware setup:
- Hardcoded secrets in JwtConfig struct
- Missing Claims validation in middleware.JWTWithConfig
- Unrestricted token issuers or audiences
- Disabled expiration checks
- Predictable refresh token logic
- Missing token blacklisting mechanisms
Echo Go's Jwt misconfiguration often hides in custom claim structures. When developers create JwtCustomClaims without proper validation, attackers can exploit missing field checks:
type JwtCustomClaims struct {
jwt.StandardClaims
UserID string `json:"user_id"`
Role string `json:"role"`
// VULNERABLE: Missing validation methods
}
func (claims *JwtCustomClaims) Valid() error {
// MUST implement validation for all custom claims
return nil // INSECURE: always returns nil
}Runtime detection involves testing token manipulation. Echo Go applications with Jwt misconfiguration often accept tokens with modified claims, altered expiration times, or forged issuers. Use tools like jwt.io to craft test tokens and observe how your Echo Go application handles them.
Echo Go-Specific Remediation
Remediating Jwt misconfiguration in Echo Go requires implementing proper token validation, secure key management, and robust middleware configuration. The foundation is using asymmetric signing algorithms with properly secured private keys.
Secure Echo Go Jwt configuration:
import (
"github.com/labstack/echo/v4/middleware"
"github.com/golang-jwt/jwt/v5"
"time"
)
func secureJWTMiddleware() echo.MiddlewareFunc {
return middleware.JWTWithConfig(middleware.JWTConfig{
SigningMethod: "RS256",
ContextKey: "user",
Claims: &models.JwtCustomClaims{},
TokenLookup: "header:Authorization",
AuthScheme: "Bearer",
// Secure key loading from environment
SigningKeys: map[string]interface{}{
"public.pem": loadPublicKey("public.pem"),
},
// Critical: validate issuer and audience
Validate: func(claims jwt.Claims) error {
jwtClaims, ok := claims.(*models.JwtCustomClaims)
if !ok {
return errors.New("invalid claims type")
}
// Validate issuer
if jwtClaims.Issuer != "your-service.com" {
return errors.New("invalid issuer")
}
// Validate audience
if !contains(jwtClaims.Audience, "your-api.com") {
return errors.New("invalid audience")
}
// Validate expiration
if jwtClaims.ExpiresAt < time.Now().Unix() {
return errors.New("token expired")
}
return nil
},
})
}Implement secure token refresh with proper validation:
func refresh(c echo.Context) error {
user := c.Get("user").(*jwt.Token)
claims := user.Claims.(*models.JwtCustomClaims)
// Validate original token before refresh
if claims.ExpiresAt < time.Now().Unix() {
return echo.NewHTTPError(http.StatusUnauthorized, "Original token expired")
}
// Generate new token with same claims but new expiration
newClaims := &models.JwtCustomClaims{
jwt.StandardClaims{
Subject: claims.Subject,
ExpiresAt: time.Now().Add(time.Hour * 24).Unix(),
Issuer: "your-service.com",
},
claims.UserID,
claims.Role,
}
token := jwt.NewWithClaims(jwt.SigningMethodRS256, newClaims)
signedToken, err := token.SignedString(privateKey)
if err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Token generation failed")
}
return c.JSON(http.StatusOK, echo.Map{"token": signedToken})
}Secure claim validation in Echo Go:
func (claims *JwtCustomClaims) Valid() error {
// Validate standard claims
if err := claims.StandardClaims.Valid(); err != nil {
return err
}
// Custom validation for Echo Go application
if claims.UserID == "" || claims.Role == "" {
return errors.New("missing required claims")
}
// Role-based access control
allowedRoles := map[string]bool{
"admin": true,
"user": true,
"moderator": true,
}
if !allowedRoles[claims.Role] {
return errors.New("invalid role")
}
return nil
}Related CWEs: authentication
| CWE ID | Name | Severity |
|---|---|---|
| CWE-287 | Improper Authentication | CRITICAL |
| CWE-306 | Missing Authentication for Critical Function | CRITICAL |
| CWE-307 | Brute Force | HIGH |
| CWE-308 | Single-Factor Authentication | MEDIUM |
| CWE-309 | Use of Password System for Primary Authentication | MEDIUM |
| CWE-347 | Improper Verification of Cryptographic Signature | HIGH |
| CWE-384 | Session Fixation | HIGH |
| CWE-521 | Weak Password Requirements | MEDIUM |
| CWE-613 | Insufficient Session Expiration | MEDIUM |
| CWE-640 | Weak Password Recovery | HIGH |