Skip to content

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - #156

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability
Open

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]#156
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
github.com/labstack/echo/v4v4.13.3v4.15.3ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

CVE-2026-55677 / GHSA-vfp3-v2gw-7wfq

More information

Details

Summary

Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.

Details

Root cause 1 — router.go lines 798-802:
The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern.

if!r.useEscapedPathForRouting&&req.URL.RawPath!="" {
path=req.URL.RawPath
}

Root cause 2 — echo.go lines 559-568:
StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.

if!disablePathUnescaping {
tmpPath, err:=url.PathUnescape(p)
p=tmpPath
}
name:=filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot)

Sample:
image

403:
image

Bypass with encoded slash:
image

Impact

Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/%2F) in the URL to bypass all route-level protection.

Common affected pattern:

adminGroup:=e.Group("/admin", authMiddleware)
e.StaticFS("/", os.DirFS("public"))

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

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

v4.15.3: - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Compare Source

Security

  • fix(static): reject encoded path separators that bypass route-level middleware by @​vishr in #​3011

Fixes GHSA-vfp3-v2gw-7wfq: an encoded path separator (%2F or %5C) in a static file URL could bypass route-level middleware (e.g. authentication on a sibling route) and disclose static files. Both StaticDirectoryHandler (used by Static/StaticFS) and the Static middleware are affected. Backport of the v5 fix (#​3009, released in v5.2.0). Thanks to @​a-tt-om and @​oran-gugu for reporting.

Full Changelog: labstack/echo@v4.15.2...v4.15.3

v4.15.2: - Context.Scheme() header validation

Compare Source

Security

Thanks to @​shblue21 for reporting this issue.

Full Changelog: labstack/echo@v4.15.1...v4.15.2

v4.15.1

Compare Source

What's Changed

  • CSRF: support older token-based CSRF protection handler that want to render token into template by @​aldas in #​2905

Full Changelog: labstack/echo@v4.15.0...v4.15.1

v4.15.0

Compare Source

Security

NB: If your application relies on cross-origin or same-site (same subdomain) requests do not blindly push this version to production

The CSRF middleware now supports the Sec-Fetch-Site header as a modern, defense-in-depth approach to CSRF
protection
, implementing the OWASP-recommended Fetch Metadata API alongside the traditional token-based mechanism.

How it works:

Modern browsers automatically send the Sec-Fetch-Site header with all requests, indicating the relationship
between the request origin and the target. The middleware uses this to make security decisions:

  • same-origin or none: Requests are allowed (exact origin match or direct user navigation)
  • same-site: Falls back to token validation (e.g., subdomain to main domain)
  • cross-site: Blocked by default with 403 error for unsafe methods (POST, PUT, DELETE, PATCH)

For browsers that don't send this header (older browsers), the middleware seamlessly falls back to
traditional token-based CSRF protection.

New Configuration Options:

  • TrustedOrigins []string: Allowlist specific origins for cross-site requests (useful for OAuth callbacks, webhooks)
  • AllowSecFetchSiteFunc func(echo.Context) (bool, error): Custom logic for same-site/cross-site request validation

Example:

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from trusted providerTrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site requestsAllowSecFetchSiteFunc: func(c echo.Context) (bool, error) {
// Your custom authorization logic herereturnvalidateCustomAuth(c), nil// return true, err // blocks request with error// return true, nil // allows CSRF request through// return false, nil // falls back to legacy token logic
},
}))

PR: #​2858

Type-Safe Generic Parameter Binding

  • Added generic functions for type-safe parameter extraction and context access by @​aldas in #​2856

    Echo now provides generic functions for extracting path, query, and form parameters with automatic type conversion,
    eliminating manual string parsing and type assertions.

    New Functions:

    • Path parameters: PathParam[T], PathParamOr[T]
    • Query parameters: QueryParam[T], QueryParamOr[T], QueryParams[T], QueryParamsOr[T]
    • Form values: FormParam[T], FormParamOr[T], FormParams[T], FormParamsOr[T]
    • Context store: ContextGet[T], ContextGetOr[T]

    Supported Types:
    Primitives (bool, string, int/uint variants, float32/float64), time.Duration, time.Time
    (with custom layouts and Unix timestamp support), and custom types implementing BindUnmarshaler,
    TextUnmarshaler, or JSONUnmarshaler.

    Example:

    // Before: Manual parsingidStr:=c.Param("id")
    id, err:=strconv.Atoi(idStr)
    // After: Type-safe with automatic parsingid, err:=echo.PathParam[int](c, "id")
    // With default valuespage, err:=echo.QueryParamOr[int](c, "page", 1)
    limit, err:=echo.QueryParamOr[int](c, "limit", 20)
    // Type-safe context access (no more panics from type assertions)user, err:=echo.ContextGet[*User](c, "user")

PR: #​2856

DEPRECATION NOTICE Timeout Middleware Deprecated - Use ContextTimeout Instead

The middleware.Timeout middleware has been deprecated due to fundamental architectural issues that cause
data races. Use middleware.ContextTimeout or middleware.ContextTimeoutWithConfig instead.

Why is this being deprecated?

The Timeout middleware manipulates response writers across goroutine boundaries, which causes data races that
cannot be reliably fixed without a complete architectural redesign. The middleware:

  • Swaps the response writer using http.TimeoutHandler
  • Must be the first middleware in the chain (fragile constraint)
  • Can cause races with other middleware (Logger, metrics, custom middleware)
  • Has been the source of multiple race condition fixes over the years

What should you use instead?

The ContextTimeout middleware (available since v4.12.0) provides timeout functionality using Go's standard
context mechanism. It is:

  • Race-free by design
  • Can be placed anywhere in the middleware chain
  • Simpler and more maintainable
  • Compatible with all other middleware

Migration Guide:

// Before (deprecated):e.Use(middleware.Timeout())
// After (recommended):e.Use(middleware.ContextTimeout(30*time.Second))

Important Behavioral Differences:

  1. Handler cooperation required: With ContextTimeout, your handlers must check context.Done() for cooperative
    cancellation. The old Timeout middleware would send a 503 response regardless of handler cooperation, but had
    data race issues.

  2. Error handling: ContextTimeout returns errors through the standard error handling flow. Handlers that receive
    context.DeadlineExceeded should handle it appropriately:

e.GET("/long-task", func(c echo.Context) error {
ctx:=c.Request().Context()
// Example: database query with contextresult, err:=db.QueryContext(ctx, "SELECT * FROM large_table")
iferr!=nil {
iferrors.Is(err, context.DeadlineExceeded) {
// Handle timeoutreturnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
returnerr
}
returnc.JSON(http.StatusOK, result)
})
  1. Background tasks: For long-running background tasks, use goroutines with context:
e.GET("/async-task", func(c echo.Context) error {
ctx:=c.Request().Context()
resultCh:=make(chanResult, 1)
errCh:=make(chanerror, 1)
gofunc() {
result, err:=performLongTask(ctx)
iferr!=nil {
errCh<-errreturn
}
resultCh<-result
}()
select {
caseresult:=<-resultCh:
returnc.JSON(http.StatusOK, result)
caseerr:=<-errCh:
returnerrcase<-ctx.Done():
returnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
})

Enhancements

v4.14.0

Compare Source

middleware.Logger has been deprecated. For request logging, use middleware.RequestLogger or
middleware.RequestLoggerWithConfig.

middleware.RequestLogger replaces middleware.Logger, offering comparable configuration while relying on the
Go standard library’s new slog logger.

The previous default output format was JSON. The new default follows the standard slog logger settings.
To continue emitting request logs in JSON, configure slog accordingly:

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
e.Use(middleware.RequestLogger())

Security

Enhancements

v4.13.4

Compare Source

Enhancements

Security


Configuration

📅 Schedule: (in timezone Asia/Tokyo)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovateBot commented Aug 25, 2026

Copy link
Copy Markdown
ContributorAuthor

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 12 additional dependencies were updated
  • The go directive was updated for compatibility reasons

Details:

PackageChange
go1.24.2 -> 1.25.0
github.com/stretchr/testifyv1.10.0 -> v1.11.1
github.com/labstack/gommonv0.4.2 -> v0.5.0
github.com/mattn/go-colorablev0.1.13 -> v0.1.14
github.com/mattn/go-isattyv0.0.20 -> v0.0.22
golang.org/x/cryptov0.36.0 -> v0.50.0
golang.org/x/modv0.24.0 -> v0.34.0
golang.org/x/netv0.37.0 -> v0.53.0
golang.org/x/syncv0.13.0 -> v0.20.0
golang.org/x/sysv0.31.0 -> v0.43.0
golang.org/x/textv0.23.0 -> v0.36.0
golang.org/x/timev0.8.0 -> v0.15.0
golang.org/x/toolsv0.31.0 -> v0.43.0

@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 28, 2026
@renovaterenovateBot closed this Aug 28, 2026
@renovate
renovateBot deleted the renovate/go-github.com-labstack-echo-v4-vulnerability branch August 28, 2026 21:59
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from cb18ce6 to d3d1ad1CompareAugust 29, 2026 03:05
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 29, 2026
@renovaterenovateBot closed this Aug 29, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch from cb18ce6 to f224246CompareAugust 29, 2026 22:40
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 30, 2026
@renovaterenovateBot reopened this Aug 30, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from f224246 to 25c1b10CompareAugust 30, 2026 04:49
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 25c1b10 to 064deb3CompareAugust 31, 2026 01:41
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 31, 2026
@renovaterenovateBot closed this Aug 31, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 064deb3 to d6a24f0CompareAugust 31, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

, 'i'); if (__m === '*' || __re.test(location.href)) { // Add copy buttons to all \x3Cpre>\x3Ccode> blocks (function() { function addCopyButtons() { document.querySelectorAll('pre code').forEach(function(codeBlock) { if (codeBlock.parentElement.hasAttribute('data-copy-added')) return; codeBlock.parentElement.setAttribute('data-copy-added', 'true'); var btn = document.createElement('button'); btn.textContent = 'Copy'; btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;'; btn.onmouseover = function() { this.style.opacity = '1'; }; btn.onmouseout = function() { this.style.opacity = '0.7'; }; btn.onclick = function() { navigator.clipboard.writeText(codeBlock.textContent).then(function() { btn.textContent = 'Copied!'; setTimeout(function() { btn.textContent = 'Copy'; }, 1500); }); }; codeBlock.parentElement.style.position = 'relative'; codeBlock.parentElement.appendChild(btn); }); } addCopyButtons(); // Re-run on dynamic content var observer = new MutationObserver(addCopyButtons); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); } })(); (function(){ try { var __m = "github.com"; var __re = new RegExp('^' + "github\\.com" + ' Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] by renovate[bot] · Pull Request #156 · sky0621/cv-admin · GitHub
Skip to content

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - #156

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability
Open

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]#156
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
github.com/labstack/echo/v4v4.13.3v4.15.3ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

CVE-2026-55677 / GHSA-vfp3-v2gw-7wfq

More information

Details

Summary

Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.

Details

Root cause 1 — router.go lines 798-802:
The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern.

if!r.useEscapedPathForRouting&&req.URL.RawPath!="" {
path=req.URL.RawPath
}

Root cause 2 — echo.go lines 559-568:
StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.

if!disablePathUnescaping {
tmpPath, err:=url.PathUnescape(p)
p=tmpPath
}
name:=filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot)

