如何在GET参数中保护查询?

时间:2017-10-29 18:43:48

标签: php mysql security pdo get

我需要在我的网站的GET参数中保护一个SQL查询,直接访问我的数据库。

网址就像:

   xxx.de/entryAPI.php?query=`city`='Berlin'&...

生成以下SQL查询:

SELECT * FROM `xyz` WHERE `city`='Berlin' LIMIT 0, 20

该表包含更多列,我需要非常不同的查询,因此我的预备语句是不可能的。

我有一组定义的查询应该是可能的,所以它会是 想要将可能的查询写入db并且必须使用此数据库验证get参数,该数据库包含所有可能的查询?然后,如果get参数中的查询也存储在数据库中,则URL调用仅生成SQL查询。

谢谢,我希望你理解我的问题!

1 个答案:

答案 0 :(得分:1)

你基本上有3个选择

  1. 创建搜索特定内容的单独方法。这将使用预定义的输入设置方法。

  2. 使其有些灵活,但有单独的方法。这将设置方法,但在输入中具有一些灵活性。

  3. 让它变得更加灵活,因此它可以处理大多数查询。

  4. 这最后一个是非平凡的(意思是硬的)编码方式,但一旦设置它就可以处理你需要的大部分内容。更不用说它"酷"所以我将详细介绍一下。

    现在我要做的就是使用JSON,因为它会给你更灵活的结构。您始终可以使用base64_encode()或其他一些编码将其隐藏到$_GET数组中而不会出现网址字符问题,或者您可以使用$_POST。但是你想把它送到服务器很酷我。

    我会使用像这样的架构

    query = {
        "groupOp":"AND",
        "expr":[],
        "group" : [{
               "groupOp":"OR",
               "expr":[{
                    "field":"id",
                    "op":"eq",
                    "value":"2"
                },{
                    "field":"id",
                    "op":"eq",
                    "value":"3"
                }],
                "group" : []
            },{
                "groupOp":"AND",
                   "expr":[{
                        "field":"created_date",
                        "op":"gte",
                        "value":"2017-10-01"
                    },{
                        "field":"created_date",
                        "op":"lte",
                        "value":"2017-10-31"
                     }],
                   "group" : []
            }],
        }
    

    大致可以解决的问题(如果提供了表格)

    SELECT
        *
    FROM
        tbl
    WHERE
        ( id = 2 OR id = 3 )
    AND
        (created_date >= "2017-10-01" AND created_date <= "2017-10-31" )
    

    现在只是指出这一点,groupOpgroup对于上述简单查询非常重要。将上述查询与此进行比较。

    SELECT
        *
    FROM
        tbl
    WHERE
        id = 2 OR id = 3
    AND
        created_date >= "2017-10-01" AND created_date <= "2017-10-31"
    

    -note-您可以使用其他$_GET参数来处理排序顺序,排序索引,表格,限制等。(例如?sort_index=id&sort_order=DESC&query=AJGEDC

    这些组表示( )的集合,没有它们,这第二个查询具有完全不同的含义。这是一个独占OR,因为我们需要将ID作为一组进行比较,然后比较日期范围。如果没有这个,我们可以在没有日期范围的情况下匹配id=2

    所以现在我解释了理论,你必须编写一些东西(可能是一个递归函数)来将JSON编译成SQL

    基本规则是。

    • group:一组表达式(expr)

    • groupOp:表达式如何在组内相互关联,以及嵌套组与这些表达式的关系

    • expr:一组查询段

    • 字段:要比较的列的名称

    • op:字段与数据的关系,例如: eq = equal,gte =大于或等于,gt =大于等......

    • value:要比较的值。

    安全性需要注意的几点:

    • 永远不要将用户提供的字符串连接到您的sql中,而不先检查它们。如果你这样做,你可以打开各种Sql Injection nastyness。因此,请从field中获取其列名,并确保它们在使用之前存在于查询表中。

    • 使用类似SHOW TABLES的内容从数据库中获取表格列表,然后将用户提供的表格与此列表进行比较。

    • 使用类似SHOW COLUMNS FROM table的内容来获取表架构,然后将用户提供的列与此列表进行比较。

    • 始终使用准备好的语句。因此,使用占位符和输入数组构建查询。然后准备并执行查询。例如SELECT ... WHERE id = :expr1..[':expr1' => 2]

    • 如果您允许排序和限制,同样的事情不适用于连接,任何事情。不要采取安全措施的捷径。

    嵌套组的另一个例子

    query = {
    "groupOp":"AND",
    "expr":[],
    "group" : [{
           "groupOp":"OR",
           "expr":[{
                "field":"id",
                "op":"eq",
                "value":"2"
            },{
                "field":"id",
                "op":"eq",
                "value":"3"
            }],
            "group" : [{
                "groupOp":"AND",
                "expr":[{
                    "field":"id",
                    "op":"in",
                    "value":[5,6,7]
                },{
                    "field":"cat",
                    "op":"eq",
                    "value":'product'
                }
            }]
        }],
    }
    

    这是SQL

    SELECT 
        *
    FROM
        table
    WHERE
        (
            id=2
                OR
            id=3 
                OR
            (
                id IN( 5,6,7 ) 
                    AND
                cat = 'product'
            )
        )
    

    此查询会查找id 2,3个OR记录id 5,6,7的{​​{1}}的记录&#34;产品&#34;

    您也可以这样做:

    cat

    使用这样的SQL

    {
        "expr":[{
                "field":"id",
                "op":"eq",
                "value":"2"
        }]
    }
    

    所以你可以通过使用JSON看到,我们可以拥有我们需要的复杂性,这很难用URL查询参数来实现。请相信我,这样的事情在某个时候需要增加复杂程度,所以你不妨开始构建它。

    即使增加了详细程度,您仍然可能需要多种方法来处理联接和多个表等事务。我不知道你确切的用例,所以也许你只需要一张桌子。但是,如果你在其中详细说明,它可能会变得非常混乱。这是一种平衡行为。

    我以前做过这样的事情并且工作得很好,大多数时候它的目的很好,所以我没有任何东西没有一堆依赖我可以给你。而且我现在没有时间为你写完整件事,因为我必须改变这个灯具......长篇故事。

    无论如何,希望那些想法有所帮助(好运!)