如何在Golang(Gin+Gorm)中防止商品详情查询函数遭SQL注入?
防范Gin+Gorm商品查询接口的SQL注入风险
你的代码直接将URL参数id(字符串类型)传入Gorm的First方法,确实存在SQL注入风险——如果攻击者传入类似"1 OR 1=1"的字符串,Gorm会将其当作SQL片段执行,可能返回所有商品数据甚至引发更严重的问题。下面是具体的解决办法:
方法一:使用Gorm参数化查询语法
修改First方法的调用方式,明确用占位符绑定参数,Gorm会自动处理参数化,从根源避免SQL注入:
func Show(c *gin.Context) { var product models.Product id := c.Param("id") // 用占位符?绑定参数,Gorm自动做参数化处理 if err := models.DB.First(&product, "id = ?", id).Error; err != nil { switch err { case gorm.ErrRecordNotFound: c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"message": "Data not found"}) return default: c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": err.Error()}) return } } c.JSON(http.StatusOK, gin.H{"status": 200, "data": product}) }
方法二:先验证并转换ID类型
商品ID通常是整数类型,先将URL参数的字符串转换为整数,转换失败直接返回非法请求,既能过滤非法输入,也能让Gorm安全处理数字参数:
import "strconv" func Show(c *gin.Context) { var product models.Product idStr := c.Param("id") // 转换为整数(根据你的ID类型选择int/uint等) id, err := strconv.Atoi(idStr) if err != nil { c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": "Invalid product ID"}) return } // 传入整数类型参数,Gorm会自动参数化 if err := models.DB.First(&product, id).Error; err != nil { switch err { case gorm.ErrRecordNotFound: c.AbortWithStatusJSON(http.StatusNotFound, gin.H{"message": "Data not found"}) return default: c.AbortWithStatusJSON(http.StatusBadRequest, gin.H{"message": err.Error()}) return } } c.JSON(http.StatusOK, gin.H{"status": 200, "data": product}) }
关于仅靠参数验证能否防范SQL注入?
仅靠参数验证(比如验证ID是整数)可以过滤绝大多数注入尝试,但不建议只依赖参数验证:
- 如果后续ID类型变更(比如改为字符串ID),参数验证逻辑可能失效;
- 底层ORM的参数化查询是更可靠的防护手段,能从根源避免SQL注入。
建议同时使用「参数验证+ORM参数化查询」,形成双重防护。
内容的提问来源于stack exchange,提问作者ihsan karunia
相关产品推荐
相关产品推荐