Sample:
image

403:
image

Bypass with encoded slash:
image

Impact

Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/%2F) in the URL to bypass all route-level protection.

Common affected pattern:

adminGroup:=e.Group("/admin", authMiddleware)
e.StaticFS("/", os.DirFS("public"))

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

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

v4.15.3: - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Compare Source

Security

  • fix(static): reject encoded path separators that bypass route-level middleware by @​vishr in #​3011

Fixes GHSA-vfp3-v2gw-7wfq: an encoded path separator (%2F or %5C) in a static file URL could bypass route-level middleware (e.g. authentication on a sibling route) and disclose static files. Both StaticDirectoryHandler (used by Static/StaticFS) and the Static middleware are affected. Backport of the v5 fix (#​3009, released in v5.2.0). Thanks to @​a-tt-om and @​oran-gugu for reporting.

Full Changelog: labstack/echo@v4.15.2...v4.15.3

v4.15.2: - Context.Scheme() header validation

Compare Source

Security

Thanks to @​shblue21 for reporting this issue.

Full Changelog: labstack/echo@v4.15.1...v4.15.2

v4.15.1

Compare Source

What's Changed

  • CSRF: support older token-based CSRF protection handler that want to render token into template by @​aldas in #​2905

Full Changelog: labstack/echo@v4.15.0...v4.15.1

v4.15.0

Compare Source

Security

NB: If your application relies on cross-origin or same-site (same subdomain) requests do not blindly push this version to production

The CSRF middleware now supports the Sec-Fetch-Site header as a modern, defense-in-depth approach to CSRF
protection
, implementing the OWASP-recommended Fetch Metadata API alongside the traditional token-based mechanism.

How it works:

Modern browsers automatically send the Sec-Fetch-Site header with all requests, indicating the relationship
between the request origin and the target. The middleware uses this to make security decisions:

  • same-origin or none: Requests are allowed (exact origin match or direct user navigation)
  • same-site: Falls back to token validation (e.g., subdomain to main domain)
  • cross-site: Blocked by default with 403 error for unsafe methods (POST, PUT, DELETE, PATCH)

For browsers that don't send this header (older browsers), the middleware seamlessly falls back to
traditional token-based CSRF protection.

New Configuration Options:

  • TrustedOrigins []string: Allowlist specific origins for cross-site requests (useful for OAuth callbacks, webhooks)
  • AllowSecFetchSiteFunc func(echo.Context) (bool, error): Custom logic for same-site/cross-site request validation

Example:

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from trusted providerTrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site requestsAllowSecFetchSiteFunc: func(c echo.Context) (bool, error) {
// Your custom authorization logic herereturnvalidateCustomAuth(c), nil// return true, err // blocks request with error// return true, nil // allows CSRF request through// return false, nil // falls back to legacy token logic
},
}))

PR: #​2858

Type-Safe Generic Parameter Binding

  • Added generic functions for type-safe parameter extraction and context access by @​aldas in #​2856

    Echo now provides generic functions for extracting path, query, and form parameters with automatic type conversion,
    eliminating manual string parsing and type assertions.

    New Functions:

    • Path parameters: PathParam[T], PathParamOr[T]
    • Query parameters: QueryParam[T], QueryParamOr[T], QueryParams[T], QueryParamsOr[T]
    • Form values: FormParam[T], FormParamOr[T], FormParams[T], FormParamsOr[T]
    • Context store: ContextGet[T], ContextGetOr[T]

    Supported Types:
    Primitives (bool, string, int/uint variants, float32/float64), time.Duration, time.Time
    (with custom layouts and Unix timestamp support), and custom types implementing BindUnmarshaler,
    TextUnmarshaler, or JSONUnmarshaler.

    Example:

    // Before: Manual parsingidStr:=c.Param("id")
    id, err:=strconv.Atoi(idStr)
    // After: Type-safe with automatic parsingid, err:=echo.PathParam[int](c, "id")
    // With default valuespage, err:=echo.QueryParamOr[int](c, "page", 1)
    limit, err:=echo.QueryParamOr[int](c, "limit", 20)
    // Type-safe context access (no more panics from type assertions)user, err:=echo.ContextGet[*User](c, "user")

PR: #​2856

DEPRECATION NOTICE Timeout Middleware Deprecated - Use ContextTimeout Instead

The middleware.Timeout middleware has been deprecated due to fundamental architectural issues that cause
data races. Use middleware.ContextTimeout or middleware.ContextTimeoutWithConfig instead.

Why is this being deprecated?

The Timeout middleware manipulates response writers across goroutine boundaries, which causes data races that
cannot be reliably fixed without a complete architectural redesign. The middleware:

  • Swaps the response writer using http.TimeoutHandler
  • Must be the first middleware in the chain (fragile constraint)
  • Can cause races with other middleware (Logger, metrics, custom middleware)
  • Has been the source of multiple race condition fixes over the years

What should you use instead?

The ContextTimeout middleware (available since v4.12.0) provides timeout functionality using Go's standard
context mechanism. It is:

  • Race-free by design
  • Can be placed anywhere in the middleware chain
  • Simpler and more maintainable
  • Compatible with all other middleware

Migration Guide:

// Before (deprecated):e.Use(middleware.Timeout())
// After (recommended):e.Use(middleware.ContextTimeout(30*time.Second))

Important Behavioral Differences:

  1. Handler cooperation required: With ContextTimeout, your handlers must check context.Done() for cooperative
    cancellation. The old Timeout middleware would send a 503 response regardless of handler cooperation, but had
    data race issues.

  2. Error handling: ContextTimeout returns errors through the standard error handling flow. Handlers that receive
    context.DeadlineExceeded should handle it appropriately:

e.GET("/long-task", func(c echo.Context) error {
ctx:=c.Request().Context()
// Example: database query with contextresult, err:=db.QueryContext(ctx, "SELECT * FROM large_table")
iferr!=nil {
iferrors.Is(err, context.DeadlineExceeded) {
// Handle timeoutreturnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
returnerr
}
returnc.JSON(http.StatusOK, result)
})
  1. Background tasks: For long-running background tasks, use goroutines with context:
e.GET("/async-task", func(c echo.Context) error {
ctx:=c.Request().Context()
resultCh:=make(chanResult, 1)
errCh:=make(chanerror, 1)
gofunc() {
result, err:=performLongTask(ctx)
iferr!=nil {
errCh<-errreturn
}
resultCh<-result
}()
select {
caseresult:=<-resultCh:
returnc.JSON(http.StatusOK, result)
caseerr:=<-errCh:
returnerrcase<-ctx.Done():
returnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
})

Enhancements

v4.14.0

Compare Source

middleware.Logger has been deprecated. For request logging, use middleware.RequestLogger or
middleware.RequestLoggerWithConfig.

middleware.RequestLogger replaces middleware.Logger, offering comparable configuration while relying on the
Go standard library’s new slog logger.

The previous default output format was JSON. The new default follows the standard slog logger settings.
To continue emitting request logs in JSON, configure slog accordingly:

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
e.Use(middleware.RequestLogger())

Security

Enhancements

v4.13.4

Compare Source

Enhancements

Security


Configuration

📅 Schedule: (in timezone Asia/Tokyo)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovateBot commented Aug 25, 2026

Copy link
Copy Markdown
ContributorAuthor

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 12 additional dependencies were updated
  • The go directive was updated for compatibility reasons

Details:

PackageChange
go1.24.2 -> 1.25.0
github.com/stretchr/testifyv1.10.0 -> v1.11.1
github.com/labstack/gommonv0.4.2 -> v0.5.0
github.com/mattn/go-colorablev0.1.13 -> v0.1.14
github.com/mattn/go-isattyv0.0.20 -> v0.0.22
golang.org/x/cryptov0.36.0 -> v0.50.0
golang.org/x/modv0.24.0 -> v0.34.0
golang.org/x/netv0.37.0 -> v0.53.0
golang.org/x/syncv0.13.0 -> v0.20.0
golang.org/x/sysv0.31.0 -> v0.43.0
golang.org/x/textv0.23.0 -> v0.36.0
golang.org/x/timev0.8.0 -> v0.15.0
golang.org/x/toolsv0.31.0 -> v0.43.0

@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 28, 2026
@renovaterenovateBot closed this Aug 28, 2026
@renovate
renovateBot deleted the renovate/go-github.com-labstack-echo-v4-vulnerability branch August 28, 2026 21:59
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from cb18ce6 to d3d1ad1CompareAugust 29, 2026 03:05
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 29, 2026
@renovaterenovateBot closed this Aug 29, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch from cb18ce6 to f224246CompareAugust 29, 2026 22:40
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 30, 2026
@renovaterenovateBot reopened this Aug 30, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from f224246 to 25c1b10CompareAugust 30, 2026 04:49
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 25c1b10 to 064deb3CompareAugust 31, 2026 01:41
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 31, 2026
@renovaterenovateBot closed this Aug 31, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 064deb3 to d6a24f0CompareAugust 31, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

, 'i'); if (__m === '*' || __re.test(location.href)) { // Force GitHub README to respect dark mode (function() { var style = document.createElement('style'); style.textContent = ' .markdown-body { color-scheme: dark light; } .markdown-body pre { background: #161b22 !important; } .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; } .markdown-body table th, .markdown-body table td { border-color: #30363d !important; } .markdown-body img { background: #0d1117; } .markdown-body blockquote { border-left-color: #8b949e; } .markdown-body hr { border-color: #30363d; } '; document.head.appendChild(style); })(); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] by renovate[bot] · Pull Request #156 · sky0621/cv-admin · GitHub
Skip to content

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - #156

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability
Open

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]#156
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
github.com/labstack/echo/v4v4.13.3v4.15.3ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

CVE-2026-55677 / GHSA-vfp3-v2gw-7wfq

More information

Details

Summary

Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.

Details

Root cause 1 — router.go lines 798-802:
The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern.

if!r.useEscapedPathForRouting&&req.URL.RawPath!="" {
path=req.URL.RawPath
}

Root cause 2 — echo.go lines 559-568:
StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.

if!disablePathUnescaping {
tmpPath, err:=url.PathUnescape(p)
p=tmpPath
}
name:=filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot)

Sample:
image

403:
image

Bypass with encoded slash:
image

Impact

Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/%2F) in the URL to bypass all route-level protection.

Common affected pattern:

adminGroup:=e.Group("/admin", authMiddleware)
e.StaticFS("/", os.DirFS("public"))

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

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

v4.15.3: - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Compare Source

Security

  • fix(static): reject encoded path separators that bypass route-level middleware by @​vishr in #​3011

