路由参数必须显式校验类型和范围,echo不自动校验c.param("id"),传入"../etc/passwd"或"123abc"会被原样接收,导致路径遍历或sql注入;正确做法是在handler开头用strconv.atoi、filepath.clean、预定义枚举map等白名单方式校验,并在路由层兜底检查已注册路径。

路由参数必须显式校验类型和范围
Echo 不会自动校验 c.Param("id") 的内容是否合法,传入 "../etc/passwd" 或 "123abc" 会被原样接收。这直接导致路径遍历或数据库注入风险。
正确做法是:在 handler 开头立即做白名单或格式检查:
- 数字 ID 用
strconv.Atoi转换,失败则返回echo.NewHTTPError(http.StatusBadRequest) - 文件名类参数必须过滤
".."、"."、空字节,并用filepath.Clean规范化路径 - 枚举型参数(如
status)应查预定义 map:if _, ok := map[string]bool{"active": true, "inactive": true}[status]; !ok { ... }
动态路由路径不能直接拼进 os.Open 或 SQL 查询
常见错误是把未处理的 c.Param("filename") 直接塞进 os.Open(path.Join("uploads", filename)) ——攻击者构造 /video/../../.env 就能读取敏感文件。
安全写法分三步:
- 先用
strings.Contains(filename, "..") || strings.HasPrefix(filename, ".")拦截明显恶意字符 - 再用
filepath.Clean("uploads/" + filename)得到规范路径 - 最后检查该路径是否仍在允许根目录下:
!strings.HasPrefix(cleanPath, "uploads"+string(filepath.Separator))
SQL 场景同理:绝不用 fmt.Sprintf("WHERE name = '%s'", c.Param("name")),而应走参数化查询或白名单映射。
开箱即用的技能链路由引擎。13 条预定义链覆盖搜索、开发、审查、MLOps、法律、创意等场景,三层路由架构(触发词→SAD反馈→DAG编排),recall@10=96.97%。配置驱动(chains.yaml),零代码扩展。pip install skill-weave-chains 一键安装。
公开路由必须用白名单机制兜底
哪怕用了中间件鉴权,也要防止未注册路由被意外暴露。Echo 默认 404 行为不阻止非法路径访问——比如你只注册了 /api/users,但没配 /api/admin/*,攻击者仍可能试探 /api/admin/config 看是否返回 200。
建议在所有中间件链末端加一个兜底检查:
- 维护一个全局
map[string]bool记录所有已注册的公开路径模式(如"/api/users"、"/health") - 在
e.Use()中插入中间件,对c.Request().URL.Path做前缀匹配或正则比对 - 不匹配且非静态资源路径(如
.js、.css)时,统一返回echo.NewHTTPError(http.StatusNotFound)
路由组权限必须和中间件绑定,不能靠注释或文档约定
开发者常把权限逻辑写在注释里:“这个 group 只给 admin 用”,但运行时无强制约束。一旦漏加中间件,整个分组就裸奔。
正确方式是路由组初始化即绑定:
- 用
adminGroup := e.Group("/admin", authMiddleware, roleCheckMiddleware("admin"))显式挂载 - 避免在 group 内部 handler 里重复调用
c.Get("user_role")判断——中间件已该干完的事 - 敏感操作(如删除、导出)额外加二次确认中间件,例如检查
c.Request().Header.Get("X-Confirm") == "true"
路径参数校验和白名单兜底是两道独立防线;前者防单点突破,后者防整体失控。漏掉任何一层,都可能让“看似安全”的路由变成攻击入口。










