我第一次尝试使用PDO,我只是想知道我所做的事情有多安全,我也是PHP的新手。
我有一个查询,当用户被传递到我的页面时,页面会使用GET获取一个变量,然后运行。
对于PHP,我一直使用mysql_real_eescape来清理我的变量。
有人能从中看出安全漏洞吗?
// Get USER ID of person
$userID = $_GET['userID'];
// Get persons
$sql = "SELECT * FROM persons WHERE id =$userID";
$q = $conn->query($sql) or die($conn->error());
while($r = $q->fetch(PDO::FETCH_LAZY)){
echo '<div class="mis-per">';
echo '<span class="date-submitted">' . $r['date_submitted'] . '</span>';
// MORE STUF
echo '</div>';
}
不使用查询,使用prepare:
http://php.net/manual/de/pdo.prepare.php
$userID = $_GET['userID'];
$sql = "SELECT * FROM persons WHERE id = :userid";
$q = $conn->prepare($sql)
$q->execute(array(':userid' => $userID ));
while($r = $q->fetch(PDO::FETCH_ASSOC)){
echo '<div class="mis-per">';
echo '<span class="date-submitted">' . $r['date_submitted'] . '</span>';
// MORE STUF
echo '</div>';
}
SQL语句可以包含零个或多个命名(:name)或问号(?)参数标记,在执行该语句时,这些标记的实值将被替换。
使用任何东西,都是关于如何使用它,而不是使用什么。我认为PDO本身是非常安全的,只要你正确使用它。
$sql = "SELECT * FROM persons WHERE id =$userID";
太糟糕了。更好:
$sql = "SELECT * FROM persons WHERE id = " . $conn->quote($userID);
更好:
$q = $conn->prepare('SELECT * FROM persons WHERE id = ?')->execute(array($userID));
*这很糟糕,因为如果$userID
是"1 OR 1"
,那么查询将变为SELECT * FROM persons WHERE id =1 OR 1
,它将始终返回persons
表中的所有值。
正如评论所说:Atm没有任何针对SQLI的安全性。PDO为您提供(如果数据库驱动程序支持(mysql支持)Prepared Statements。把它想象成一个查询模板,它被编译/传递给dbms,然后用值填充。这里有一个用法示例:
$sql = 'SELECT name, colour, calories
FROM fruit
WHERE calories < :calories AND colour = :colour';
//Prepare the Query
$sth = $dbh->prepare($sql);
//Execute the query with values (so no tainted things can happen)
$sth->execute(array(':calories' => 150, ':colour' => 'red'));
$red = $sth->fetchAll();
如下调整(可以使用:userId
,也可以像Tom van der Woerdt建议的那样简单地使用?
,即使我认为第一个参数更清晰,尤其是当不止一个参数时):
$sql = "SELECT * FROM persons WHERE id =:userID";
$q = $conn->prepare( $sql );
$q->bindValue( ":userID", $userID, PDO::PARAM_INT ); // or PDO::PARAM_STR, it depends
$q->execute();
$r = $st->fetch();
...
...