Fixes GHSA-vfp3-v2gw-7wfq: an encoded path separator (%2F or %5C) in a static file URL could bypass route-level middleware (e.g. authentication on a sibling route) and disclose static files. Both StaticDirectoryHandler (used by Static/StaticFS) and the Static middleware are affected. Backport of the v5 fix (#​3009, released in v5.2.0). Thanks to @​a-tt-om and @​oran-gugu for reporting.

Full Changelog: labstack/echo@v4.15.2...v4.15.3

v4.15.2: - Context.Scheme() header validation

Compare Source

Security

Thanks to @​shblue21 for reporting this issue.

Full Changelog: labstack/echo@v4.15.1...v4.15.2

v4.15.1

Compare Source

What's Changed

  • CSRF: support older token-based CSRF protection handler that want to render token into template by @​aldas in #​2905

Full Changelog: labstack/echo@v4.15.0...v4.15.1

v4.15.0

Compare Source

Security

NB: If your application relies on cross-origin or same-site (same subdomain) requests do not blindly push this version to production

The CSRF middleware now supports the Sec-Fetch-Site header as a modern, defense-in-depth approach to CSRF
protection
, implementing the OWASP-recommended Fetch Metadata API alongside the traditional token-based mechanism.

How it works:

Modern browsers automatically send the Sec-Fetch-Site header with all requests, indicating the relationship
between the request origin and the target. The middleware uses this to make security decisions:

  • same-origin or none: Requests are allowed (exact origin match or direct user navigation)
  • same-site: Falls back to token validation (e.g., subdomain to main domain)
  • cross-site: Blocked by default with 403 error for unsafe methods (POST, PUT, DELETE, PATCH)

For browsers that don't send this header (older browsers), the middleware seamlessly falls back to
traditional token-based CSRF protection.

New Configuration Options:

  • TrustedOrigins []string: Allowlist specific origins for cross-site requests (useful for OAuth callbacks, webhooks)
  • AllowSecFetchSiteFunc func(echo.Context) (bool, error): Custom logic for same-site/cross-site request validation

Example:

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from trusted providerTrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site requestsAllowSecFetchSiteFunc: func(c echo.Context) (bool, error) {
// Your custom authorization logic herereturnvalidateCustomAuth(c), nil// return true, err // blocks request with error// return true, nil // allows CSRF request through// return false, nil // falls back to legacy token logic
},
}))

PR: #​2858

Type-Safe Generic Parameter Binding

  • Added generic functions for type-safe parameter extraction and context access by @​aldas in #​2856

    Echo now provides generic functions for extracting path, query, and form parameters with automatic type conversion,
    eliminating manual string parsing and type assertions.

    New Functions:

    • Path parameters: PathParam[T], PathParamOr[T]
    • Query parameters: QueryParam[T], QueryParamOr[T], QueryParams[T], QueryParamsOr[T]
    • Form values: FormParam[T], FormParamOr[T], FormParams[T], FormParamsOr[T]
    • Context store: ContextGet[T], ContextGetOr[T]

    Supported Types:
    Primitives (bool, string, int/uint variants, float32/float64), time.Duration, time.Time
    (with custom layouts and Unix timestamp support), and custom types implementing BindUnmarshaler,
    TextUnmarshaler, or JSONUnmarshaler.

    Example:

    // Before: Manual parsingidStr:=c.Param("id")
    id, err:=strconv.Atoi(idStr)
    // After: Type-safe with automatic parsingid, err:=echo.PathParam[int](c, "id")
    // With default valuespage, err:=echo.QueryParamOr[int](c, "page", 1)
    limit, err:=echo.QueryParamOr[int](c, "limit", 20)
    // Type-safe context access (no more panics from type assertions)user, err:=echo.ContextGet[*User](c, "user")

PR: #​2856

DEPRECATION NOTICE Timeout Middleware Deprecated - Use ContextTimeout Instead

The middleware.Timeout middleware has been deprecated due to fundamental architectural issues that cause
data races. Use middleware.ContextTimeout or middleware.ContextTimeoutWithConfig instead.

Why is this being deprecated?

The Timeout middleware manipulates response writers across goroutine boundaries, which causes data races that
cannot be reliably fixed without a complete architectural redesign. The middleware:

  • Swaps the response writer using http.TimeoutHandler
  • Must be the first middleware in the chain (fragile constraint)
  • Can cause races with other middleware (Logger, metrics, custom middleware)
  • Has been the source of multiple race condition fixes over the years

What should you use instead?

The ContextTimeout middleware (available since v4.12.0) provides timeout functionality using Go's standard
context mechanism. It is:

  • Race-free by design
  • Can be placed anywhere in the middleware chain
  • Simpler and more maintainable
  • Compatible with all other middleware

Migration Guide:

// Before (deprecated):e.Use(middleware.Timeout())
// After (recommended):e.Use(middleware.ContextTimeout(30*time.Second))

Important Behavioral Differences:

  1. Handler cooperation required: With ContextTimeout, your handlers must check context.Done() for cooperative
    cancellation. The old Timeout middleware would send a 503 response regardless of handler cooperation, but had
    data race issues.

  2. Error handling: ContextTimeout returns errors through the standard error handling flow. Handlers that receive
    context.DeadlineExceeded should handle it appropriately:

e.GET("/long-task", func(c echo.Context) error {
ctx:=c.Request().Context()
// Example: database query with contextresult, err:=db.QueryContext(ctx, "SELECT * FROM large_table")
iferr!=nil {
iferrors.Is(err, context.DeadlineExceeded) {
// Handle timeoutreturnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
returnerr
}
returnc.JSON(http.StatusOK, result)
})
  1. Background tasks: For long-running background tasks, use goroutines with context:
e.GET("/async-task", func(c echo.Context) error {
ctx:=c.Request().Context()
resultCh:=make(chanResult, 1)
errCh:=make(chanerror, 1)
gofunc() {
result, err:=performLongTask(ctx)
iferr!=nil {
errCh<-errreturn
}
resultCh<-result
}()
select {
caseresult:=<-resultCh:
returnc.JSON(http.StatusOK, result)
caseerr:=<-errCh:
returnerrcase<-ctx.Done():
returnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
})

Enhancements

v4.14.0

Compare Source

middleware.Logger has been deprecated. For request logging, use middleware.RequestLogger or
middleware.RequestLoggerWithConfig.

middleware.RequestLogger replaces middleware.Logger, offering comparable configuration while relying on the
Go standard library’s new slog logger.

The previous default output format was JSON. The new default follows the standard slog logger settings.
To continue emitting request logs in JSON, configure slog accordingly:

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
e.Use(middleware.RequestLogger())

Security

Enhancements

v4.13.4

Compare Source

Enhancements

Security


Configuration

📅 Schedule: (in timezone Asia/Tokyo)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovateBot commented Aug 25, 2026

Copy link
Copy Markdown
ContributorAuthor

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 12 additional dependencies were updated
  • The go directive was updated for compatibility reasons

Details:

PackageChange
go1.24.2 -> 1.25.0
github.com/stretchr/testifyv1.10.0 -> v1.11.1
github.com/labstack/gommonv0.4.2 -> v0.5.0
github.com/mattn/go-colorablev0.1.13 -> v0.1.14
github.com/mattn/go-isattyv0.0.20 -> v0.0.22
golang.org/x/cryptov0.36.0 -> v0.50.0
golang.org/x/modv0.24.0 -> v0.34.0
golang.org/x/netv0.37.0 -> v0.53.0
golang.org/x/syncv0.13.0 -> v0.20.0
golang.org/x/sysv0.31.0 -> v0.43.0
golang.org/x/textv0.23.0 -> v0.36.0
golang.org/x/timev0.8.0 -> v0.15.0
golang.org/x/toolsv0.31.0 -> v0.43.0

@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 28, 2026
@renovaterenovateBot closed this Aug 28, 2026
@renovate
renovateBot deleted the renovate/go-github.com-labstack-echo-v4-vulnerability branch August 28, 2026 21:59
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from cb18ce6 to d3d1ad1CompareAugust 29, 2026 03:05
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 29, 2026
@renovaterenovateBot closed this Aug 29, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch from cb18ce6 to f224246CompareAugust 29, 2026 22:40
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 30, 2026
@renovaterenovateBot reopened this Aug 30, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from f224246 to 25c1b10CompareAugust 30, 2026 04:49
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 25c1b10 to 064deb3CompareAugust 31, 2026 01:41
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 31, 2026
@renovaterenovateBot closed this Aug 31, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 064deb3 to d6a24f0CompareAugust 31, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

, 'i'); if (__m === '*' || __re.test(location.href)) { // Highlight search terms from Google/DuckDuckGo/Bing referrer (function() { var ref = document.referrer; var terms = []; if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) { var url = new URL(ref); var q = url.searchParams.get('q') || url.searchParams.get('p'); if (q) { terms = q.split(/\s+/).filter(function(t) { return t.length > 2; }); } } if (terms.length === 0) return; var style = document.createElement('style'); style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }'; document.head.appendChild(style); function highlight(node) { if (node.nodeType === 3) { // text node var text = node.textContent; var found = false; terms.forEach(function(term) { var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\]\\]/g, '\\') + ')', 'gi'); if (regex.test(text)) { found = true; var frag = document.createDocumentFragment(); var parts = text.split(regex); parts.forEach(function(part, i) { if (i % 2 === 0) { frag.appendChild(document.createTextNode(part)); } else { var span = document.createElement('span'); span.className = 'userscript-highlight'; span.textContent = part; frag.appendChild(span); } }); node.parentNode.replaceChild(frag, node); } }); } else if (node.nodeType === 1 && node.childNodes) { // element var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT']; if (!skipTags.includes(node.tagName)) { Array.from(node.childNodes).forEach(highlight); } } } highlight(document.body); // Re-highlight on dynamic content var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1 || node.nodeType === 3) highlight(node); }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] by renovate[bot] · Pull Request #156 · sky0621/cv-admin · GitHub
Skip to content

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - #156

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability
Open

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]#156
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
github.com/labstack/echo/v4v4.13.3v4.15.3ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

CVE-2026-55677 / GHSA-vfp3-v2gw-7wfq

More information

Details

Summary

Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.

Details

Root cause 1 — router.go lines 798-802:
The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern.

if!r.useEscapedPathForRouting&&req.URL.RawPath!="" {
path=req.URL.RawPath
}

Root cause 2 — echo.go lines 559-568:
StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.

if!disablePathUnescaping {
tmpPath, err:=url.PathUnescape(p)
p=tmpPath
}
name:=filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot)

Sample:
image

403:
image

Bypass with encoded slash:
image

Impact

Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/%2F) in the URL to bypass all route-level protection.

Common affected pattern:

adminGroup:=e.Group("/admin", authMiddleware)
e.StaticFS("/", os.DirFS("public"))

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

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

v4.15.3: - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Compare Source

