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

在360安全卫士的企业版中,用户数据(如设备信息、威胁情报)存储在数据库中。请说明如何防止SQL注入攻击,并设计一个具体的代码示例(使用Java或Python)展示参数化查询的正确实现方式,以及错误实现(使用字符串拼接)的漏洞点。

360安全开发初级工程师难度:中等

答案

1) 【一句话结论】防止SQL注入的核心是使用参数化查询(预编译语句),通过将SQL语句与用户输入参数分离,避免恶意输入被解释为SQL代码,从而阻断注入攻击。

2) 【原理/概念讲解】SQL注入是指攻击者通过在输入字段插入恶意SQL代码,绕过验证逻辑执行非预期数据库操作。例如,用户输入' OR 1=1 --会改变查询逻辑(如原本SELECT * FROM users WHERE username = 'admin'变成SELECT * FROM users WHERE username = '' OR 1=1 --,导致所有用户被查询)。参数化查询(如Java的PreparedStatement、Python的psycopg2等)将SQL语句的参数用占位符(如?)表示,由数据库引擎处理参数,用户输入仅作为参数传递,不会参与SQL解析,从而防止注入。类比:填空题中,用户填答案(参数),而非修改题目(SQL语句),题目(SQL结构)与答案(参数)分离,避免答案影响题目逻辑。

3) 【对比与适用场景】

方式定义特性使用场景注意点
字符串拼接将SQL语句与用户输入直接拼接成字符串SQL语句与参数混合,用户输入可能被解释为SQL代码简单查询,开发时未考虑安全容易被注入,需手动转义,复杂查询易出错
参数化查询将SQL语句的参数用占位符表示,参数单独传递SQL语句与参数分离,参数由数据库处理所有需要用户输入的查询(尤其是动态查询)需预编译,可能存在参数类型匹配问题

4) 【示例】(以Java为例):

  • 错误实现(字符串拼接):
    String sql = "SELECT * FROM users WHERE username = '" + username + "'";
    // 若username为"admin' OR '1'='1",实际执行:SELECT * FROM users WHERE username = 'admin' OR '1'='1'(导致注入)
    
  • 正确实现(参数化查询):
    String sql = "SELECT * FROM users WHERE username = ?";
    PreparedStatement pstmt = connection.prepareStatement(sql);
    pstmt.setString(1, username); // 参数1对应第一个?,用户输入作为参数传递
    ResultSet rs = pstmt.executeQuery();
    

5) 【面试口播版答案】
“面试官您好,关于防止SQL注入,核心是使用参数化查询(预编译语句)。SQL注入的原理是攻击者通过输入恶意SQL代码绕过验证,比如输入' OR 1=1 --会改变查询逻辑。参数化查询通过将SQL语句和参数分离,用占位符(如?),由数据库处理参数,用户输入仅作为参数传递,不会参与SQL解析,从而阻断注入。比如错误实现用字符串拼接,会把用户输入直接拼入SQL,导致注入;正确实现用PreparedStatement,把用户输入作为参数,数据库只处理参数,不会执行恶意SQL。比如Java中,错误写法是SELECT * FROM users WHERE username = '" + username + "',这样输入admin' OR '1'='1就会导致注入;正确写法是SELECT * FROM users WHERE username = ?,用pstmt.setString(1, username),无论输入什么,数据库都只按参数处理,不会执行恶意SQL。总结来说,参数化查询是防止SQL注入最有效的方法,因为它从根本上隔离了用户输入和SQL语句的执行逻辑。”

6) 【追问清单】

  • 问:如果查询中需要动态表名或列名,如何处理?
    回答要点:对于动态表名/列名,应先验证是否在允许列表中(白名单),或对输入进行正则匹配,避免直接拼接。例如,检查表名是否在预定义列表,确保输入符合规范。
  • 问:参数化查询的效率如何?是否比字符串拼接慢?
    回答要点:预编译语句第一次执行时编译SQL,后续复用结果,效率与字符串拼接相当,甚至更高,因为避免了重复解析SQL。
  • 问:除了参数化查询,还有其他防御措施吗?
    回答要点:输入验证(白名单/黑名单)、输出编码(防XSS结合注入)、数据库权限最小化(仅授予必要权限)等辅助措施。
  • 问:如何处理存储过程中的SQL注入?
    回答要点:存储过程同样需参数化,将输入参数作为参数传递,避免拼接用户输入的SQL代码。
  • 问:用户输入包含特殊字符(如单引号),参数化查询是否会处理?
    回答要点:参数化查询会自动转义特殊字符(如单引号转为'),无需手动转义,而字符串拼接需手动转义,易遗漏。

7) 【常见坑/雷区】

  • 坑1:认为手动转义(如替换单引号为'')能完全防止注入。
    雷区:手动转义易遗漏特殊场景(如多语句注入),且不同数据库转义规则不同,维护成本高。
  • 坑2:参数化查询中参数类型与输入不匹配(如字符串设为整数)。
    雷区:可能导致类型错误或SQL语法错误,虽不直接注入,但可能引发其他安全问题(如崩溃或信息泄露)。
  • 坑3:用字符串拼接处理动态SQL(如拼接表名/列名)。
    雷区:即使转义,动态拼接仍可能被绕过(如特殊输入导致转义失效)。
  • 坑4:预编译语句参数数量/位置错误(如pstmt.setString(1, input)中占位符数量不匹配)。
    雷区:导致SQL语法错误或参数未正确绑定,影响查询结果。
  • 坑5:认为参数化查询适用于所有SQL操作。
    雷区:复杂查询(如涉及动态SQL的存储过程)仍需谨慎处理,核心原则是参数与SQL结构分离。
51mee.com致力于为招聘者提供最新、最全的招聘信息。AI智能解析岗位要求,聚合全网优质机会。
产品招聘中心面经会员专区简历解析Resume API
联系我们南京浅度求索科技有限公司admin@51mee.com
联系客服
51mee客服微信二维码 - 扫码添加客服获取帮助
© 2025 南京浅度求索科技有限公司. All rights reserved.
公安备案图标苏公网安备32010602012192号苏ICP备2025178433号-1