php 关于 INT 的分页安全性
php pagination security regarding INT
我希望将页面上的分页更新为 PDO。但是,我想确保它 100% 没有任何 SQL 注入等
以下是我发现的分页脚本的内容,我认为它可以正常工作。然而,因为它将从 URL 中提取数据,所以我有点担心这条线:
if (isset($_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
我可以看到 isset 在那里检查变量是否为 NULL(我认为)但我看不到任何检查它是否不是数字。
我正在考虑更改为:
if (isset($_GET["page"])) { $page = (int)$_GET["page"]; } else { $page=1; };
因为我认为这将检查页面变量是否为数字。或者应该是:
if (isset((int)$_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
还是两者都使用 INT?我认为在旧的 mysql 中,您会使用 striptags 等,但不确定是否使用 PDO(仍在学习)。
这是上述改动前的完整代码。
<?php
include('connect.php');
if (isset($_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
$start_from = ($page-1) * 3;
$result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT $start_from, 3");
$result->execute();
for($i=0; $row = $result->fetch(); $i++){
?>
<tr class="record">
<td><?php echo $row['a']; ?></td>
<td><?php echo $row['b']; ?></td>
<td><?php echo $row['c']; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
<div id="pagination">
<?php
$result = $db->prepare("SELECT COUNT(id) FROM members");
$result->execute();
$row = $result->fetch();
$total_records = $row[0];
$total_pages = ceil($total_records / 3);
for ($i=1; $i<=$total_pages; $i++) {
echo "<a href='index.php?page=".$i."'";
if($page==$i)
{
echo "id=active";
}
echo ">";
echo "".$i."</a> ";
};
?>
Connect.php 包含
$db = new PDO('mysql:host='.$db_host.';dbname='.$db_database, $db_user, $db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
如有任何帮助或指导,我们将不胜感激。另外,如果您能发现其他安全方面的问题,请告诉我。
编辑:
添加行:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
到connect.php
还有其他安全提示吗?
使用参数化查询这将避免注入的可能性。要使用 PDO 做到这一点,您可以
- 将用户提供的值传递到数组中执行
- 放置一个问号作为占位符来代替用户数据
$result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT ?, 3");
$result->execute(array((int)$start_from));
你也可以绑定,http://php.net/manual/en/pdostatement.bindparam.php(基于doc和其他线程,我一般不绑定)。
$result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT :start, 3");
$result->bindParam(':start', (int)$start_from, PDO::PARAM_INT);
$result->execute();
这里有一个更长的线程,How can I prevent SQL injection in PHP?
还有 PHP 注释,http://php.net/manual/en/pdo.prepared-statements.php
对于更长的样本,如果您有多个值:
$result = $db->prepare("SELECT * FROM members where username = ? and email = ? ORDER BY id ASC LIMIT ?, 3");
$result->execute(array($_GET['name'], $_GET['email'], $start_from));
我希望将页面上的分页更新为 PDO。但是,我想确保它 100% 没有任何 SQL 注入等
以下是我发现的分页脚本的内容,我认为它可以正常工作。然而,因为它将从 URL 中提取数据,所以我有点担心这条线:
if (isset($_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
我可以看到 isset 在那里检查变量是否为 NULL(我认为)但我看不到任何检查它是否不是数字。
我正在考虑更改为:
if (isset($_GET["page"])) { $page = (int)$_GET["page"]; } else { $page=1; };
因为我认为这将检查页面变量是否为数字。或者应该是:
if (isset((int)$_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
还是两者都使用 INT?我认为在旧的 mysql 中,您会使用 striptags 等,但不确定是否使用 PDO(仍在学习)。
这是上述改动前的完整代码。
<?php
include('connect.php');
if (isset($_GET["page"])) { $page = $_GET["page"]; } else { $page=1; };
$start_from = ($page-1) * 3;
$result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT $start_from, 3");
$result->execute();
for($i=0; $row = $result->fetch(); $i++){
?>
<tr class="record">
<td><?php echo $row['a']; ?></td>
<td><?php echo $row['b']; ?></td>
<td><?php echo $row['c']; ?></td>
</tr>
<?php
}
?>
</tbody>
</table>
<div id="pagination">
<?php
$result = $db->prepare("SELECT COUNT(id) FROM members");
$result->execute();
$row = $result->fetch();
$total_records = $row[0];
$total_pages = ceil($total_records / 3);
for ($i=1; $i<=$total_pages; $i++) {
echo "<a href='index.php?page=".$i."'";
if($page==$i)
{
echo "id=active";
}
echo ">";
echo "".$i."</a> ";
};
?>
Connect.php 包含
$db = new PDO('mysql:host='.$db_host.';dbname='.$db_database, $db_user, $db_pass);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
如有任何帮助或指导,我们将不胜感激。另外,如果您能发现其他安全方面的问题,请告诉我。
编辑:
添加行:
$db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
到connect.php
还有其他安全提示吗?
使用参数化查询这将避免注入的可能性。要使用 PDO 做到这一点,您可以
- 将用户提供的值传递到数组中执行
- 放置一个问号作为占位符来代替用户数据
$result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT ?, 3");
$result->execute(array((int)$start_from));
你也可以绑定,http://php.net/manual/en/pdostatement.bindparam.php(基于doc和其他线程,我一般不绑定)。
$result = $db->prepare("SELECT * FROM members ORDER BY id ASC LIMIT :start, 3");
$result->bindParam(':start', (int)$start_from, PDO::PARAM_INT);
$result->execute();
这里有一个更长的线程,How can I prevent SQL injection in PHP?
还有 PHP 注释,http://php.net/manual/en/pdo.prepared-statements.php
对于更长的样本,如果您有多个值:
$result = $db->prepare("SELECT * FROM members where username = ? and email = ? ORDER BY id ASC LIMIT ?, 3");
$result->execute(array($_GET['name'], $_GET['email'], $start_from));