首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >存储过程如何防止SQL注入?

存储过程如何防止SQL注入?
EN

Security用户
提问于 2014-10-01 06:12:44
回答 3查看 42.3K关注 0票数 15

也许我对存储过程不太清楚。有人能解释一下存储过程如何用MySql的简单示例来防止SQL注入吗?

EN

回答 3

Security用户

发布于 2017-01-12 06:04:31

存储过程不受SQL注入的影响。如下文所述:

https://blogs.msdn.microsoft.com/brian_swan/2011/02/16/do-stored-procedures-protect-against-sql-injection/

只要可以在存储过程中创建动态SQL,就容易受到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/

代码语言:javascript
运行
复制
VULNERABLE STORED PROCEDURE USING EXEC STATEMENT.
CREATE PROCEDURE getDescription
   @vname VARCHAR(50)
AS
   EXEC('SELECT description FROM products WHERE name = '''+@vname+ '''')
RETURN

另一个例子是:

代码语言:javascript
运行
复制
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运行。

票数 4
EN

Security用户

发布于 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请求中直接获取参数,那么像这样的语句可能会产生这样的结果。

代码语言:javascript
运行
复制
var sqlString="SELECT * FROM myTable WHERE id=";
sqlString = sqlString+request.getParameter("id");
// database parse, compile and optimize
var result=database.doQuery(sqlString);

如果使用存储过程或准备好的语句。解析和编译过程都是在数据库中完成的。所有的解释都取决于你的程序代码。当您调用它时,数据库只将给定的参数插入到预编译的代码中,并且它现在是它的eccepted数据类型。

代码语言:javascript
运行
复制
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();

存储过程和准备好的语句在安全性上是相等的。

票数 3
EN

Security用户

发布于 2018-03-27 17:23:32

另一种思考它的方式,是明确和增加已经给出的答案。

代码语言:javascript
运行
复制
SELECT * FROM users WHERE username = 'blah' AND password = 'foo' OR 'x'='x'

如果没有准备好的语句,“foo”之后的OR将被视为代码

现在,从数据库的角度看,准备好的语句的密码尝试如下:

'foo' OR 'x'='x'

,即“foo”之后的OR (以及其他一切)被视为数据。

票数 0
EN
页面原文内容由Security提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://security.stackexchange.com/questions/68701

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档