测试登录页面SQL注入时遇语法错误,求修复方案
解决SQL注入测试中的SQL语法错误(错误码42000/102)
我在测试登录页面的SQL注入机制时,编写了如下PHP代码:
public function login() { $db = new Database(); //---------------------------------------------------------------- -------------------------------- $p = $this->getPhone(); $pa = $this->getPassword(); //-------------------------------------------------------------------------------------------------------------------------------- // $sql = "SELECT * FROM dbo.Account WHERE phone = ? and password = ?"; //---------------------------------------------------------------------------------------------------- $sql = "SELECT * FROM dbo.Account WHERE phone = $p and password = $pa"; //---------------------------------------------------------------------------------------------------- // Use an array to pass parameters in the correct order // $params = array($this->phone, $this->password); // var_dump($sql); //---------------------------------------------------------------------------------------------------- // $result = $db->query($sql,$params); //-------------------------------------------------------------------------------------------------- $result = $db->query($sql); // var_dump($result); if ($result) { // Check if there is a matching user if ($result > 0) { return true; } else { // Incorrect phone or password return false; } } else { // Error in the query // You might want to log the error or handle it appropriately return false; } }
在XAMPP环境下运行该PHP代码时,出现如下错误:
Array ( [0] => Array ( [0] => 42000 [SQLSTATE] => 42000 [1] => 102 [code] => 102 [2] => [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '&'. [message] => [Microsoft][ODBC Driver 17 for SQL Server][SQL Server]Incorrect syntax near '&'. ) )
错误原因
直接将用户输入的$p和$pa拼接到SQL语句中,存在两个核心问题:
- 手机号、密码属于字符串类型,拼接时未加单引号,本身就会导致SQL语法错误;
- 当输入包含
&、单引号等特殊字符时,会直接破坏SQL语句结构,触发语法解析错误。
修复方案
方案1:使用参数化查询(推荐,同时避免SQL注入)
直接启用你代码中被注释的参数化逻辑,这是处理用户输入的标准安全做法,也能彻底解决语法问题:
public function login() { $db = new Database(); $p = $this->getPhone(); $pa = $this->getPassword(); // 使用参数化SQL语句 $sql = "SELECT * FROM dbo.Account WHERE phone = ? and password = ?"; // 准备参数数组 $params = array($p, $pa); // 调用带参数的查询方法 $result = $db->query($sql, $params); if ($result) { if ($result > 0) { return true; } else { return false; } } else { return false; } }
方案2:手动转义+补全引号(仅用于SQL注入测试,不推荐生产环境)
如果你只是为了测试SQL注入的危害,需要保留拼接写法,必须补全字符串引号并转义特殊字符:
public function login() { $db = new Database(); // 假设Database类包含SQL Server连接对象$conn,用sqlsrv_real_escape_string转义特殊字符 $p = sqlsrv_real_escape_string($db->conn, $this->getPhone()); $pa = sqlsrv_real_escape_string($db->conn, $this->getPassword()); // 给字符串变量加上单引号 $sql = "SELECT * FROM dbo.Account WHERE phone = '$p' and password = '$pa'"; $result = $db->query($sql); if ($result) { if ($result > 0) { return true; } else { return false; } } else { return false; } }
内容的提问来源于stack exchange,提问作者Khoi Minh
相关产品推荐
相关产品推荐

