MST

星途 面试题库

面试题:Java Web应用中常见SQL注入漏洞在代码层面如何体现及预防

在Java Web开发中,阐述一下使用JDBC操作数据库时,SQL注入漏洞可能在哪些代码场景下出现,比如使用Statement和PreparedStatement的区别,以及如何正确使用PreparedStatement来有效预防SQL注入漏洞,请举例说明。
20.3万 热度难度
编程语言Java

知识考点

AI 面试

面试题答案

一键面试

SQL注入漏洞可能出现的代码场景

  1. 使用Statement时:Statement在执行SQL语句时,将用户输入的数据直接拼接到SQL语句字符串中。如果用户输入的数据包含恶意的SQL语句片段,就会导致SQL注入漏洞。例如:
String username = request.getParameter("username");
String password = request.getParameter("password");
String sql = "SELECT * FROM users WHERE username = '" + username + "' AND password = '" + password + "'";
Statement statement = connection.createStatement();
ResultSet resultSet = statement.executeQuery(sql);

这里如果usernamepassword的值被恶意构造(如username = "any' OR '1'='1"),整个SQL语句的逻辑就会被改变,可能导致非法数据访问。

Statement和PreparedStatement的区别

  1. SQL语句编译方式
    • Statement:每次执行SQL语句时,数据库都要重新编译SQL语句,性能较低。而且由于SQL语句是动态拼接的,无法预编译,容易导致SQL注入。
    • PreparedStatement:SQL语句在创建PreparedStatement对象时就被预编译并存储在数据库中。执行时,只需要传入参数,数据库直接使用预编译的语句,性能较高。并且参数和SQL语句分离,有效防止SQL注入。
  2. 安全性
    • Statement:由于直接拼接用户输入数据到SQL语句,对用户输入没有任何防护,极易受到SQL注入攻击。
    • PreparedStatement:通过占位符(?)来代替实际参数,数据库会将参数当作普通数据处理,而不是SQL语句的一部分,从而防止SQL注入。

正确使用PreparedStatement预防SQL注入漏洞示例

String username = request.getParameter("username");
String password = request.getParameter("password");
String sql = "SELECT * FROM users WHERE username =? AND password =?";
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setString(1, username);
preparedStatement.setString(2, password);
ResultSet resultSet = preparedStatement.executeQuery();

在上述示例中,使用?作为占位符,通过setString方法设置参数值,无论usernamepassword的值是什么,都不会改变SQL语句的结构,从而有效预防SQL注入漏洞。