go语言代码审计之hrms未授权漏洞分析
字数 837 2025-08-30 06:50:35
Go语言代码审计之HRMS未授权漏洞分析
漏洞概述
HRMS系统存在未授权获取用户信息漏洞,该漏洞是由于系统在数据库查询时权限验证存在缺陷,攻击者通过构造特定的cookies可以绕过权限验证,导致未经授权访问敏感信息。
漏洞影响范围
所有使用HrmsDB方法进行数据库查询的功能模块均受影响,包括但不限于:
- 账号密码查询
- 薪资查询
- 员工信息查询
- 部门信息查询
漏洞详细分析
1. 漏洞路由定位
漏洞存在于密码管理相关的查询路由:
passwordGroup.GET("/query/:staff_id", handler.PasswordQuery)
2. 核心漏洞函数分析
PasswordQuery函数
func PasswordQuery(c *gin.Context) {
var total int64 = 1
// 分页处理
start, limit := service.AcceptPage(c)
code := 2000
staffId := c.Param("staff_id")
var psws []model.PasswordQueryVO
result, err := buildPasswordQueryResult(c, staffId, start, limit)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{
"status": 5000,
"total": 0,
"msg": err,
})
return
}
// 总记录数
resource.HrmsDB(c).Where("staff_id != 'root' and staff_id != 'admin'").Model(&model.Staff{}).Count(&total)
psws = result
c.JSON(http.StatusOK, gin.H{
"status": code,
"total": total,
"msg": psws,
})
}
buildPasswordQueryResult函数
该方法是一个数据库查询方法,当staffId为"all"时,会通过用户验证后获取非管理员用户的账号及密码信息。
关键漏洞点 - HrmsDB函数
func HrmsDB(c *gin.Context) *gorm.DB {
cookie, err := c.Cookie("user_cookie")
if err != nil || cookie == "" {
c.HTML(http.StatusOK, "login.html", nil)
return nil
}
branchId := strings.Split(cookie, "_")[2]
dbName := fmt.Sprintf("hrms_%v", branchId)
if db, ok := DbMapper[dbName]; ok {
return db
}
c.HTML(http.StatusOK, "login.html", nil)
return nil
}
3. 漏洞成因
- 权限验证缺失:
HrmsDB函数仅验证了cookie中的数据库信息,没有进行用户身份验证 - 构造简单:攻击者只需构造一个由"_"分隔且第三个部分为数据库名称的
user_cookie即可绕过验证 - 影响广泛:所有使用
HrmsDB方法进行数据库查询的功能都受影响
漏洞验证方法
攻击步骤
-
构造特定的cookie格式:
a_b_C001或a_b_C002等- 其中第三个部分(
C001/C002)为目标数据库名称
- 其中第三个部分(
-
访问以下接口获取敏感信息:
- 账号密码查询
- 薪资查询
- 员工信息查询
- 部门信息查询
示例攻击请求
GET /password/query/all HTTP/1.1
Host: target.com
Cookie: user_cookie=a_b_C001
修复建议
-
完善身份验证:
func HrmsDB(c *gin.Context) *gorm.DB { // 验证用户是否登录 if !checkUserLogin(c) { c.HTML(http.StatusOK, "login.html", nil) return nil } cookie, err := c.Cookie("user_cookie") if err != nil || cookie == "" { c.HTML(http.StatusOK, "login.html", nil) return nil } // 验证cookie有效性 if !validateCookie(cookie) { c.HTML(http.StatusOK, "login.html", nil) return nil } branchId := strings.Split(cookie, "_")[2] dbName := fmt.Sprintf("hrms_%v", branchId) if db, ok := DbMapper[dbName]; ok { return db } c.HTML(http.StatusOK, "login.html", nil) return nil } -
增加权限检查:在每个敏感操作前验证用户权限
-
使用安全的会话管理:
- 使用加密的会话令牌
- 实现CSRF防护
- 设置合理的会话过期时间
-
最小权限原则:确保数据库用户仅具有必要的最小权限
总结
该漏洞展示了在Go Web应用中由于权限验证不完善可能导致的安全风险。开发人员应当:
- 对所有敏感操作实施严格的权限验证
- 避免仅依赖简单的字符串解析进行身份验证
- 遵循最小权限原则设计系统权限模型
- 对用户输入进行严格验证