存储过程中的准备好的语句是否安全,不受SQL注入的影响?

在MySQL中是一个在SQL注入安全的存储过程中的准备语句? 见下面的例子。 get_info存储过程传递一个表名(pTbl)和where子句(pWhere)。 p可以有多个AND(例如fld1 =“a”AND fld2 =“b”AND ...)。 这可能不是最好的办法,但我需要动态SQL。

CREATE PROCEDURE get_info(pTbl VARCHAR(10), pWhere TEXT)
BEGIN
    SET @uSQL = CONCAT('SELECT info FROM ',pTbl,' WHERE ',pWhere);
    PREPARE ps FROM @uSQL;
    EXECUTE ps;
END$$

我尝试使用MySQL查询浏览器调用像下面这样的存储过程,但只是收到了一个错误,说我的SQL中有一个语法错误。

CALL get_info('tbl','1=1;SELECT * FROM information_schema.TABLES;');

如果它有助于任何使用PDO从PHP调用存储过程,如下所示。 $ tbl是$ _SESSION变量,$ whr是$ _GET变量。

$s=$c->prepare("CALL get_info(?,?)");
$s->execute(array($tbl,$whr));

这个存储过程安全吗? 如果不是,我将如何注入它? 如果我从MySQL查询浏览器vs网页注入,它有什么不同吗? 谢谢...


任何时候你在一个语句中插入一个值都有注入的可能性。 该程序很脆弱。 在SQL过程和函数中注入的唯一一般限制是PREPARE在单个语句上工作。 在这种特定情况下,注入的文本在SELECTWHERE子句之后基本上限制了对子选择, UNION ,调用过程和函数(棘手但可能非常危险)的攻击以及转储到文件(如果get_info的定义者FILE权限)。

作为例子,请尝试:

CALL get_info('tbl','1=0 UNION SELECT CONCAT(user, "@", host, " ", password) FROM mysql.user;');

是的,这是安全的。 (编辑:不,不是)

关键是要知道什么时候分析了SQL文本并将其转换为语义树。 准备好的陈述恰恰是:准备好的陈述,只是等待论据。 它们存储在完全编译为内部执行计划的服务器中,缺少参数的“漏洞”。

这就是为什么你得到语法错误,你试图将整个WHERE部分设置为一个参数; 但它是一个完整的表达式树。 准备好的陈述只能有数据元素的“漏洞”,而不能用于语法文本。

传输参数的协议完全是二进制安全的,不管你在参数变量中有什么,它们都将作为二进制数据发送并仅用作数据,而不是作为SQL命令的一部分。

编辑 ooops! 我刚刚注意到你正在进行文本插值,只是不在PHP中,而是在SQL中。 这意味着您稍后使用外部数据构建S​​QL命令。

绝对不安全。


由于其中一个值来自用户,因此可能会使用某些形式的SQL注入; 虽然只有SELECT查询可以运行,但仍可以通过将1=1传递给页面来显示信息。 以这种方式显示的信息的实际用处可能很低,但它仍然可能发生。

链接地址: http://www.djcxy.com/p/93701.html

上一篇: Is a prepared statement inside a stored procedure safe from SQL injection?

下一篇: Reference: What is a perfect code sample using the MySQL extension?