Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/87.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
php代码在不使用escape的情况下是否可以安全地避免sql InjAction?_Php_Sql_Sql Injection - Fatal编程技术网

php代码在不使用escape的情况下是否可以安全地避免sql InjAction?

php代码在不使用escape的情况下是否可以安全地避免sql InjAction?,php,sql,sql-injection,Php,Sql,Sql Injection,显然,没有转义函数,因此可以插入as或'1'='1,以使WHERE子句为真,并且fetchUserData将返回表中的所有行。但是,verfiyLogin检查用户输入的密码和来自数据库的查询结果是否相同,所以身份验证将失败。攻击者也无法修改表,因为mysql\u db\u query只执行一条sql语句。我说得对吗?有什么想法吗 是的,非常有可能对根据用户输入构建的任何SQL查询执行SQL注入 您应该使用转义函数或优先准备的语句来保护自己不受SQL注入的影响。但是,如果您使用的是过时且不推荐使用

显然,没有转义函数,因此可以插入as
或'1'='1
,以使WHERE子句为真,并且
fetchUserData
将返回表中的所有行。但是,
verfiyLogin
检查用户输入的密码和来自数据库的查询结果是否相同,所以身份验证将失败。攻击者也无法修改表,因为
mysql\u db\u query
只执行一条sql语句。我说得对吗?有什么想法吗

是的,非常有可能对根据用户输入构建的任何SQL查询执行SQL注入

您应该使用转义函数或优先准备的语句来保护自己不受SQL注入的影响。但是,如果您使用的是过时且不推荐使用的mysql_*函数,则不能使用prepared语句。您需要切换到mysqli或PDO

PDO示例:

public function fetchUserData( $username, $noUpdate = false ) {
  if ( DEBUG ) echo "DBInterface::fetchUserData( '$username' )\n";
  $query = "SELECT * FROM logins WHERE username = '$username'";
  $result = mysql_db_query( $this->database, $query, $this->dbc );
  if ( $result && !$noUpdate ) {
        mysql_db_query( $this->database, "UPDATE logins SET last_accessed = CURRENT_TIMESTAMP WHERE username = '$username' ", $this->dbc );
  }
  return $this->userData = mysql_fetch_assoc( $result );
}


public function verifyLogin( $username = null, $password = null ) {
  if ( DEBUG ) echo "DBInterface::verifyLogin( '$username', '$password' )\n";
  $success = ( $username && $password
            && $this->fetchUserData( $username )
            && $this->userData['password'] == $this->md5_base64( $password  )
            && $this->setLoggedIn()
          );
  return $success;
}

数据验证经常与SQL格式混淆。你所说的“逃避”(不管你在这个模糊的术语下是什么意思)不属于“注入”,而仅仅属于格式。您需要转义字符串不是因为注入,而是因为字符串分隔符和其他一些原因


数据验证规则可能会更改。SQL格式规则是常量。您必须格式化放入SQL字符串中的任何数据。无论您在构造查询之前对这些数据做了什么,都无关紧要

您可以使用将自己的数据注入到结果集中。因此,攻击者可以提供自己的
$this->userData['password']
值,该值将等于
$this->md5_base64($password)
值,例如:

$myPDO = new PDO ('Connection options go here');
$stmt = $myPDO -> prepare ("SELECT * FROM table WHERE rowID = :rowID");
if ($stmt -> execute (array ('rowID' = $inputFromUntrustedSource))) {
    while ($row = $stmt -> fetch ()) {
        // do stuff with $row here
    }
}

因此,您应该绝对确保自己的安全。

即使在这种情况下不可能,为什么不使用适当的技术呢?阅读大红色警告:使用mysqli_*函数避免sql注入我只是想知道是否可以在这里进行sql注入。这是来自开放源代码的,显然已经过更新。正如您已经看到的,您可以更改查询,因为参数没有转义,并且已经是注入。即使孤立地看它可能不太方便,但与其他代码结合起来也可能是个问题。因此,每一个可以以这种方式修改的查询都应该作为安全问题来处理。@krishna虽然应该使用
mysqli
PDO
来代替不推荐的扩展,但它们不会阻止编写允许注入的代码。
' UNION SELECT 'admin', 'X03MO1qnZdYdgyfeuILPmQ==