也许我对存储过程不太清楚。有人能解释一下存储过程如何用MySql的简单示例来防止SQL注入吗?
发布于 2017-01-12 06:04:31
存储过程不受SQL注入的影响。如下文所述:
的攻击。
和MySQL从5.0.13开始,具有动态SQL功能:
https://stackoverflow.com/questions/190776/how-to-have-dynamic-sql-in-mysql-stored-procedure
因此容易受到SQL注入的影响。
在SQL server中,下面是一个示例:
http://www.sqlinjection.net/advanced/stored-procedure/
VULNERABLE STORED PROCEDURE USING EXEC STATEMENT.
CREATE PROCEDURE getDescription
@vname VARCHAR(50)
AS
EXEC('SELECT description FROM products WHERE name = '''+@vname+ '''')
RETURN
另一个例子是:
VULNERABLE STORED PROCEDURE USING DYNAMIC CURSOR.
CREATE PROCEDURE printDescriptions
@vname VARCHAR(100)
AS
DECLARE @vdesc VARCHAR(1000)
DECLARE @vsql VARCHAR(4000)
SET @vsql = 'SELECT description FROM products WHERE name='''+@vname+''''
DECLARE cur CURSOR FOR EXEC @vsql
OPEN cur
FETCH NEXT FROM cur INTO @vdesc
WHILE @@FETCH_STATUS = 0
BEGIN
PRINT @vdesc
FETCH NEXT FROM cur INTO @vdesc
END
CLOSE cur
DEALLOCATE cur
RETURN
在Oracle中,下面是一些例子:
http://software-security.sans.org/developer-how-to/fix-sql-injection-in-oracle-database-code
https://www.blackhat.com/presentations/bh-europe-04/bh-eu-04-litchfield.pdf
上述由Blackhat欧洲的David介绍的内容更严重,从SQL注入到权限提升--因此,如果存储过程是由DBA创建的(例如,所有Oracle系统对象),正常的Oracle用户可以作为DBA运行。
发布于 2014-10-01 07:40:18
SQL数据库分几个步骤工作一条语句。首先分析SQL语句的测试,然后对其进行优化和编译。完成此操作后,数据库现在有了一个可以运行给定SQL语句的内部软件。
预编译存储过程。换句话说,数据库在使用之前会创建内部软件。在这种情况下,只解释程序代码而不受任何参数的影响。
如果将包含SQL语句的完整参数传递给数据库,则该参数将处理上述步骤。
比如说..。
SELECT * FROM myTable WHERE id=1
或者你给了那样的东西..。
SELECT * FROM myTable WHERE id=1;DROP TABLE myTable
通常,没有人会在他的程序代码中编写第二条语句,但是如果您从web请求中直接获取参数,那么像这样的语句可能会产生这样的结果。
var sqlString="SELECT * FROM myTable WHERE id=";
sqlString = sqlString+request.getParameter("id");
// database parse, compile and optimize
var result=database.doQuery(sqlString);
如果使用存储过程或准备好的语句。解析和编译过程都是在数据库中完成的。所有的解释都取决于你的程序代码。当您调用它时,数据库只将给定的参数插入到预编译的代码中,并且它现在是它的eccepted数据类型。
var sqlString = "call queryMyTable(?)";
// get the precompiled statement from database
var statement = database.createStatement(sqlString);
// inject the parameter
statement.setParameter(1,request.getParameter("id"));
// if 'id' is a number it works fine ...
// but if 'id' is '1;DROP TABLE myTable' you will got a type cast error and the risk of SQL injection is banned
var result = statement.execute();
存储过程和准备好的语句在安全性上是相等的。
发布于 2018-03-27 17:23:32
另一种思考它的方式,是明确和增加已经给出的答案。
SELECT * FROM users WHERE username = 'blah' AND password = 'foo' OR 'x'='x'
如果没有准备好的语句,“foo”之后的OR
将被视为代码
现在,从数据库的角度看,准备好的语句的密码尝试如下:
'foo' OR 'x'='x'
,即“foo”之后的OR
(以及其他一切)被视为数据。
https://security.stackexchange.com/questions/68701
复制相似问题