【问题标题】:How to secure a Query inside of a GET param?如何保护 GET 参数中的查询?
【发布时间】:2018-04-10 18:17:57
【问题描述】:

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

网址是这样的:

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

生成以下 SQL 查询:

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

该表包含更多列,我需要非常不同的查询,因此我无法使用准备好的语句。

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

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

【问题讨论】:

  • 您应该有一组有限的 GET 参数city 等。然后根据传递的参数构建查询。绑定值。您还应该对您的 get 参数进行 URL 编码,以免丢失值。
  • @chris85 这是不可能的,因为该表包含大量列,所有这些列都需要针对不同的情况以不同的方式进行查询。
  • 你不能让用户将他们想要的任何东西传递给你的 SQL。
  • @DanielJanke - 你永远不应该允许用户传入 SQL,它不会对你很好。
  • 你怎么知道每个城市的名字?列应该是参数名称,值应该是被查询的值。对值使用占位符,对列使用白名单。

标签: php mysql security pdo get


【解决方案1】:

你基本上有3个选择

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

  2. 让它有点灵活,但有不同的方法。这将设置方法,但输入具有一定的灵活性。

  3. 让它超级灵活,因此它可以处理大多数查询。

这最后一个是非平凡的(意味着硬)编码明智,但一旦设置它可以处理你需要的大部分东西。更不用说它很“酷”,所以我将详细介绍它。

现在我要做的是使用 JSON,因为它会在结构方面为您提供更多的灵活性。您始终可以使用base64_encode() 或其他一些编码将其潜入$_GET 数组而不会出现url 字符问题,或者您可以使用$_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"

-注意-您可以将其他 $_GET 参数用于排序顺序、排序索引、表格、限制等。(如 ?sort_index=id&amp;sort_order=DESC&amp;query=AJGEDC

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

既然我解释了理论,你将不得不写一些东西(可能是一个递归函数)来将 JSON 编译成 SQL

基本规则是。

  • 组:一组表达式(expr)

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

  • expr:一组查询段

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

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

  • value:要比较的值。

安全需要注意的几点:

  • 永远不要将用户提供的字符串连接到您的 sql 中,而不先检查它们。如果你这样做,你就会向各种 Sql Injection 讨厌的东西敞开心扉。因此,从field 中获取它们的列名,并确保它们存在于查询所针对的表中,然后再使用它们。

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

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

  • 始终使用准备好的语句。因此,使用占位符和输入数组构建您的查询。然后准备并执行查询。比如SELECT ... WHERE id = :expr1..[':expr1' =&gt; 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'
        )
    )

此查询将查找具有id2,3 的记录或具有id5,6,7 的记录 一个cat 的“产品”。

你也可以简单地做:

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

使用这样的 SQL

SELECT 
    *
FROM
    table
WHERE
   id=2

因此,您可以看到,通过使用 JSON,我们可以获得所需的复杂性,而仅使用 URL 查询参数很难实现。相信我,这样的事情有时会需要增加复杂性,所以您不妨一开始就将其构建。

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

我以前构建过这样的东西,它们运行得很好,大多数时候它都是专门构建的,所以我没有任何东西没有我可以给你的一堆依赖项。而且我现在没有时间为你写完整的东西,因为我必须改变这个灯具......说来话长。

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-10-08
    • 2011-04-15
    • 2019-10-09
    • 1970-01-01
    • 2019-12-30
    • 2013-10-21
    相关资源
    最近更新 更多