跳转到内容

CORS

CORS 中间件实现了 CORS 规范。 CORS 为 Web 服务器提供跨域访问控制,从而支持安全的跨域数据传输。

所有核心中间件都位于 middleware 包中:

import "github.com/labstack/echo/v5/middleware"
e.Use(middleware.CORS("https://example.com", "https://subdomain.example.com"))
e := echo.New()
e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"https://labstack.com", "https://labstack.net"},
AllowHeaders: []string{echo.HeaderOrigin, echo.HeaderContentType, echo.HeaderAccept},
}))

CORSConfig · github.com/labstack/echo/v5@5196b9b

字段说明由英文源码注释生成。

包源码中的字段
字段类型说明源码
Skipper Skipper Skipper defines a function to skip middleware. L19
AllowOrigins []string AllowOrigins determines the value of the Access-Control-Allow-Origin response header. This header defines a list of origins that may access the resource. Origin consist of following parts: `scheme + "://" + host + optional ":" + port` Wildcard can be used, but has to be set explicitly []string{"*"} Example: `https://example.com`, `http://example.com:8080`, `*` Security: use extreme caution when handling the origin, and carefully validate any logic. Remember that attackers may register hostile domain names. See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Origin Mandatory. L35
UnsafeAllowOriginFunc func(c *echo.Context, origin string) (allowedOrigin string, allowed bool, err error) UnsafeAllowOriginFunc is an optional custom function to validate the origin. It takes the origin as an argument and returns - string, allowed origin - bool, true if allowed or false otherwise. - error, if an error is returned, it is returned immediately by the handler. If this option is set, AllowOrigins is ignored. Security: use extreme caution when handling the origin, and carefully validate any logic. Remember that attackers may register hostile (sub)domain names. See https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html Sub-domain checks example: UnsafeAllowOriginFunc: func(c *echo.Context, origin string) (string, bool, error) { if strings.HasSuffix(origin, ".example.com") { return origin, true, nil } return "", false, nil }, Optional. L57
AllowMethods []string AllowMethods determines the value of the Access-Control-Allow-Methods response header. This header specified the list of methods allowed when accessing the resource. This is used in response to a preflight request. Optional. Default value DefaultCORSConfig.AllowMethods. If `allowMethods` is left empty, this middleware will fill for preflight request `Access-Control-Allow-Methods` header value from `Allow` header that echo.Router set into context. See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Methods L69
AllowHeaders []string AllowHeaders determines the value of the Access-Control-Allow-Headers response header. This header is used in response to a preflight request to indicate which HTTP headers can be used when making the actual request. Optional. Defaults to empty list. No domains allowed for CORS. See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Headers L78
AllowCredentials bool AllowCredentials determines the value of the Access-Control-Allow-Credentials response header. This header indicates whether or not the response to the request can be exposed when the credentials mode (Request.credentials) is true. When used as part of a response to a preflight request, this indicates whether or not the actual request can be made using credentials. See also [MDN: Access-Control-Allow-Credentials]. Optional. Default value false, in which case the header is not set. Security: avoid using `AllowCredentials = true` with `AllowOrigins = *`. See "Exploiting CORS misconfigurations for Bitcoins and bounties", https://blog.portswigger.net/2016/10/exploiting-cors-misconfigurations-for.html See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Allow-Credentials L95
ExposeHeaders []string ExposeHeaders determines the value of Access-Control-Expose-Headers, which defines a list of headers that clients are allowed to access. Optional. Default value []string{}, in which case the header is not set. See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Expose-Header L103
MaxAge int MaxAge determines the value of the Access-Control-Max-Age response header. This header indicates how long (in seconds) the results of a preflight request can be cached. The header is set only if MaxAge != 0, negative value sends "0" which instructs browsers not to cache that response. Optional. Default value 0 - meaning header is not sent. See also: https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Access-Control-Max-Age L113
包源码中的函数
类型源码
func CORS(allowOrigins ...string) echo.MiddlewareFunc L137
func CORSWithConfig(config CORSConfig) echo.MiddlewareFunc L146
// Effective defaults applied when fields are left unset.
CORSConfig{
Skipper: DefaultSkipper,
AllowMethods: []string{http.MethodGet, http.MethodHead, http.MethodPut, http.MethodPatch, http.MethodPost, http.MethodDelete},
}

通配符 origin(AllowOrigins: []string{"*"})与 AllowCredentials: true 组合使用非常危险: 它会把任意请求的 Origin 原样反射到 Access-Control-Allow-Origin 中,使得任意网站上的页面 都能向你的 API 发起携带凭证的跨域请求(参见 Exploiting CORS misconfigurations)。

Echo 会拒绝这种组合,而不是构建不安全的中间件:CORS 和 CORSWithConfig 会 panic, CORSConfig.ToMiddleware() 会返回错误。要允许携带凭证的请求,请显式列出受信任的 origin:

e.Use(middleware.CORSWithConfig(middleware.CORSConfig{
AllowOrigins: []string{"https://example.com"},
AllowCredentials: true,
}))

需要动态 origin 验证时,请使用 UnsafeAllowOriginFunc 并仔细验证每个 origin—— 攻击者可能注册仿冒或恶意的(子)域名。