Security

  • fix(static): reject encoded path separators that bypass route-level middleware by @​vishr in #​3011

Fixes GHSA-vfp3-v2gw-7wfq: an encoded path separator (%2F or %5C) in a static file URL could bypass route-level middleware (e.g. authentication on a sibling route) and disclose static files. Both StaticDirectoryHandler (used by Static/StaticFS) and the Static middleware are affected. Backport of the v5 fix (#​3009, released in v5.2.0). Thanks to @​a-tt-om and @​oran-gugu for reporting.

Full Changelog: labstack/echo@v4.15.2...v4.15.3

v4.15.2: - Context.Scheme() header validation

Compare Source

Security

Thanks to @​shblue21 for reporting this issue.

Full Changelog: labstack/echo@v4.15.1...v4.15.2

v4.15.1

Compare Source

What's Changed

  • CSRF: support older token-based CSRF protection handler that want to render token into template by @​aldas in #​2905

Full Changelog: labstack/echo@v4.15.0...v4.15.1

v4.15.0

Compare Source

Security

NB: If your application relies on cross-origin or same-site (same subdomain) requests do not blindly push this version to production

The CSRF middleware now supports the Sec-Fetch-Site header as a modern, defense-in-depth approach to CSRF
protection
, implementing the OWASP-recommended Fetch Metadata API alongside the traditional token-based mechanism.

How it works:

Modern browsers automatically send the Sec-Fetch-Site header with all requests, indicating the relationship
between the request origin and the target. The middleware uses this to make security decisions:

  • same-origin or none: Requests are allowed (exact origin match or direct user navigation)
  • same-site: Falls back to token validation (e.g., subdomain to main domain)
  • cross-site: Blocked by default with 403 error for unsafe methods (POST, PUT, DELETE, PATCH)

For browsers that don't send this header (older browsers), the middleware seamlessly falls back to
traditional token-based CSRF protection.

New Configuration Options:

  • TrustedOrigins []string: Allowlist specific origins for cross-site requests (useful for OAuth callbacks, webhooks)
  • AllowSecFetchSiteFunc func(echo.Context) (bool, error): Custom logic for same-site/cross-site request validation

Example:

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from trusted providerTrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site requestsAllowSecFetchSiteFunc: func(c echo.Context) (bool, error) {
// Your custom authorization logic herereturnvalidateCustomAuth(c), nil// return true, err // blocks request with error// return true, nil // allows CSRF request through// return false, nil // falls back to legacy token logic
},
}))

PR: #​2858

Type-Safe Generic Parameter Binding

  • Added generic functions for type-safe parameter extraction and context access by @​aldas in #​2856

    Echo now provides generic functions for extracting path, query, and form parameters with automatic type conversion,
    eliminating manual string parsing and type assertions.

    New Functions:

    • Path parameters: PathParam[T], PathParamOr[T]
    • Query parameters: QueryParam[T], QueryParamOr[T], QueryParams[T], QueryParamsOr[T]
    • Form values: FormParam[T], FormParamOr[T], FormParams[T], FormParamsOr[T]
    • Context store: ContextGet[T], ContextGetOr[T]

    Supported Types:
    Primitives (bool, string, int/uint variants, float32/float64), time.Duration, time.Time
    (with custom layouts and Unix timestamp support), and custom types implementing BindUnmarshaler,
    TextUnmarshaler, or JSONUnmarshaler.

    Example:

    // Before: Manual parsingidStr:=c.Param("id")
    id, err:=strconv.Atoi(idStr)
    // After: Type-safe with automatic parsingid, err:=echo.PathParam[int](c, "id")
    // With default valuespage, err:=echo.QueryParamOr[int](c, "page", 1)
    limit, err:=echo.QueryParamOr[int](c, "limit", 20)
    // Type-safe context access (no more panics from type assertions)user, err:=echo.ContextGet[*User](c, "user")

PR: #​2856

DEPRECATION NOTICE Timeout Middleware Deprecated - Use ContextTimeout Instead

The middleware.Timeout middleware has been deprecated due to fundamental architectural issues that cause
data races. Use middleware.ContextTimeout or middleware.ContextTimeoutWithConfig instead.

Why is this being deprecated?

The Timeout middleware manipulates response writers across goroutine boundaries, which causes data races that
cannot be reliably fixed without a complete architectural redesign. The middleware:

  • Swaps the response writer using http.TimeoutHandler
  • Must be the first middleware in the chain (fragile constraint)
  • Can cause races with other middleware (Logger, metrics, custom middleware)
  • Has been the source of multiple race condition fixes over the years

What should you use instead?

The ContextTimeout middleware (available since v4.12.0) provides timeout functionality using Go's standard
context mechanism. It is:

  • Race-free by design
  • Can be placed anywhere in the middleware chain
  • Simpler and more maintainable
  • Compatible with all other middleware

Migration Guide:

// Before (deprecated):e.Use(middleware.Timeout())
// After (recommended):e.Use(middleware.ContextTimeout(30*time.Second))

Important Behavioral Differences:

  1. Handler cooperation required: With ContextTimeout, your handlers must check context.Done() for cooperative
    cancellation. The old Timeout middleware would send a 503 response regardless of handler cooperation, but had
    data race issues.

  2. Error handling: ContextTimeout returns errors through the standard error handling flow. Handlers that receive
    context.DeadlineExceeded should handle it appropriately:

e.GET("/long-task", func(c echo.Context) error {
ctx:=c.Request().Context()
// Example: database query with contextresult, err:=db.QueryContext(ctx, "SELECT * FROM large_table")
iferr!=nil {
iferrors.Is(err, context.DeadlineExceeded) {
// Handle timeoutreturnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
returnerr
}
returnc.JSON(http.StatusOK, result)
})
  1. Background tasks: For long-running background tasks, use goroutines with context:
e.GET("/async-task", func(c echo.Context) error {
ctx:=c.Request().Context()
resultCh:=make(chanResult, 1)
errCh:=make(chanerror, 1)
gofunc() {
result, err:=performLongTask(ctx)
iferr!=nil {
errCh<-errreturn
}
resultCh<-result
}()
select {
caseresult:=<-resultCh:
returnc.JSON(http.StatusOK, result)
caseerr:=<-errCh:
returnerrcase<-ctx.Done():
returnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
})

Enhancements

v4.14.0

Compare Source

middleware.Logger has been deprecated. For request logging, use middleware.RequestLogger or
middleware.RequestLoggerWithConfig.

middleware.RequestLogger replaces middleware.Logger, offering comparable configuration while relying on the
Go standard library’s new slog logger.

The previous default output format was JSON. The new default follows the standard slog logger settings.
To continue emitting request logs in JSON, configure slog accordingly:

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
e.Use(middleware.RequestLogger())

Security

Enhancements

v4.13.4

Compare Source

Enhancements

Security


Configuration

📅 Schedule: (in timezone Asia/Tokyo)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovateBot commented Aug 25, 2026

Copy link
Copy Markdown
ContributorAuthor

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 12 additional dependencies were updated
  • The go directive was updated for compatibility reasons

Details:

PackageChange
go1.24.2 -> 1.25.0
github.com/stretchr/testifyv1.10.0 -> v1.11.1
github.com/labstack/gommonv0.4.2 -> v0.5.0
github.com/mattn/go-colorablev0.1.13 -> v0.1.14
github.com/mattn/go-isattyv0.0.20 -> v0.0.22
golang.org/x/cryptov0.36.0 -> v0.50.0
golang.org/x/modv0.24.0 -> v0.34.0
golang.org/x/netv0.37.0 -> v0.53.0
golang.org/x/syncv0.13.0 -> v0.20.0
golang.org/x/sysv0.31.0 -> v0.43.0
golang.org/x/textv0.23.0 -> v0.36.0
golang.org/x/timev0.8.0 -> v0.15.0
golang.org/x/toolsv0.31.0 -> v0.43.0

@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 28, 2026
@renovaterenovateBot closed this Aug 28, 2026
@renovate
renovateBot deleted the renovate/go-github.com-labstack-echo-v4-vulnerability branch August 28, 2026 21:59
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from cb18ce6 to d3d1ad1CompareAugust 29, 2026 03:05
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 29, 2026
@renovaterenovateBot closed this Aug 29, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch from cb18ce6 to f224246CompareAugust 29, 2026 22:40
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 30, 2026
@renovaterenovateBot reopened this Aug 30, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from f224246 to 25c1b10CompareAugust 30, 2026 04:49
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 25c1b10 to 064deb3CompareAugust 31, 2026 01:41
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 31, 2026
@renovaterenovateBot closed this Aug 31, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 064deb3 to d6a24f0CompareAugust 31, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

, 'i'); if (__m === '*' || __re.test(location.href)) { // Strip utm_, fbclid, gclid, etc. from all links on page (function() { var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content', 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid', 'ref', 'ref_src', 'source', 'medium', 'campaign']; function cleanUrl(url) { try { var u = new URL(url, window.location.origin); var changed = false; trackingParams.forEach(function(p) { if (u.searchParams.has(p)) { u.searchParams.delete(p); changed = true; } }); return changed ? u.toString() : url; } catch (e) { return url; } } function cleanLinks() { document.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } cleanLinks(); var observer = new MutationObserver(function(mutations) { mutations.forEach(function(m) { m.addedNodes.forEach(function(node) { if (node.nodeType === 1) { if (node.tagName === 'A') cleanLinks(); node.querySelectorAll('a[href]').forEach(function(a) { var clean = cleanUrl(a.href); if (clean !== a.href) a.href = clean; }); } }); }); }); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + ' Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] by renovate[bot] · Pull Request #156 · sky0621/cv-admin · GitHub
Skip to content

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - #156

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability
Open

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]#156
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
github.com/labstack/echo/v4v4.13.3v4.15.3ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

CVE-2026-55677 / GHSA-vfp3-v2gw-7wfq

More information

Details

Summary

Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.

Details

Root cause 1 — router.go lines 798-802:
The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern.

if!r.useEscapedPathForRouting&&req.URL.RawPath!="" {
path=req.URL.RawPath
}

Root cause 2 — echo.go lines 559-568:
StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.

if!disablePathUnescaping {
tmpPath, err:=url.PathUnescape(p)
p=tmpPath
}
name:=filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot)

Sample:
image

403:
image

Bypass with encoded slash:
image

Impact

Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/%2F) in the URL to bypass all route-level protection.

Common affected pattern:

adminGroup:=e.Group("/admin", authMiddleware)
e.StaticFS("/", os.DirFS("public"))

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

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

v4.15.3: - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Compare Source

Security

  • fix(static): reject encoded path separators that bypass route-level middleware by @​vishr in #​3011

