labstack/echo
 Watch   
 Star   
 Fork   
14 days ago
echo

v4.15.4

Security

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 (#3016, released in v5.2.1). Thanks to @a-tt-om and @oran-gugu for reporting.


Make serving static file releated methods and middleware not unescape path by default - so how the way Router interprets paths and Static methods/middleware is consistent.

Given following situation:

// 0.
// given folder structure:
// private.txt
// public/
// public/index.html
// public/text.txt
// public/admin/private.txt

// 1. share `public/` folder contents from the server root. This folder actually contains subfolder `admin` which
// contents we want to forbid from downloading
e.Static("/", "public")

// 2. naively assume that everything under /admin folder is now forbidden
e.GET("/admin/*", func(c *Context) error {
    return ErrForbidden
})

Then requests to /admin%2fprivate.txt would not be matched to GET /admin/* route (routing does not look unescaped path) and static file serving will use unescaped path to serve the file.

Note: this way of "guarding" subfolders will never work for for paths like /assets/../admin%2fprivate.txt which will path.Clean("/assets/../admin%2fprivate.txt") to /admin/private.txt and are servable if static file serving is configured to unescape paths.

If you want to guard routes - use middlewares on Static* methods and before Static middleware.

Breaking change / migration: If you serve files whose names contain URL-encoded characters (e.g., /hello%20world.txthello world.txt), you must now opt in:

	e := echo.New()
	e.EnablePathUnescapingStaticFiles = true  // <-- enable old behavior
	e.Static("/", "public")

for static middleware

	e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
		EnablePathUnescaping: true, // <-- enable old behavior
	}))

Full Changelog: https://github.com/labstack/echo/compare/v4.15.3...v4.15.4

14 days ago
echo

v5.2.1

Security

Make serving static file releated methods and middleware not unescape path by default - so how the way Router interprets paths and Static methods/middleware is consistent.

Given following situation:

// 0.
// given folder structure:
// private.txt
// public/
// public/index.html
// public/text.txt
// public/admin/private.txt

// 1. share `public/` folder contents from the server root. This folder actually contains subfolder `admin` which
// contents we want to forbid from downloading
e.Static("/", "public")

// 2. naively assume that everything under /admin folder is now forbidden
e.GET("/admin/*", func(c *Context) error {
    return ErrForbidden
})

Then requests to /admin%2fprivate.txt would not be matched to GET /admin/* route (routing does not look unescaped path) and static file serving will use unescaped path to serve the file.

Note: this way of "guarding" subfolders will never work for for paths like /assets/../admin%2fprivate.txt which will path.Clean("/assets/../admin%2fprivate.txt") to /admin/private.txt and are servable if static file serving is configured to unescape paths.

If you want to guard routes - use middlewares on Static* methods and before Static middleware.


Closes GHSA-vfp3-v2gw-7wfq more completely: the previous fix (#3009) rejected explicitly encoded separators at the handler level; this patch makes the no-unescape behavior the default so new configurations are safe without extra opt-out steps.

What changed: DisablePathUnescaping (on StaticConfig and StaticDirectoryHandlerConfig) is deprecated and replaced by EnablePathUnescaping (default false). Path unescaping is now opt-in.

What this protects: With EnablePathUnescaping: false (new default), encoded separators (%2F, %5C) are never decoded before routing or file lookup, so they cannot bypass route-level authentication or other middleware guards.

What this does NOT protect: Serving a directory with Static, StaticFS, or StaticDirectoryHandler exposes its entire subtree. Sibling routes are not a reliable ACL boundary — attach authorization middleware directly to the static mount, or serve sensitive sub-trees under separate guarded routes.

Breaking change / migration: If you serve files whose names contain URL-encoded characters (e.g., /hello%20world.txthello world.txt), you must now opt in:

// Static middleware
e.Use(middleware.StaticWithConfig(middleware.StaticConfig{
    EnablePathUnescaping: true, // only safe when NOT relying on route-based ACL guards
    ...
}))

// StaticDirectoryHandler
middleware.StaticDirectoryHandler(fs, &middleware.StaticDirectoryHandlerConfig{
    EnablePathUnescaping: true,
})

Full Changelog: https://github.com/labstack/echo/compare/v5.2.0...v5.2.1

15 days ago
echo

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

Security

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: https://github.com/labstack/echo/compare/v4.15.2...v4.15.3

15 days ago
echo

v5.2.0 - Static encoded-separator route bypass fix (GHSA-vfp3-v2gw-7wfq)

Security

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/StaticFS and the Static middleware are affected. Thanks to @a-tt-om and @oran-gugu for reporting.

Enhancements

New Contributors

Full Changelog: https://github.com/labstack/echo/compare/v5.1.1...v5.2.0

2026-05-02 03:14:30
echo

v5.1.1 - Context.Scheme() should validate header values

Security

Thanks to @shblue21 for reporting this issue - Context.Scheme accepts malformed forwarded scheme values used by host redirects.

Enhancements

New Contributors

Full Changelog: https://github.com/labstack/echo/compare/v5.1.0...v5.1.1

2026-05-02 01:59:02
echo

v4.15.2 - Context.Scheme() header validation

Security

Thanks to @shblue21 for reporting this issue.

Full Changelog: https://github.com/labstack/echo/compare/v4.15.1...v4.15.2

2026-04-01 04:52:35
echo

v5.1.0

Security

This change does not break the API contract, but it does introduce breaking changes in logic/behavior. If your application is using c.RealIP() beware and read https://echo.labstack.com/docs/ip-address

In v5 the c.RealIP() will now return request.RemoteAddr unless e.IPExtractor has been configured. No potentially spoofable headers are used by default anymore.

Configure IPExtractor with proper trust options when you want to read IP from headers. See:

v4 behavior can be restored with:

e := echo.New()
e.IPExtractor = echo.LegacyIPExtractor()

Related PR: Remove legacy IP extraction logic from context.RealIP method by @aldas in https://github.com/labstack/echo/pull/2933

What's Changed

New Contributors

Full Changelog: https://github.com/labstack/echo/compare/v5.0.4...v5.1.0

2026-02-22 19:50:50
echo

v4.15.1

What's Changed

Full Changelog: https://github.com/labstack/echo/compare/v4.15.0...v4.15.1

2026-02-15 23:48:33
echo

v5.0.4 small fixes and improvements

What's Changed

New Contributors

Full Changelog: https://github.com/labstack/echo/compare/v5.0.3...v5.0.4

2026-02-06 21:23:31
echo

v5.0.3 security (static middleware directory traversal under Windows)

Fix directory traversal vulnerability under Windows in Static middleware when default Echo filesystem is used. Reported by @shblue21 (https://github.com/labstack/echo/pull/2891).

This applies to cases when:

  • Windows is used as OS
  • middleware.StaticConfig.Filesystem is nil (default)
  • echo.Filesystem is has not been set explicitly (default)

Exposure is restricted to the active process working directory and its subfolders.

Full Changelog: https://github.com/labstack/echo/compare/v5.0.2...v5.0.3