Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
106 changes: 106 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,111 @@
# Changelog

## v5.3.0 - 2026-07-12

**Logic changes**
PR [#2996](https://github.com/labstack/echo/pull/2996) revert back to `v4` behavior for a group registering implicit 404 handlers.

If you do not want this behavior, can do not want implicit 404 handlers for groups, use:
```go
e := echo.NewWithConfig(echo.Config{NoGroupAutoRegister404Routes: true})
g := e.Group("/api")
```

some other noteworthy echancements:
* Adds first-class support for the QUERY HTTP method [RFC 10008](https://www.rfc-editor.org/info/rfc10008/) in https://github.com/labstack/echo/pull/3038
```go
e.QUERY("/", func(c *Context) error {
return c.String(http.StatusTeapot, "OK")
})
```

* Router: automatically handle HEAD request by GET handlers in https://github.com/labtack/echo/pull/2949
```go
e := echo.NewWithConfig(echo.Config{
Router: echo.NewRouter(echo.RouterConfig{
AutoHandleHEAD: true,
}),
})
```

**Enhancements**

* perf(json): pooled-buffer JSON deserialize by @vishr in https://github.com/labstack/echo/pull/3023
* perf(router): cache-friendly static child lookup by @vishr in https://github.com/labstack/echo/pull/3024
* update golang.org/x deps to latest versions by @aldas in https://github.com/labstack/echo/pull/3034
* pin GitHub Actions to full commit SHAs and rework actions SHAs to own variables by @aldas in https://github.com/labstack/echo/pull/3035
* docs(csrf): fix godoc typo in Generator default (tp -> to) by @DucMinhNe in https://github.com/labstack/echo/pull/3026
* docs(cors): note reverse-proxy header duplication by @vishr in https://github.com/labstack/echo/pull/3027
* feat: add support for HTTP QUERY method by @thdxg in https://github.com/labstack/echo/pull/3038
* docs: fix typos in API_CHANGES_V5.md by @maxtaran2010 in https://github.com/labstack/echo/pull/3039
* Router: auto HEAD to GET by @aldas in https://github.com/labstack/echo/pull/2949
* Revert back to v4 behavior for group registering implicit 404 handler… by @aldas in https://github.com/labstack/echo/pull/2996


## v5.2.1 - 2026-06-15

**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:
```go
// 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.


------

* revert PR #3009 changes to just disabling path escaping by default in static methods/middleware by @aldas in https://github.com/labstack/echo/pull/3016

Closes [GHSA-vfp3-v2gw-7wfq](https://github.com/labstack/echo/security/advisories/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.txt` → `hello world.txt`), you must now opt in:

```go
// 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,
})
```


## v5.2.0 - 2026-06-14

**Security**
Expand Down
2 changes: 1 addition & 1 deletion version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,5 @@ package echo

const (
// Version of Echo
Version = "5.2.0"
Version = "5.3.0"
)
Loading