Fixes GHSA-vfp3-v2gw-7wfq: an encoded path separator (%2F or %5C) in a static file URL could bypass route-level middleware (e.g. authentication on a sibling route) and disclose static files. Both StaticDirectoryHandler (used by Static/StaticFS) and the Static middleware are affected. Backport of the v5 fix (#​3009, released in v5.2.0). Thanks to @​a-tt-om and @​oran-gugu for reporting.

Full Changelog: labstack/echo@v4.15.2...v4.15.3

v4.15.2: - Context.Scheme() header validation

Compare Source

Security

Thanks to @​shblue21 for reporting this issue.

Full Changelog: labstack/echo@v4.15.1...v4.15.2

v4.15.1

Compare Source

What's Changed

  • CSRF: support older token-based CSRF protection handler that want to render token into template by @​aldas in #​2905

Full Changelog: labstack/echo@v4.15.0...v4.15.1

v4.15.0

Compare Source

Security

NB: If your application relies on cross-origin or same-site (same subdomain) requests do not blindly push this version to production

The CSRF middleware now supports the Sec-Fetch-Site header as a modern, defense-in-depth approach to CSRF
protection
, implementing the OWASP-recommended Fetch Metadata API alongside the traditional token-based mechanism.

How it works:

Modern browsers automatically send the Sec-Fetch-Site header with all requests, indicating the relationship
between the request origin and the target. The middleware uses this to make security decisions:

  • same-origin or none: Requests are allowed (exact origin match or direct user navigation)
  • same-site: Falls back to token validation (e.g., subdomain to main domain)
  • cross-site: Blocked by default with 403 error for unsafe methods (POST, PUT, DELETE, PATCH)

For browsers that don't send this header (older browsers), the middleware seamlessly falls back to
traditional token-based CSRF protection.

New Configuration Options:

  • TrustedOrigins []string: Allowlist specific origins for cross-site requests (useful for OAuth callbacks, webhooks)
  • AllowSecFetchSiteFunc func(echo.Context) (bool, error): Custom logic for same-site/cross-site request validation

Example:

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from trusted providerTrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site requestsAllowSecFetchSiteFunc: func(c echo.Context) (bool, error) {
// Your custom authorization logic herereturnvalidateCustomAuth(c), nil// return true, err // blocks request with error// return true, nil // allows CSRF request through// return false, nil // falls back to legacy token logic
},
}))

PR: #​2858

Type-Safe Generic Parameter Binding

  • Added generic functions for type-safe parameter extraction and context access by @​aldas in #​2856

    Echo now provides generic functions for extracting path, query, and form parameters with automatic type conversion,
    eliminating manual string parsing and type assertions.

    New Functions:

    • Path parameters: PathParam[T], PathParamOr[T]
    • Query parameters: QueryParam[T], QueryParamOr[T], QueryParams[T], QueryParamsOr[T]
    • Form values: FormParam[T], FormParamOr[T], FormParams[T], FormParamsOr[T]
    • Context store: ContextGet[T], ContextGetOr[T]

    Supported Types:
    Primitives (bool, string, int/uint variants, float32/float64), time.Duration, time.Time
    (with custom layouts and Unix timestamp support), and custom types implementing BindUnmarshaler,
    TextUnmarshaler, or JSONUnmarshaler.

    Example:

    // Before: Manual parsingidStr:=c.Param("id")
    id, err:=strconv.Atoi(idStr)
    // After: Type-safe with automatic parsingid, err:=echo.PathParam[int](c, "id")
    // With default valuespage, err:=echo.QueryParamOr[int](c, "page", 1)
    limit, err:=echo.QueryParamOr[int](c, "limit", 20)
    // Type-safe context access (no more panics from type assertions)user, err:=echo.ContextGet[*User](c, "user")

PR: #​2856

DEPRECATION NOTICE Timeout Middleware Deprecated - Use ContextTimeout Instead

The middleware.Timeout middleware has been deprecated due to fundamental architectural issues that cause
data races. Use middleware.ContextTimeout or middleware.ContextTimeoutWithConfig instead.

Why is this being deprecated?

The Timeout middleware manipulates response writers across goroutine boundaries, which causes data races that
cannot be reliably fixed without a complete architectural redesign. The middleware:

  • Swaps the response writer using http.TimeoutHandler
  • Must be the first middleware in the chain (fragile constraint)
  • Can cause races with other middleware (Logger, metrics, custom middleware)
  • Has been the source of multiple race condition fixes over the years

What should you use instead?

The ContextTimeout middleware (available since v4.12.0) provides timeout functionality using Go's standard
context mechanism. It is:

  • Race-free by design
  • Can be placed anywhere in the middleware chain
  • Simpler and more maintainable
  • Compatible with all other middleware

Migration Guide:

// Before (deprecated):e.Use(middleware.Timeout())
// After (recommended):e.Use(middleware.ContextTimeout(30*time.Second))

Important Behavioral Differences:

  1. Handler cooperation required: With ContextTimeout, your handlers must check context.Done() for cooperative
    cancellation. The old Timeout middleware would send a 503 response regardless of handler cooperation, but had
    data race issues.

  2. Error handling: ContextTimeout returns errors through the standard error handling flow. Handlers that receive
    context.DeadlineExceeded should handle it appropriately:

e.GET("/long-task", func(c echo.Context) error {
ctx:=c.Request().Context()
// Example: database query with contextresult, err:=db.QueryContext(ctx, "SELECT * FROM large_table")
iferr!=nil {
iferrors.Is(err, context.DeadlineExceeded) {
// Handle timeoutreturnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
returnerr
}
returnc.JSON(http.StatusOK, result)
})
  1. Background tasks: For long-running background tasks, use goroutines with context:
e.GET("/async-task", func(c echo.Context) error {
ctx:=c.Request().Context()
resultCh:=make(chanResult, 1)
errCh:=make(chanerror, 1)
gofunc() {
result, err:=performLongTask(ctx)
iferr!=nil {
errCh<-errreturn
}
resultCh<-result
}()
select {
caseresult:=<-resultCh:
returnc.JSON(http.StatusOK, result)
caseerr:=<-errCh:
returnerrcase<-ctx.Done():
returnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
})

Enhancements

v4.14.0

Compare Source

middleware.Logger has been deprecated. For request logging, use middleware.RequestLogger or
middleware.RequestLoggerWithConfig.

middleware.RequestLogger replaces middleware.Logger, offering comparable configuration while relying on the
Go standard library’s new slog logger.

The previous default output format was JSON. The new default follows the standard slog logger settings.
To continue emitting request logs in JSON, configure slog accordingly:

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
e.Use(middleware.RequestLogger())

Security

Enhancements

v4.13.4

Compare Source

Enhancements

Security


Configuration

📅 Schedule: (in timezone Asia/Tokyo)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovateBot commented Aug 25, 2026

Copy link
Copy Markdown
ContributorAuthor

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 12 additional dependencies were updated
  • The go directive was updated for compatibility reasons

Details:

PackageChange
go1.24.2 -> 1.25.0
github.com/stretchr/testifyv1.10.0 -> v1.11.1
github.com/labstack/gommonv0.4.2 -> v0.5.0
github.com/mattn/go-colorablev0.1.13 -> v0.1.14
github.com/mattn/go-isattyv0.0.20 -> v0.0.22
golang.org/x/cryptov0.36.0 -> v0.50.0
golang.org/x/modv0.24.0 -> v0.34.0
golang.org/x/netv0.37.0 -> v0.53.0
golang.org/x/syncv0.13.0 -> v0.20.0
golang.org/x/sysv0.31.0 -> v0.43.0
golang.org/x/textv0.23.0 -> v0.36.0
golang.org/x/timev0.8.0 -> v0.15.0
golang.org/x/toolsv0.31.0 -> v0.43.0

@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 28, 2026
@renovaterenovateBot closed this Aug 28, 2026
@renovate
renovateBot deleted the renovate/go-github.com-labstack-echo-v4-vulnerability branch August 28, 2026 21:59
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from cb18ce6 to d3d1ad1CompareAugust 29, 2026 03:05
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 29, 2026
@renovaterenovateBot closed this Aug 29, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch from cb18ce6 to f224246CompareAugust 29, 2026 22:40
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 30, 2026
@renovaterenovateBot reopened this Aug 30, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from f224246 to 25c1b10CompareAugust 30, 2026 04:49
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 25c1b10 to 064deb3CompareAugust 31, 2026 01:41
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 31, 2026
@renovaterenovateBot closed this Aug 31, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 064deb3 to d6a24f0CompareAugust 31, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

, 'i'); if (__m === '*' || __re.test(location.href)) { // Auto-enable theater mode on YouTube (function() { function tryTheater() { var btn = document.querySelector('button[aria-label="Theater mode"], ytd-player #player button[title="Theater mode"]'); if (btn && !btn.classList.contains('activated')) { btn.click(); } } // Try immediately tryTheater(); // Try after navigation (SPA) var lastUrl = location.href; setInterval(function() { if (location.href !== lastUrl) { lastUrl = location.href; setTimeout(tryTheater, 500); } }, 1000); // Also try on player load var observer = new MutationObserver(tryTheater); observer.observe(document.body, { childList: true, subtree: true }); })(); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] by renovate[bot] · Pull Request #156 · sky0621/cv-admin · GitHub
Skip to content

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - #156

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability
Open

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]#156
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
github.com/labstack/echo/v4v4.13.3v4.15.3ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

CVE-2026-55677 / GHSA-vfp3-v2gw-7wfq

More information

Details

Summary

Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.

Details

Root cause 1 — router.go lines 798-802:
The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern.

if!r.useEscapedPathForRouting&&req.URL.RawPath!="" {
path=req.URL.RawPath
}

Root cause 2 — echo.go lines 559-568:
StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.

if!disablePathUnescaping {
tmpPath, err:=url.PathUnescape(p)
p=tmpPath
}
name:=filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot)

Sample:
image

403:
image

Bypass with encoded slash:
image

Impact

Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/%2F) in the URL to bypass all route-level protection.

Common affected pattern:

adminGroup:=e.Group("/admin", authMiddleware)
e.StaticFS("/", os.DirFS("public"))

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

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

v4.15.3: - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Compare Source

Security

  • fix(static): reject encoded path separators that bypass route-level middleware by @​vishr in #​3011

