Laminas Framework DB适配器会自动剥离诸如mysqli_real_escape_string之类的标签吗? 命名参数匿名参数

问题描述

我正在使用Laminas框架(以前称为ZEND框架),想知道DB Adapter是否在插入和选择语句/执行($ statement-> prepare()/ $ statement-> execute( )-> current())以避免SQL注入?

如果不是,使用LAMINAS DB Adapter时实现它的最佳方法是什么?包装函数可以获取干净的SQL语句?

之前,我使用的是包装函数,该函数使用mysqli_real_escape_string

清除了输入

解决方法

您需要提供一些示例代码才能更准确地回答这个问题,但是您在这里谈论的主题是参数化。如果正确使用 laminas-db,则不必调用 mysqli_real_escape_string 或类似方法来防止 SQL 注入。但是,如果写入数据库的任何数据最终被回显到浏览器,您仍然应该非常警惕任何潜在的跨站点脚本 (XSS) 问题。请参阅以下部分。

如何不做

如果你做这样的事情,laminas-db 不会为你参数化你的查询,你很容易受到 SQL 注入的影响:

// DO NOT DO THIS
$idToSelect = $_POST['id'];
$myQuery = "select * from myTable where id = $idToSelect";
$statement->prepare($myQuery);
$results = $statement->execute();

如何正确操作

就我个人而言,我使用 Laminas TableGatewayInterface 抽象,因为它通常使生活更轻松。如果您想在较低级别进行操作,这样的操作是一种更安全的方法;它将确保您不会意外地在代码中添加一大堆 SQL 注入漏洞

命名参数

$idToSelect = $_POST['id'];
$myQuery = "select * from myTable where id = :id";
$statement->prepare($myQuery);
$results = $statement->execute(['id' => $idToSelect]);

匿名参数

$idToSelect = $_POST['id'];
$myQuery = "select * from myTable where id = ?";
$statement->prepare($myQuery);
$results = $statement->execute([$idToSelect]);

如果您以类似的方式执行此操作,则不需要任何额外的包装函数或任何东西,底层组件会为您处理。您可以使用命名或匿名参数版本,但我个人更喜欢命名参数,因为我发现它有助于代码可读性并且通常更容易调试。

清理输入/转义输出

在清理输入时要非常小心。它不仅会导致错误的安全感,还会引入微妙且非常令人沮丧的行为,最终用户会将其视为错误。

以这个例子为例:有人试图以“Bob & Jane Smith”的名义注册一个网站,但是输入清理程序会发现 & 字符并将其删除。突然之间,鲍勃获得了一个他们从来不知道的中间名。
输入清理的最大问题之一是上下文。有些字符在一个给定的上下文中可能是不安全的,但在另一个上下文中是完全良性的。此外,如果您需要支持整个 unicode 字符集(我们通常应该支持,除非我们有很好的理由不支持),尝试清除数据中的控制字符,这些数据可能会通过几个不同的系统(html、javascript、 html、php、sql 等)由于处理多字节字符的方式而成为一个非常困难的问题。

对于 MySQL,参数化几乎可以解决所有这些问题,因此我们无需担心 "Little Bobby Tables" scenario

将所有这些都翻转过来并转义输出要容易得多。理论上,呈现输出数据的代码知道它的目标是哪个上下文,因此可以转义所述上下文的输出,用安全的替代方法替换控制字符。

例如,假设某人在虚构的社交网站上的个人简介中添加了以下内容:

My name is Bob,I like to write javascript
<script>window.postStatusUpdate("Bob is my hero ♥️");</script>

这需要以不同的方式进行转义,具体取决于要显示此数据的上下文。如果要在浏览器中显示,转义符需要用转义版本替换尖括号。如果它作为 JSON 输出输出,则需要将双引号转义为反斜杠等。

我很欣赏这是对一个看似简单的问题的一个相当有风的答案,但是这些事情当然应该在应用程序设计的早期考虑;它可以为您节省大量的时间和更多的挫败感。

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...