Identification Failures in Echo Go
How Identification Failures Manifests in Echo Go
Identification failures in Echo Go typically occur when user identity is not properly established before authorization checks. Echo Go's middleware-based architecture creates several common failure points.
Missing Authentication Middleware
// Vulnerable: no authentication middleware
func main() {
e := echo.New()
// Route accessible without identity
e.GET("/api/user/profile", getUserProfile)
e.Start(":1323")
}
func getUserProfile(c echo.Context) error {
// No user identity available
userID := c.Get("user")
if userID == nil {
return c.JSON(http.StatusInternalServerError, map[string]string{
"error": "user not identified",
})
}
// Proceed with userID...
}
Context Identity Not Propagated
// Vulnerable: identity lost in handler chain
func main() {
e := echo.New()
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
SigningKey: []byte("secret"),
}))
e.GET("/api/admin", adminHandler)
e.Start(":1323")
}
func adminHandler(c echo.Context) error {
// JWT claims available but not used
claims := jwt.MapClaims{}
// Missing identity propagation
return processAdminRequest(c, claims)
}
func processAdminRequest(c echo.Context, claims jwt.MapClaims) error {
// Claims not passed through
return c.JSON(http.StatusOK, map[string]string{
"message": "admin access granted",
})
}
Weak Identity Extraction
// Vulnerable: weak identity extraction
func getUserID(c echo.Context) string {
// No validation of identity source
id := c.Request().Header.Get("X-User-ID")
if id == "" {
id = "anonymous"
}
return id
}
func main() {
e := echo.New()
e.GET("/api/data", func(c echo.Context) error {
userID := getUserID(c)
// Any user can impersonate any ID
return c.JSON(http.StatusOK, map[string]string{
"user_id": userID,
"data": "sensitive information",
})
})
e.Start(":1323")
}
Missing Identity in Database Operations
// Vulnerable: operations without user context
func main() {
e := echo.New()
e.POST("/api/posts", createPost)
e.Start("/:1323")
}
func createPost(c echo.Context) error {
var post Post
if err := c.Bind(&post); err != nil {
return err
}
// No user identification before DB operation
result := db.Create(&post)
return c.JSON(http.StatusCreated, result)
}Echo Go-Specific Detection
middleBrick's Echo Go-specific scanning identifies identification failures through several Echo Go-native patterns:
Authentication Middleware Analysis
# Scan Echo Go API for identification failures
middlebrick scan https://yourapi.com
# Output includes:
# - Missing JWT middleware on protected routes
# - Routes accessible without authentication
# - Context identity propagation failures
Echo Go Route Inspection
// What middleBrick detects in Echo Go routes
func main() {
e := echo.New()
// Detected: missing authentication middleware
e.GET("/api/admin", adminHandler)
// Detected: weak identity extraction
e.GET("/api/user/:id", getUserHandler)
// Detected: missing identity in DB operations
e.POST("/api/posts", createPost)
}
Context Identity Verification
// middleBrick checks for proper context usage
func getUserProfile(c echo.Context) error {
// Detected: missing identity validation
user := c.Get("user")
if user == nil {
return c.JSON(http.StatusUnauthorized, map[string]string{
"error": "unauthenticated",
})
}
// Detected: proper identity propagation
claims := user.(*jwt.Token).Claims
return c.JSON(http.StatusOK, claims)
}
Database Operation Context
// middleBrick identifies missing user context in DB operations
func createPost(c echo.Context) error {
userID := getCurrentUserID(c) // Detected: missing implementation
var post Post
if err := c.Bind(&post); err != nil {
return err
}
// Detected: missing user context in database operation
post.UserID = userID
result := db.Create(&post)
return c.JSON(http.StatusCreated, result)
}
Echo Go-Specific Remediation
Echo Go provides native mechanisms for proper identification that address these failures:
Proper Authentication Middleware
// Secure: proper authentication middleware
func main() {
e := echo.New()
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
SigningKey: []byte("your-secret-key"),
Claims: &jwt.StandardClaims{},
}))
e.GET("/api/user/profile", getUserProfile)
e.GET("/api/admin", adminHandler)
e.Start(":1323")
}
func getUserProfile(c echo.Context) error {
// Secure: identity properly extracted
user := c.Get("user").(*jwt.Token)
claims := user.Claims.(*jwt.StandardClaims)
return c.JSON(http.StatusOK, map[string]string{
"user_id": claims.Subject,
"message": "profile accessed",
})
}
func adminHandler(c echo.Context) error {
// Secure: identity verified for admin access
user := c.Get("user").(*jwt.Token)
claims := user.Claims.(*jwt.StandardClaims)
if claims.Subject != "admin" {
return c.JSON(http.StatusForbidden, map[string]string{
"error": "admin access required",
})
}
return c.JSON(http.StatusOK, map[string]string{
"message": "admin access granted",
})
}
Context Identity Propagation
// Secure: identity propagated through handler chain
func main() {
e := echo.New()
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
SigningKey: []byte("secret"),
}))
e.GET("/api/admin", processAdminRequest)
e.Start(":1323")
}
func processAdminRequest(c echo.Context) error {
user := c.Get("user").(*jwt.Token)
claims := user.Claims.(*jwt.StandardClaims)
// Secure: identity passed to processing functions
return handleAdminOperation(c, claims)
}
func handleAdminOperation(c echo.Context, claims *jwt.StandardClaims) error {
// Identity available throughout processing
return c.JSON(http.StatusOK, map[string]string{
"user_id": claims.Subject,
"operation": "admin task completed",
})
}
Secure Identity Extraction
// Secure: validated identity extraction
func getCurrentUserID(c echo.Context) string {
user := c.Get("user")
if user == nil {
return ""
}
token := user.(*jwt.Token)
claims := token.Claims.(*jwt.StandardClaims)
return claims.Subject
}
func main() {
e := echo.New()
e.Use(middleware.JWTWithConfig(middleware.JWTConfig{
SigningKey: []byte("secret"),
}))
e.GET("/api/data", func(c echo.Context) error {
userID := getCurrentUserID(c)
if userID == "" {
return c.JSON(http.StatusUnauthorized, map[string]string{
"error": "authentication required",
})
}
// Secure: operations with validated identity
return c.JSON(http.StatusOK, map[string]string{
"user_id": userID,
"data": "sensitive information",
})
})
e.Start(":1323")
}
Database Operations with Identity
// Secure: database operations with user context
func createPost(c echo.Context) error {
userID := getCurrentUserID(c)
if userID == "" {
return c.JSON(http.StatusUnauthorized, map[string]string{
"error": "authentication required",
})
}
var post Post
if err := c.Bind(&post); err != nil {
return err
}
// Secure: user context included in database operation
post.UserID = userID
result := db.Create(&post)
return c.JSON(http.StatusCreated, result)
}
type Post struct {
ID uint `json:"id" gorm:"primary_key"`
UserID string `json:"user_id" gorm:"index"`
Content string `json:"content"`
}