51mee - AI智能招聘平台Logo
模拟面试题目大全招聘中心会员专区

设计一个API安全防护系统,用于360安全产品的Web服务,防止SQL注入、XSS等攻击。请说明中间件设计(Gin中间件)、SQL注入防护(预编译语句)、XSS防护(HTML编码)、CSRF防护(token验证),并给出Golang实现示例。

360服务端开发工程师-Golang难度:中等

答案

1) 【一句话结论】通过Gin框架的中间件链,集成SQL注入(预编译+参数类型验证)、XSS(HTML编码+输入验证)、CSRF(token+会话绑定)防护,构建多层安全网关,有效抵御常见Web攻击。

2) 【原理/概念讲解】

  • Gin中间件:Gin的中间件是链式调用结构,每个中间件处理请求的特定阶段(预处理、安全检查、响应处理),通过gin.Context.Next()传递控制权,实现模块化安全逻辑。类比:工厂流水线,每个工序(中间件)负责检查不同环节,确保请求安全。
  • SQL注入防护(预编译语句):预编译语句将SQL语句的文本与参数分离,数据库引擎预先解析SQL结构,参数以占位符(如?)传递,防止恶意SQL拼接。同时,需对参数进行类型转换(如int类型)和范围验证(如用户ID是否为正整数),避免因类型错误导致数据库错误或注入风险。
  • XSS防护(HTML编码):将用户输入中的特殊字符(如<、>、&)转换为HTML实体(如&lt;、&gt;、&amp;),避免浏览器解析为脚本。补充输入正则验证(如限制输入为字母数字),并处理内联事件(如onclick),防止通过事件属性注入。
  • CSRF防护(token验证):在请求头或表单中添加随机token(如uuid),服务器端验证token是否与用户会话匹配。token需存入HttpOnly、Secure、SameSite的cookie,每次请求后更新token(如刷新cookie),防止token被窃取后重放攻击。

3) 【对比与适用场景】

防护类型定义原理特性使用场景注意点
SQL注入防止恶意SQL语句注入预编译语句+参数化防止SQL拼接,数据库解析参数数据库查询、更新等操作需数据库支持预编译(如MySQL、PostgreSQL),参数类型转换和范围验证
XSS防止跨站脚本攻击HTML字符转义+输入验证转义特殊字符,阻止脚本执行响应内容输出(HTML、JSON等)输入需验证,内联事件需额外处理
CSRF防止跨站请求伪造token验证+会话绑定验证请求来源合法性表单提交、API调用token唯一性,与用户会话绑定,请求后更新token

4) 【示例】(Gin中间件实现,改进后):

// 1. SQL注入防护中间件(含参数类型检查和错误处理)
func SQLInjectionMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        idStr := c.Query("id")
        id, err := strconv.Atoi(idStr)
        if err != nil || id <= 0 {
            c.JSON(http.StatusBadRequest, gin.H{"error": "无效的ID参数"})
            c.Abort()
            return
        }
        db, err := sql.Open("mysql", "user:password@/db")
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": "数据库连接失败"})
            return
        }
        defer db.Close()
        stmt, err := db.Prepare("SELECT * FROM users WHERE id=?")
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": "SQL准备失败"})
            return
        }
        defer stmt.Close()
        rows, err := stmt.Query(id)
        if err != nil {
            c.JSON(http.StatusInternalServerError, gin.H{"error": "查询失败"})
            return
        }
        c.Next()
    }
}

// 2. XSS防护中间件(含输入验证和内联事件处理)
func XSSMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        param := c.Query("param")
        if !regexp.MustCompile(`^[a-zA-Z0-9]+$`).MatchString(param) {
            c.JSON(http.StatusBadRequest, gin.H{"error": "输入包含非法字符"})
            c.Abort()
            return
        }
        if strings.Contains(param, "onclick=") {
            c.JSON(http.StatusBadRequest, gin.H{"error": "内联事件非法"})
            c.Abort()
            return
        }
        encodedParam := html.EscapeString(param)
        c.Set("xss_param", encodedParam)
        c.Next()
    }
}

