HIGH path traversalecho gobearer tokens

Path Traversal in Echo Go with Bearer Tokens

Path Traversal in Echo Go with Bearer Tokens — how this specific combination creates or exposes the vulnerability

Path Traversal occurs when user-controlled input is used to construct file system paths without proper validation, allowing an attacker to access files outside the intended directory. In Echo Go, this often arises when a route parameter or query value is directly joined with a base directory to serve files or access resources. Combining this with Bearer Token authentication can create a misleading sense of security and expose scenarios where authorization is checked but path construction remains unsafe.

Consider an Echo Go handler that serves user documents. The developer may protect the endpoint with Bearer Token validation, assuming that only authenticated users can request files. However, if the token is validated before the file path is built, and the path is constructed by concatenating a user-supplied filename or directory segment without cleaning or restricting it, an authenticated user can send requests like /files/../../../etc/passwd. Even with a valid Bearer Token, the handler might resolve this to a sensitive file on the server because the path is not canonicalized or confined to a safe base directory.

This combination is particularly risky when tokens are issued with broad scopes or long lifetimes, increasing the window for abuse if path traversal exists. An attacker who obtains a Bearer Token—through leaks, insecure storage, or accidental exposure—can exploit traversal to read configuration files, logs, or other sensitive artifacts. In API-first designs, endpoints that accept file identifiers as path parameters or query strings must treat these inputs as untrusted, regardless of the presence of Bearer Token checks.

middleBrick detects such issues by testing unauthenticated and authenticated-like probes where applicable, including checks for Path Traversal across different authentication schemes. When scanning an Echo Go API with Bearer Token protection, it will flag instances where file-system interactions are not properly constrained, even if authentication logic appears correct.

Bearer Tokens-Specific Remediation in Echo Go — concrete code fixes

Remediation focuses on strict input validation, path canonicalization, and ensuring that authorization decisions consider the resolved path, not just the token’s validity. Below are concrete, secure patterns for Echo Go handlers.

1. Use filepath.Clean and restrict to a base directory

Always clean user input and join it to a predefined base directory. Reject paths that escape the base using .. or absolute segments.

import (
    "net/http"
    "path/filepath"
    "strings"

    "github.com/labstack/echo/v4"
)

const baseDir = "/var/data/documents"

func safeFileHandler(c echo.Context) error {
    // Extract Bearer token from Authorization header
    auth := c.Request().Header.Get("Authorization")
    if auth == "" || !strings.HasPrefix(auth, "Bearer ") {
        return echo.NewHTTPError(http.StatusUnauthorized, "missing or invalid bearer token")
    }
    token := strings.TrimPrefix(auth, "Bearer ")
    // Validate token (e.g., verify signature, scopes, expiration)
    if !isValidToken(token) {
        return echo.NewHTTPError(http.StatusUnauthorized, "invalid token")
    }

    // User-supplied filename from query or param
    requested := c.QueryParam("file")
    if requested == "" {
        return echo.NewHTTPError(http.StatusBadRequest, "file parameter is required")
    }

    // Clean and join safely
    clean := filepath.Clean(requested)
    if strings.Contains(clean, "..") {
        return echo.NewHTTPError(http.StatusBadRequest, "invalid file path")
    }
    fullPath := filepath.Join(baseDir, clean)

    // Ensure the resolved path is still inside baseDir
    if !strings.HasPrefix(fullPath, filepath.Clean(baseDir)+string(filepath.Separator)) && fullPath != filepath.Clean(baseDir) {
        return echo.NewHTTPError(http.StatusForbidden, "access denied")
    }

    http.ServeFile(c.Response().Writer, c.Request(), fullPath)
    return nil
}

func isValidToken(token string) bool {
    // Placeholder: implement JWT verification or lookup
    return token == "valid_token_123"
}

2. Validate against a whitelist when possible

If the set of accessible files is predictable, prefer an allowlist over constructing filesystem paths from user input.

func whitelistFileHandler(c echo.Context) error {
    auth := c.Request().Header.Get("Authorization")
    if auth == "" || !strings.HasPrefix(auth, "Bearer ") {
        return echo.NewHTTPError(http.StatusUnauthorized, "missing or invalid bearer token")
    }
    token := strings.TrimPrefix(auth, "Bearer ")
    if !isValidToken(token) {
        return echo.NewHTTPError(http.StatusUnauthorized, "invalid token")
    }

    allowed := map[string]bool{
        "report.pdf": true,
        "readme.txt": true,
    }
    file := c.QueryParam("file")
    if !allowed[file] {
        return echo.NewHTTPError(http.StatusBadRequest, "file not allowed")
    }

    http.ServeFile(c.Response().Writer, c.Request(), "/var/data/"+file)
    return nil
}

3. Use http.Dir and Open for additional safety

The http.Dir type and its Open method clean paths implicitly and can be combined with base directory constraints.

func httpDirHandler(c echo.Context) error {
    auth := c.Request().Header.Get("Authorization")
    if auth == "" || !strings.HasPrefix(auth, "Bearer ") {
        return echo.NewHTTPError(http.StatusUnauthorized, "missing or invalid bearer token")
    }
    token := strings.TrimPrefix(auth, "Bearer ")
    if !isValidToken(token) {
        return echo.NewHTTPError(http.StatusUnauthorized, "invalid token")
    }

    fs := http.Dir("/var/data/documents")
    file, err := fs.Open(c.QueryParam("file"))
    if err != nil {
        return echo.NewHTTPError(http.StatusBadRequest, "file not found")
    }
    defer file.Close()

    // Optionally inspect file info to ensure it is a regular file
    info, _ := file.Stat()
    if info.IsDir() {
        return echo.NewHTTPError(http.StatusBadRequest, "cannot serve directory")
    }

    http.ServeContent(c.Response().Writer, c.Request(), info.Name(), info.ModTime(), file)
    return nil
}

These patterns ensure that even when Bearer Tokens protect the endpoint, file access is constrained and predictable. Always treat path inputs as hostile and validate them independently of authentication checks.

Related CWEs: inputValidation

CWE IDNameSeverity
CWE-20Improper Input Validation HIGH
CWE-22Path Traversal HIGH
CWE-74Injection CRITICAL
CWE-77Command Injection CRITICAL
CWE-78OS Command Injection CRITICAL
CWE-79Cross-site Scripting (XSS) HIGH
CWE-89SQL Injection CRITICAL
CWE-90LDAP Injection HIGH
CWE-91XML Injection HIGH
CWE-94Code Injection CRITICAL

Frequently Asked Questions

Can an attacker bypass Bearer Token checks via path traversal in Echo Go?
Yes, if the handler validates the token but constructs file paths using unsanitized user input, an authenticated attacker can traverse directories and access unintended files. Token validity does not prevent path traversal; you must validate and restrict paths separately.
How does middleBrick help detect Path Traversal in APIs using Bearer Tokens?
middleBrick runs checks that probe endpoints with and without valid Bearer Tokens, attempting traversal patterns such as ../../../etc/passwd. It reports whether authentication is bypassed or whether file-system interactions expose directory escape risks, providing remediation guidance specific to Echo Go patterns.