使用MySQL存储过程检查恶意代码

时间:2012-11-28 01:14:28

标签: mysql stored-procedures

我正在尝试在MySql中编写一个存储过程,它将接受一个参数,然后检查该参数是否包含“DROP”,“INSERT”,“UPDATE”,“TRUNCATE”等任何文本,几乎任何不是SELECT语句的东西。我知道它并不理想,但遗憾的是SELECT语句是在客户端构建的,并且为了防止某种中间人改变,它只是服务器增加的安全级别。

我尝试过几种方法来完成它,但是,它对我不起作用。我想出了类似的东西:

CREATE PROCEDURE `myDatabase`.`execQuery` (in INC_query text)
BEGIN

#check to see if the incoming SQL query contains INSERT, DROP, TRUNCATE, 
#or UPDATE as an added measure of security
IF (
    SELECT LOCATE(LOWER(INC_query),'drop') OR
    SELECT LOCATE(LOWER(INC_query),'truncate') OR
    SELECT LOCATE(LOWER(INC_query),'insert') OR
    SELECT LOCATE(LOWER(INC_query),'update') OR
    SELECT LOCATE(LOWER(INC_query),'set')
    >= 1) 
THEN
    SET @command = INC_query;
    PREPARE statement FROM @command;
    EXECUTE statement;
ELSE
    SELECT * FROM database.otherTable; #just a generic output to know the procedure executed correctly, and will be removed later. Purely testing.

END IF;

END

即使它包含我的任何“可过滤”单词,它仍会执行查询。任何帮助都会受到赞赏,或者如果有更好的办法,我会全力以赴。

1 个答案:

答案 0 :(得分:1)

如果您有一个名为updated_atsettings的列,该怎么办?你不可能期望这个按你的意愿工作。这种技术是网上clbuttic引用如此之多的原因。

如果你走这条路的话,你真的会弄得一团糟。

解决此问题的唯一合理方法是发送您要构建的查询类型的参数,然后使用经过审核的白名单允许的术语在您的应用程序中构建查询。用JSON表示的一个例子:

{
    "select" : {
      "table" : "users",
      "columns" : [ "id", "name", "DROP TABLE users", "SUM(date)", "password_hash" ],
      "joins" : {
         "orders" : [ "users.id", "orders.user_id" ]
      }
}

您只需创建一个发出此类事物的查询构造函数,另一个将其转换回有效查询。您可能只想列出要查询的特定列,因为某些列可能是秘密的,也可能只是内部的,不会被公开,例如本例中的password_hash

您还可以允许(SUM|MIN|MAX|AVG)\((\w+)\)等模式捕获特定的分组操作或JOIN条件。这取决于你想要走多远。