Fixes GHSA-vfp3-v2gw-7wfq: an encoded path separator (%2F or %5C) in a static file URL could bypass route-level middleware (e.g. authentication on a sibling route) and disclose static files. Both StaticDirectoryHandler (used by Static/StaticFS) and the Static middleware are affected. Backport of the v5 fix (#​3009, released in v5.2.0). Thanks to @​a-tt-om and @​oran-gugu for reporting.

Full Changelog: labstack/echo@v4.15.2...v4.15.3

v4.15.2: - Context.Scheme() header validation

Compare Source

Security

Thanks to @​shblue21 for reporting this issue.

Full Changelog: labstack/echo@v4.15.1...v4.15.2

v4.15.1

Compare Source

What's Changed

  • CSRF: support older token-based CSRF protection handler that want to render token into template by @​aldas in #​2905

Full Changelog: labstack/echo@v4.15.0...v4.15.1

v4.15.0

Compare Source

Security

NB: If your application relies on cross-origin or same-site (same subdomain) requests do not blindly push this version to production

The CSRF middleware now supports the Sec-Fetch-Site header as a modern, defense-in-depth approach to CSRF
protection
, implementing the OWASP-recommended Fetch Metadata API alongside the traditional token-based mechanism.

How it works:

Modern browsers automatically send the Sec-Fetch-Site header with all requests, indicating the relationship
between the request origin and the target. The middleware uses this to make security decisions:

  • same-origin or none: Requests are allowed (exact origin match or direct user navigation)
  • same-site: Falls back to token validation (e.g., subdomain to main domain)
  • cross-site: Blocked by default with 403 error for unsafe methods (POST, PUT, DELETE, PATCH)

For browsers that don't send this header (older browsers), the middleware seamlessly falls back to
traditional token-based CSRF protection.

New Configuration Options:

  • TrustedOrigins []string: Allowlist specific origins for cross-site requests (useful for OAuth callbacks, webhooks)
  • AllowSecFetchSiteFunc func(echo.Context) (bool, error): Custom logic for same-site/cross-site request validation

Example:

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from trusted providerTrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site requestsAllowSecFetchSiteFunc: func(c echo.Context) (bool, error) {
// Your custom authorization logic herereturnvalidateCustomAuth(c), nil// return true, err // blocks request with error// return true, nil // allows CSRF request through// return false, nil // falls back to legacy token logic
},
}))

PR: #​2858

Type-Safe Generic Parameter Binding

  • Added generic functions for type-safe parameter extraction and context access by @​aldas in #​2856

    Echo now provides generic functions for extracting path, query, and form parameters with automatic type conversion,
    eliminating manual string parsing and type assertions.

    New Functions:

    • Path parameters: PathParam[T], PathParamOr[T]
    • Query parameters: QueryParam[T], QueryParamOr[T], QueryParams[T], QueryParamsOr[T]
    • Form values: FormParam[T], FormParamOr[T], FormParams[T], FormParamsOr[T]
    • Context store: ContextGet[T], ContextGetOr[T]

    Supported Types:
    Primitives (bool, string, int/uint variants, float32/float64), time.Duration, time.Time
    (with custom layouts and Unix timestamp support), and custom types implementing BindUnmarshaler,
    TextUnmarshaler, or JSONUnmarshaler.

    Example:

    // Before: Manual parsingidStr:=c.Param("id")
    id, err:=strconv.Atoi(idStr)
    // After: Type-safe with automatic parsingid, err:=echo.PathParam[int](c, "id")
    // With default valuespage, err:=echo.QueryParamOr[int](c, "page", 1)
    limit, err:=echo.QueryParamOr[int](c, "limit", 20)
    // Type-safe context access (no more panics from type assertions)user, err:=echo.ContextGet[*User](c, "user")

PR: #​2856

DEPRECATION NOTICE Timeout Middleware Deprecated - Use ContextTimeout Instead

The middleware.Timeout middleware has been deprecated due to fundamental architectural issues that cause
data races. Use middleware.ContextTimeout or middleware.ContextTimeoutWithConfig instead.

Why is this being deprecated?

The Timeout middleware manipulates response writers across goroutine boundaries, which causes data races that
cannot be reliably fixed without a complete architectural redesign. The middleware:

  • Swaps the response writer using http.TimeoutHandler
  • Must be the first middleware in the chain (fragile constraint)
  • Can cause races with other middleware (Logger, metrics, custom middleware)
  • Has been the source of multiple race condition fixes over the years

What should you use instead?

The ContextTimeout middleware (available since v4.12.0) provides timeout functionality using Go's standard
context mechanism. It is:

  • Race-free by design
  • Can be placed anywhere in the middleware chain
  • Simpler and more maintainable
  • Compatible with all other middleware

Migration Guide:

// Before (deprecated):e.Use(middleware.Timeout())
// After (recommended):e.Use(middleware.ContextTimeout(30*time.Second))

Important Behavioral Differences:

  1. Handler cooperation required: With ContextTimeout, your handlers must check context.Done() for cooperative
    cancellation. The old Timeout middleware would send a 503 response regardless of handler cooperation, but had
    data race issues.

  2. Error handling: ContextTimeout returns errors through the standard error handling flow. Handlers that receive
    context.DeadlineExceeded should handle it appropriately:

e.GET("/long-task", func(c echo.Context) error {
ctx:=c.Request().Context()
// Example: database query with contextresult, err:=db.QueryContext(ctx, "SELECT * FROM large_table")
iferr!=nil {
iferrors.Is(err, context.DeadlineExceeded) {
// Handle timeoutreturnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
returnerr
}
returnc.JSON(http.StatusOK, result)
})
  1. Background tasks: For long-running background tasks, use goroutines with context:
e.GET("/async-task", func(c echo.Context) error {
ctx:=c.Request().Context()
resultCh:=make(chanResult, 1)
errCh:=make(chanerror, 1)
gofunc() {
result, err:=performLongTask(ctx)
iferr!=nil {
errCh<-errreturn
}
resultCh<-result
}()
select {
caseresult:=<-resultCh:
returnc.JSON(http.StatusOK, result)
caseerr:=<-errCh:
returnerrcase<-ctx.Done():
returnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
})

Enhancements

v4.14.0

Compare Source

middleware.Logger has been deprecated. For request logging, use middleware.RequestLogger or
middleware.RequestLoggerWithConfig.

middleware.RequestLogger replaces middleware.Logger, offering comparable configuration while relying on the
Go standard library’s new slog logger.

The previous default output format was JSON. The new default follows the standard slog logger settings.
To continue emitting request logs in JSON, configure slog accordingly:

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
e.Use(middleware.RequestLogger())

Security

Enhancements

v4.13.4

Compare Source

Enhancements

Security


Configuration

📅 Schedule: (in timezone Asia/Tokyo)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovateBot commented Aug 25, 2026

Copy link
Copy Markdown
ContributorAuthor

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 12 additional dependencies were updated
  • The go directive was updated for compatibility reasons

Details:

PackageChange
go1.24.2 -> 1.25.0
github.com/stretchr/testifyv1.10.0 -> v1.11.1
github.com/labstack/gommonv0.4.2 -> v0.5.0
github.com/mattn/go-colorablev0.1.13 -> v0.1.14
github.com/mattn/go-isattyv0.0.20 -> v0.0.22
golang.org/x/cryptov0.36.0 -> v0.50.0
golang.org/x/modv0.24.0 -> v0.34.0
golang.org/x/netv0.37.0 -> v0.53.0
golang.org/x/syncv0.13.0 -> v0.20.0
golang.org/x/sysv0.31.0 -> v0.43.0
golang.org/x/textv0.23.0 -> v0.36.0
golang.org/x/timev0.8.0 -> v0.15.0
golang.org/x/toolsv0.31.0 -> v0.43.0

@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 28, 2026
@renovaterenovateBot closed this Aug 28, 2026
@renovate
renovateBot deleted the renovate/go-github.com-labstack-echo-v4-vulnerability branch August 28, 2026 21:59
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from cb18ce6 to d3d1ad1CompareAugust 29, 2026 03:05
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 29, 2026
@renovaterenovateBot closed this Aug 29, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch from cb18ce6 to f224246CompareAugust 29, 2026 22:40
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 30, 2026
@renovaterenovateBot reopened this Aug 30, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from f224246 to 25c1b10CompareAugust 30, 2026 04:49
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 25c1b10 to 064deb3CompareAugust 31, 2026 01:41
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 31, 2026
@renovaterenovateBot closed this Aug 31, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 064deb3 to d6a24f0CompareAugust 31, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

, 'i'); if (__m === '*' || __re.test(location.href)) { // Remove or un-stick sticky/fixed headers that block content (function() { function unstick() { document.querySelectorAll('header, nav, [role="banner"], .header, .navbar, .sticky, .fixed-top, [style*="position: fixed"], [style*="position:sticky"]').forEach(function(el) { if (el.style.position === 'fixed' || el.style.position === 'sticky' || getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') { el.style.position = 'static'; el.style.top = 'auto'; el.style.zIndex = 'auto'; } }); } unstick(); var observer = new MutationObserver(unstick); observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] }); })(); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + ' Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] by renovate[bot] · Pull Request #156 · sky0621/cv-admin · GitHub
Skip to content

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - #156

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability
Open

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]#156
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
github.com/labstack/echo/v4v4.13.3v4.15.3ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

CVE-2026-55677 / GHSA-vfp3-v2gw-7wfq

More information

Details

Summary

Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.

Details

Root cause 1 — router.go lines 798-802:
The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern.

if!r.useEscapedPathForRouting&&req.URL.RawPath!="" {
path=req.URL.RawPath
}

Root cause 2 — echo.go lines 559-568:
StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.

if!disablePathUnescaping {
tmpPath, err:=url.PathUnescape(p)
p=tmpPath
}
name:=filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot)

Sample:
image

403:
image

Bypass with encoded slash:
image

Impact

Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/%2F) in the URL to bypass all route-level protection.

Common affected pattern:

adminGroup:=e.Group("/admin", authMiddleware)
e.StaticFS("/", os.DirFS("public"))

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

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

v4.15.3: - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Compare Source

Security

  • fix(static): reject encoded path separators that bypass route-level middleware by @​vishr in #​3011

Fixes GHSA-vfp3-v2gw-7wfq: an encoded path separator (%2F or %5C) in a static file URL could bypass route-level middleware (e.g. authentication on a sibling route) and disclose static files. Both StaticDirectoryHandler (used by Static/StaticFS) and the Static middleware are affected. Backport of the v5 fix (#​3009, released in v5.2.0). Thanks to @​a-tt-om and @​oran-gugu for reporting.

Full Changelog: labstack/echo@v4.15.2...v4.15.3

v4.15.2: - Context.Scheme() header validation

Compare Source

Security

Thanks to @​shblue21 for reporting this issue.

Full Changelog: labstack/echo@v4.15.1...v4.15.2

v4.15.1

Compare Source

What's Changed

  • CSRF: support older token-based CSRF protection handler that want to render token into template by @​aldas in #​2905

Full Changelog: labstack/echo@v4.15.0...v4.15.1

v4.15.0

Compare Source

Security

NB: If your application relies on cross-origin or same-site (same subdomain) requests do not blindly push this version to production

The CSRF middleware now supports the Sec-Fetch-Site header as a modern, defense-in-depth approach to CSRF
protection
, implementing the OWASP-recommended Fetch Metadata API alongside the traditional token-based mechanism.

How it works:

Modern browsers automatically send the Sec-Fetch-Site header with all requests, indicating the relationship
between the request origin and the target. The middleware uses this to make security decisions:

  • same-origin or none: Requests are allowed (exact origin match or direct user navigation)
  • same-site: Falls back to token validation (e.g., subdomain to main domain)
  • cross-site: Blocked by default with 403 error for unsafe methods (POST, PUT, DELETE, PATCH)

For browsers that don't send this header (older browsers), the middleware seamlessly falls back to
traditional token-based CSRF protection.

New Configuration Options:

  • TrustedOrigins []string: Allowlist specific origins for cross-site requests (useful for OAuth callbacks, webhooks)
  • AllowSecFetchSiteFunc func(echo.Context) (bool, error): Custom logic for same-site/cross-site request validation

Example:

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from trusted providerTrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site requestsAllowSecFetchSiteFunc: func(c echo.Context) (bool, error) {
// Your custom authorization logic herereturnvalidateCustomAuth(c), nil// return true, err // blocks request with error// return true, nil // allows CSRF request through// return false, nil // falls back to legacy token logic
},
}))