// 3. CSRF防护中间件(token生成、存储和更新)
func CSRFMiddleware() gin.HandlerFunc {
    return func(c *gin.Context) {
        token := c.Request.Header.Get("X-CSRF-Token")
        if token == "" {
            newToken := uuid.New().String()
            cookie := &http.Cookie{
                Name:     "csrf_token",
                Value:    newToken,
                HttpOnly: true,
                Secure:   true,
                SameSite: http.SameSiteLaxMode,
            }
            c.SetCookie("csrf_token", newToken, 3600, "/", "", true, true)
            c.Set("csrf_token", newToken)
        } else {
            if !isValidCSRFToken(token, c) {
                c.AbortWithStatus(http.StatusForbidden)
                return
            }
            newToken := uuid.New().String()
            c.SetCookie("csrf_token", newToken, 3600, "/", "", true, true)
            c.Set("csrf_token", newToken)
        }
        c.Next()
    }
}

router.Use(SQLInjectionMiddleware(), XSSMiddleware(), CSRFMiddleware())

5) 【面试口播版答案】
“面试官您好,设计API安全防护系统,核心是通过Gin框架的中间件链,分层处理常见攻击。首先,SQL注入防护用预编译语句,将SQL文本与参数分离,同时检查参数类型(如int类型转换及范围验证),避免恶意输入导致数据库错误;XSS防护用HTML编码转义用户输入的特殊字符,并补充输入正则验证,防止内联事件(如onclick)绕过;CSRF防护通过随机生成token(如uuid),存入HttpOnly、Secure的cookie,每次请求后更新token,确保请求来自合法会话。具体实现上,用Gin中间件封装这些逻辑,比如SQL注入中间件处理数据库查询,XSS中间件处理响应输出,CSRF中间件检查请求头token,中间件顺序为CSRF(先验证请求合法性)→XSS(处理响应)→SQL注入(处理数据库操作),层层递进,保障Web服务安全。”

6) 【追问清单】

  • 问题1:如何处理动态SQL拼接?
    回答要点:动态SQL拼接仍可能被绕过,需结合参数化查询,或对输入进行白名单验证(如参数类型白名单),确保参数类型正确,避免恶意SQL结构拼接。
  • 问题2:CSRF token如何防止重放攻击?
    回答要点:token需随机生成且与用户会话绑定,每次请求后更新token(如刷新cookie),避免被窃取后重放,同时设置HttpOnly、Secure等属性,防止JavaScript获取。
  • 问题3:中间件顺序对安全有影响吗?
    回答要点:顺序可能影响处理逻辑,例如CSRF中间件应放在XSS之前,确保请求合法后再处理响应,避免非法请求触发XSS防护,导致错误响应。
  • 问题4:预编译语句是否支持复杂查询?
    回答要点:预编译语句支持复杂查询(如JOIN、子查询),但需注意参数绑定顺序,避免SQL结构被篡改,例如使用数据库驱动提供的参数绑定方法(如MySQL的?占位符)。
  • 问题5:XSS防护是否覆盖所有场景?
    回答要点:HTML编码主要处理输出,输入仍需验证(如正则过滤),且需考虑内联事件(如onclick),可能需要额外处理(如过滤事件属性),避免通过事件注入。

7) 【常见坑/雷区】

  • 预编译语句仅防SQL注入,动态SQL拼接仍可能被绕过:需确保所有数据库操作都使用预编译,避免手动拼接SQL,否则可能被绕过。
  • XSS编码只处理输出,输入仍需验证:若输入未验证,恶意字符可能绕过编码,导致攻击,例如用户输入<script>alert(1)</script>,编码后为&lt;script&gt;alert(1)&lt;/script&gt;,但输入时已过滤。
  • CSRF token存储位置不当:若token存于cookie,需设置HttpOnly、Secure等属性,防止JavaScript获取,否则可能被跨站脚本攻击窃取。
  • 中间件顺序错误:例如CSRF中间件放在XSS之后,可能导致非法请求先被XSS处理,引发错误响应,影响用户体验。
  • 数据库驱动支持问题:部分驱动预编译支持有限,需选择支持良好的数据库(如MySQL的mysql驱动),否则可能无法正确处理参数化查询。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1