2

我正在尝试在 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

即使它包含我的任何“可过滤”单词,它仍然会执行查询。任何帮助将不胜感激,或者如果有更好的做某事的方法,我会全力以赴。

4

1 回答 1

1

如果您有一个名为updated_ator的列settings怎么办?您不可能期望它按您的意愿工作。这种技术是网络上有这么多对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条件之类的模式。这取决于你想走多远。

于 2012-11-28T01:27:22.317 回答