PR: #​2858

Type-Safe Generic Parameter Binding

  • Added generic functions for type-safe parameter extraction and context access by @​aldas in #​2856

    Echo now provides generic functions for extracting path, query, and form parameters with automatic type conversion,
    eliminating manual string parsing and type assertions.

    New Functions:

    • Path parameters: PathParam[T], PathParamOr[T]
    • Query parameters: QueryParam[T], QueryParamOr[T], QueryParams[T], QueryParamsOr[T]
    • Form values: FormParam[T], FormParamOr[T], FormParams[T], FormParamsOr[T]
    • Context store: ContextGet[T], ContextGetOr[T]

    Supported Types:
    Primitives (bool, string, int/uint variants, float32/float64), time.Duration, time.Time
    (with custom layouts and Unix timestamp support), and custom types implementing BindUnmarshaler,
    TextUnmarshaler, or JSONUnmarshaler.

    Example:

    // Before: Manual parsingidStr:=c.Param("id")
    id, err:=strconv.Atoi(idStr)
    // After: Type-safe with automatic parsingid, err:=echo.PathParam[int](c, "id")
    // With default valuespage, err:=echo.QueryParamOr[int](c, "page", 1)
    limit, err:=echo.QueryParamOr[int](c, "limit", 20)
    // Type-safe context access (no more panics from type assertions)user, err:=echo.ContextGet[*User](c, "user")

PR: #​2856

DEPRECATION NOTICE Timeout Middleware Deprecated - Use ContextTimeout Instead

The middleware.Timeout middleware has been deprecated due to fundamental architectural issues that cause
data races. Use middleware.ContextTimeout or middleware.ContextTimeoutWithConfig instead.

Why is this being deprecated?

The Timeout middleware manipulates response writers across goroutine boundaries, which causes data races that
cannot be reliably fixed without a complete architectural redesign. The middleware:

  • Swaps the response writer using http.TimeoutHandler
  • Must be the first middleware in the chain (fragile constraint)
  • Can cause races with other middleware (Logger, metrics, custom middleware)
  • Has been the source of multiple race condition fixes over the years

What should you use instead?

The ContextTimeout middleware (available since v4.12.0) provides timeout functionality using Go's standard
context mechanism. It is:

  • Race-free by design
  • Can be placed anywhere in the middleware chain
  • Simpler and more maintainable
  • Compatible with all other middleware

Migration Guide:

// Before (deprecated):e.Use(middleware.Timeout())
// After (recommended):e.Use(middleware.ContextTimeout(30*time.Second))

Important Behavioral Differences:

  1. Handler cooperation required: With ContextTimeout, your handlers must check context.Done() for cooperative
    cancellation. The old Timeout middleware would send a 503 response regardless of handler cooperation, but had
    data race issues.

  2. Error handling: ContextTimeout returns errors through the standard error handling flow. Handlers that receive
    context.DeadlineExceeded should handle it appropriately:

e.GET("/long-task", func(c echo.Context) error {
ctx:=c.Request().Context()
// Example: database query with contextresult, err:=db.QueryContext(ctx, "SELECT * FROM large_table")
iferr!=nil {
iferrors.Is(err, context.DeadlineExceeded) {
// Handle timeoutreturnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
returnerr
}
returnc.JSON(http.StatusOK, result)
})
  1. Background tasks: For long-running background tasks, use goroutines with context:
e.GET("/async-task", func(c echo.Context) error {
ctx:=c.Request().Context()
resultCh:=make(chanResult, 1)
errCh:=make(chanerror, 1)
gofunc() {
result, err:=performLongTask(ctx)
iferr!=nil {
errCh<-errreturn
}
resultCh<-result
}()
select {
caseresult:=<-resultCh:
returnc.JSON(http.StatusOK, result)
caseerr:=<-errCh:
returnerrcase<-ctx.Done():
returnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
})

Enhancements

v4.14.0

Compare Source

middleware.Logger has been deprecated. For request logging, use middleware.RequestLogger or
middleware.RequestLoggerWithConfig.

middleware.RequestLogger replaces middleware.Logger, offering comparable configuration while relying on the
Go standard library’s new slog logger.

The previous default output format was JSON. The new default follows the standard slog logger settings.
To continue emitting request logs in JSON, configure slog accordingly:

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
e.Use(middleware.RequestLogger())

Security

Enhancements

v4.13.4

Compare Source

Enhancements

Security


Configuration

📅 Schedule: (in timezone Asia/Tokyo)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovateBot commented Aug 25, 2026

Copy link
Copy Markdown
ContributorAuthor

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 12 additional dependencies were updated
  • The go directive was updated for compatibility reasons

Details:

PackageChange
go1.24.2 -> 1.25.0
github.com/stretchr/testifyv1.10.0 -> v1.11.1
github.com/labstack/gommonv0.4.2 -> v0.5.0
github.com/mattn/go-colorablev0.1.13 -> v0.1.14
github.com/mattn/go-isattyv0.0.20 -> v0.0.22
golang.org/x/cryptov0.36.0 -> v0.50.0
golang.org/x/modv0.24.0 -> v0.34.0
golang.org/x/netv0.37.0 -> v0.53.0
golang.org/x/syncv0.13.0 -> v0.20.0
golang.org/x/sysv0.31.0 -> v0.43.0
golang.org/x/textv0.23.0 -> v0.36.0
golang.org/x/timev0.8.0 -> v0.15.0
golang.org/x/toolsv0.31.0 -> v0.43.0

@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 28, 2026
@renovaterenovateBot closed this Aug 28, 2026
@renovate
renovateBot deleted the renovate/go-github.com-labstack-echo-v4-vulnerability branch August 28, 2026 21:59
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from cb18ce6 to d3d1ad1CompareAugust 29, 2026 03:05
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 29, 2026
@renovaterenovateBot closed this Aug 29, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch from cb18ce6 to f224246CompareAugust 29, 2026 22:40
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 30, 2026
@renovaterenovateBot reopened this Aug 30, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from f224246 to 25c1b10CompareAugust 30, 2026 04:49
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 25c1b10 to 064deb3CompareAugust 31, 2026 01:41
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 31, 2026
@renovaterenovateBot closed this Aug 31, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 064deb3 to d6a24f0CompareAugust 31, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants

, 'i'); if (__m === '*' || __re.test(location.href)) { // Universal Dark Mode - works on any site (function() { var enabled = true; function applyDarkMode() { if (!enabled) return; // Create style element if it doesn't exist var style = document.getElementById('universal-dark-mode-style'); if (!style) { style = document.createElement('style'); style.id = 'universal-dark-mode-style'; document.head.appendChild(style); } // Dark mode CSS - inverts colors but preserves images/video style.textContent = ' /* Invert everything except media */ html { filter: invert(1) hue-rotate(180deg) !important; background: #1a1a2e !important; } /* Restore images, videos, iframes, canvas */ img, video, iframe, canvas, svg, picture, [style*="background-image"] { filter: invert(1) hue-rotate(180deg) !important; } /* Preserve specific elements that should not be inverted */ .no-dark-mode, .no-dark-mode *, [data-theme="light"], [data-theme="light"], .ace_editor, .ace_editor *, .CodeMirror, .CodeMirror *, .monaco-editor, .monaco-editor *, .markdown-body pre, .markdown-body pre *, .highlight, .highlight *, pre code, pre code * { filter: none !important; } /* Fix common UI elements */ .modal, .popup, .dropdown-menu, .tooltip, .popover { filter: invert(1) hue-rotate(180deg) !important; background: #2d2d44 !important; border-color: #444 !important; } /* Scrollbars */ ::-webkit-scrollbar { background: #1a1a2e !important; } ::-webkit-scrollbar-thumb { background: #444 !important; } ::-webkit-scrollbar-thumb:hover { background: #555 !important; } /* Selection */ ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; } ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; } '; } function removeDarkMode() { var style = document.getElementById('universal-dark-mode-style'); if (style) style.remove(); } // Toggle with Alt+Shift+D document.addEventListener('keydown', function(e) { if (e.altKey && e.shiftKey && e.key === 'D') { e.preventDefault(); enabled = !enabled; if (enabled) { applyDarkMode(); console.log('[Universal Dark Mode] Enabled'); } else { removeDarkMode(); console.log('[Universal Dark Mode] Disabled'); } } }); // Apply on load applyDarkMode(); // Re-apply on dynamic content var observer = new MutationObserver(function(mutations) { if (enabled && !document.getElementById('universal-dark-mode-style')) { applyDarkMode(); } }); observer.observe(document.head, { childList: true }); console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle'); })(); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })(); Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] by renovate[bot] · Pull Request #156 · sky0621/cv-admin · GitHub
Skip to content

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - #156

Open
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability
Open

Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]#156
renovate[bot] wants to merge 1 commit into
mainfrom
renovate/go-github.com-labstack-echo-v4-vulnerability

Conversation

@renovate

@renovaterenovateBot commented Aug 25, 2026

Copy link
Copy Markdown
Contributor

This PR contains the following updates:

PackageChangeAgeConfidence
github.com/labstack/echo/v4v4.13.3v4.15.3ageconfidence

Warning

Some dependencies could not be looked up. Check the Dependency Dashboard for more information.


Echo: Encoded slash (%2F) bypasses route-level protection and exposes static files

CVE-2026-55677 / GHSA-vfp3-v2gw-7wfq

More information

Details

Summary

Echo's router and static file handler disagree on URL path decoding. The router matches routes using the raw encoded path (preserving %2F as-is), while StaticDirectoryHandler unescapes %2F to / before resolving filesystem paths. This allows an attacker to bypass route-level access controls and read static files without authorization.

Details

Root cause 1 — router.go lines 798-802:
The router uses req.URL.RawPath for route matching when useEscapedPathForRouting is false (the default). This means /admin%2Fsecret.txt is treated as a single path segment and does NOT match the /admin/* route pattern.

if!r.useEscapedPathForRouting&&req.URL.RawPath!="" {
path=req.URL.RawPath
}

Root cause 2 — echo.go lines 559-568:
StaticDirectoryHandler calls url.PathUnescape() on the path parameter before opening files. This converts %2F back to /, resolving admin/secret.txt on disk.

if!disablePathUnescaping {
tmpPath, err:=url.PathUnescape(p)
p=tmpPath
}
name:=filepath.ToSlash(filepath.Clean(strings.TrimPrefix(p, "/")))
PoC (Screenshot)

Sample:
image

403:
image

Bypass with encoded slash:
image

Impact

Unauthorized static file disclosure. Applications that protect route prefixes with authentication middleware while also serving static files from a broader root are vulnerable. An attacker only needs to encode the slash (/%2F) in the URL to bypass all route-level protection.

Common affected pattern:

adminGroup:=e.Group("/admin", authMiddleware)
e.StaticFS("/", os.DirFS("public"))

Severity

  • CVSS Score: 7.5 / 10 (High)
  • Vector String: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:N/A:N

References

This data is provided by the GitHub Advisory Database (CC-BY 4.0).


Release Notes

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

v4.15.3: - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Compare Source

Security

  • fix(static): reject encoded path separators that bypass route-level middleware by @​vishr in #​3011

Fixes GHSA-vfp3-v2gw-7wfq: an encoded path separator (%2F or %5C) in a static file URL could bypass route-level middleware (e.g. authentication on a sibling route) and disclose static files. Both StaticDirectoryHandler (used by Static/StaticFS) and the Static middleware are affected. Backport of the v5 fix (#​3009, released in v5.2.0). Thanks to @​a-tt-om and @​oran-gugu for reporting.

Full Changelog: labstack/echo@v4.15.2...v4.15.3

v4.15.2: - Context.Scheme() header validation

Compare Source

Security

Thanks to @​shblue21 for reporting this issue.

Full Changelog: labstack/echo@v4.15.1...v4.15.2

v4.15.1

Compare Source

What's Changed

  • CSRF: support older token-based CSRF protection handler that want to render token into template by @​aldas in #​2905

Full Changelog: labstack/echo@v4.15.0...v4.15.1

v4.15.0

Compare Source

Security

NB: If your application relies on cross-origin or same-site (same subdomain) requests do not blindly push this version to production

The CSRF middleware now supports the Sec-Fetch-Site header as a modern, defense-in-depth approach to CSRF
protection
, implementing the OWASP-recommended Fetch Metadata API alongside the traditional token-based mechanism.

How it works:

Modern browsers automatically send the Sec-Fetch-Site header with all requests, indicating the relationship
between the request origin and the target. The middleware uses this to make security decisions:

  • same-origin or none: Requests are allowed (exact origin match or direct user navigation)
  • same-site: Falls back to token validation (e.g., subdomain to main domain)
  • cross-site: Blocked by default with 403 error for unsafe methods (POST, PUT, DELETE, PATCH)

For browsers that don't send this header (older browsers), the middleware seamlessly falls back to
traditional token-based CSRF protection.

New Configuration Options:

  • TrustedOrigins []string: Allowlist specific origins for cross-site requests (useful for OAuth callbacks, webhooks)
  • AllowSecFetchSiteFunc func(echo.Context) (bool, error): Custom logic for same-site/cross-site request validation

Example:

e.Use(middleware.CSRFWithConfig(middleware.CSRFConfig{
// Allow OAuth callbacks from trusted providerTrustedOrigins: []string{"https://oauth-provider.com"},
// Custom validation for same-site requestsAllowSecFetchSiteFunc: func(c echo.Context) (bool, error) {
// Your custom authorization logic herereturnvalidateCustomAuth(c), nil// return true, err // blocks request with error// return true, nil // allows CSRF request through// return false, nil // falls back to legacy token logic
},
}))

PR: #​2858

Type-Safe Generic Parameter Binding

  • Added generic functions for type-safe parameter extraction and context access by @​aldas in #​2856

    Echo now provides generic functions for extracting path, query, and form parameters with automatic type conversion,
    eliminating manual string parsing and type assertions.

    New Functions:

    • Path parameters: PathParam[T], PathParamOr[T]
    • Query parameters: QueryParam[T], QueryParamOr[T], QueryParams[T], QueryParamsOr[T]
    • Form values: FormParam[T], FormParamOr[T], FormParams[T], FormParamsOr[T]
    • Context store: ContextGet[T], ContextGetOr[T]

    Supported Types:
    Primitives (bool, string, int/uint variants, float32/float64), time.Duration, time.Time
    (with custom layouts and Unix timestamp support), and custom types implementing BindUnmarshaler,
    TextUnmarshaler, or JSONUnmarshaler.

    Example:

    // Before: Manual parsingidStr:=c.Param("id")
    id, err:=strconv.Atoi(idStr)
    // After: Type-safe with automatic parsingid, err:=echo.PathParam[int](c, "id")
    // With default valuespage, err:=echo.QueryParamOr[int](c, "page", 1)
    limit, err:=echo.QueryParamOr[int](c, "limit", 20)
    // Type-safe context access (no more panics from type assertions)user, err:=echo.ContextGet[*User](c, "user")

PR: #​2856

DEPRECATION NOTICE Timeout Middleware Deprecated - Use ContextTimeout Instead

The middleware.Timeout middleware has been deprecated due to fundamental architectural issues that cause
data races. Use middleware.ContextTimeout or middleware.ContextTimeoutWithConfig instead.

Why is this being deprecated?

The Timeout middleware manipulates response writers across goroutine boundaries, which causes data races that
cannot be reliably fixed without a complete architectural redesign. The middleware:

  • Swaps the response writer using http.TimeoutHandler
  • Must be the first middleware in the chain (fragile constraint)
  • Can cause races with other middleware (Logger, metrics, custom middleware)
  • Has been the source of multiple race condition fixes over the years

What should you use instead?

The ContextTimeout middleware (available since v4.12.0) provides timeout functionality using Go's standard
context mechanism. It is:

  • Race-free by design
  • Can be placed anywhere in the middleware chain
  • Simpler and more maintainable
  • Compatible with all other middleware

Migration Guide:

// Before (deprecated):e.Use(middleware.Timeout())
// After (recommended):e.Use(middleware.ContextTimeout(30*time.Second))

Important Behavioral Differences:

  1. Handler cooperation required: With ContextTimeout, your handlers must check context.Done() for cooperative
    cancellation. The old Timeout middleware would send a 503 response regardless of handler cooperation, but had
    data race issues.

  2. Error handling: ContextTimeout returns errors through the standard error handling flow. Handlers that receive
    context.DeadlineExceeded should handle it appropriately:

e.GET("/long-task", func(c echo.Context) error {
ctx:=c.Request().Context()
// Example: database query with contextresult, err:=db.QueryContext(ctx, "SELECT * FROM large_table")
iferr!=nil {
iferrors.Is(err, context.DeadlineExceeded) {
// Handle timeoutreturnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
returnerr
}
returnc.JSON(http.StatusOK, result)
})
  1. Background tasks: For long-running background tasks, use goroutines with context:
e.GET("/async-task", func(c echo.Context) error {
ctx:=c.Request().Context()
resultCh:=make(chanResult, 1)
errCh:=make(chanerror, 1)
gofunc() {
result, err:=performLongTask(ctx)
iferr!=nil {
errCh<-errreturn
}
resultCh<-result
}()
select {
caseresult:=<-resultCh:
returnc.JSON(http.StatusOK, result)
caseerr:=<-errCh:
returnerrcase<-ctx.Done():
returnecho.NewHTTPError(http.StatusServiceUnavailable, "Request timeout")
}
})

Enhancements

v4.14.0

Compare Source

middleware.Logger has been deprecated. For request logging, use middleware.RequestLogger or
middleware.RequestLoggerWithConfig.

middleware.RequestLogger replaces middleware.Logger, offering comparable configuration while relying on the
Go standard library’s new slog logger.

The previous default output format was JSON. The new default follows the standard slog logger settings.
To continue emitting request logs in JSON, configure slog accordingly:

slog.SetDefault(slog.New(slog.NewJSONHandler(os.Stdout, nil)))
e.Use(middleware.RequestLogger())

Security

Enhancements

v4.13.4

Compare Source

Enhancements

Security


Configuration

📅 Schedule: (in timezone Asia/Tokyo)

  • Branch creation
    • At any time (no schedule defined)
  • Automerge
    • At any time (no schedule defined)

🚦 Automerge: Disabled by config. Please merge this manually once you are satisfied.

Rebasing: Whenever PR becomes conflicted, or you tick the rebase/retry checkbox.

🔕 Ignore: Close this PR and you won't be reminded about this update again.


  • If you want to rebase/retry this PR, check this box

This PR was generated by Mend Renovate. View the repository job log.

@renovate

renovateBot commented Aug 25, 2026

Copy link
Copy Markdown
ContributorAuthor

ℹ️ Artifact update notice

File name: go.mod

In order to perform the update(s) described in the table above, Renovate ran the go get command, which resulted in the following additional change(s):

  • 12 additional dependencies were updated
  • The go directive was updated for compatibility reasons

Details:

PackageChange
go1.24.2 -> 1.25.0
github.com/stretchr/testifyv1.10.0 -> v1.11.1
github.com/labstack/gommonv0.4.2 -> v0.5.0
github.com/mattn/go-colorablev0.1.13 -> v0.1.14
github.com/mattn/go-isattyv0.0.20 -> v0.0.22
golang.org/x/cryptov0.36.0 -> v0.50.0
golang.org/x/modv0.24.0 -> v0.34.0
golang.org/x/netv0.37.0 -> v0.53.0
golang.org/x/syncv0.13.0 -> v0.20.0
golang.org/x/sysv0.31.0 -> v0.43.0
golang.org/x/textv0.23.0 -> v0.36.0
golang.org/x/timev0.8.0 -> v0.15.0
golang.org/x/toolsv0.31.0 -> v0.43.0

@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 28, 2026
@renovaterenovateBot closed this Aug 28, 2026
@renovate
renovateBot deleted the renovate/go-github.com-labstack-echo-v4-vulnerability branch August 28, 2026 21:59
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from cb18ce6 to d3d1ad1CompareAugust 29, 2026 03:05
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 29, 2026
@renovaterenovateBot closed this Aug 29, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 29, 2026
@renovaterenovateBot reopened this Aug 29, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch from cb18ce6 to f224246CompareAugust 29, 2026 22:40
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 30, 2026
@renovaterenovateBot reopened this Aug 30, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from f224246 to 25c1b10CompareAugust 30, 2026 04:49
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 30, 2026
@renovaterenovateBot closed this Aug 30, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 25c1b10 to 064deb3CompareAugust 31, 2026 01:41
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedAug 31, 2026
@renovaterenovateBot closed this Aug 31, 2026
@renovaterenovateBot changed the title Update module github.com/labstack/echo/v4 to v4.15.3 [SECURITY] - autoclosedUpdate module github.com/labstack/echo/v4 to v4.15.3 [SECURITY]Aug 31, 2026
@renovaterenovateBot reopened this Aug 31, 2026
@renovate
renovateBotforce-pushed the renovate/go-github.com-labstack-echo-v4-vulnerability branch 2 times, most recently from 064deb3 to d6a24f0CompareAugust 31, 2026 18:07
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

0 participants