【问题标题】:SQL injection and Postgres "CREATE SCHEMA"SQL 注入和 Postgres “CREATE SCHEMA”
【发布时间】:2011-05-11 13:00:32
【问题描述】:

在postgres中使用CREATE SCHEMA schema_name时,如果需要用户输入,如何防止schema_name参数的SQL注入?

schema_name 不能是引用值,因此例如 ActiveRecord::Base.sanitize() 将不起作用。 (如果您使用导轨)。

【问题讨论】:

    标签: postgresql schema sql-injection


    【解决方案1】:

    允许用户创建模式(通常是做 DDL)是相当不寻常的(甚至是可怕的)。你确定要这样做吗?

    在任何情况下,您都可以做通常的事情:清理您的输入(我猜如果您允许用户创建 schames,至少您可以限制允许的名称 - 例如只有字母数字等),和/或使用准备好的语句,绑定架构名称(这取决于您的语言/环境)。

    【讨论】:

    • 也许这是一个不同的问题,但为什么允许用户创建架构如此可怕?
    【解决方案2】:

    我知道这可能不是您正在寻找的答案,但如果您的设计让用户决定您的架构名称,但您不信任您的用户,那么您确实需要重新设计。让您的用户决定模式名称类似于要求用户决定类和函数名称。

    如果您真的非常想这样做,我会使用正则表达式将其限制为仅 16 个字母数字字符,以字母字符开头,强制小写 (/^[a-z][a-z0- 9]{1,15}$/)。您还需要明确过滤掉“public”作为架构名称、information_schema(如果您也允许使用下划线)和其他内置架构名称。

    再次,我愿意打赌你真的不想这样做,并且有更好的方法来解决你的根本问题。

    【讨论】:

      【解决方案3】:

      用户永远不应该拥有 DDL 权限,他们不需要它,这给了他们太多权力。

      您可以使用带有 quote_ident 的 SQL 函数来创建架构并避免 SQL 注入:

          CREATE OR REPLACE FUNCTION new_schema(IN _schemaname TEXT) 
          RETURNS bool 
          LANGUAGE plpgsql 
          AS
          $$
          BEGIN;
            EXECUTE 'CREATE SCHEMA ' || quote_ident(_schemaname);
      
            RETURN true;
          END;
          $$
          SECURITY DEFINER;
      
      -- test:
      SELECT new_schema('Frank; drop database template1');
      

      【讨论】:

        猜你喜欢
        • 2019-12-27
        • 2020-01-30
        • 2010-11-16
        • 1970-01-01
        • 2013-11-17
        • 1970-01-01
        • 2014-10-14
        • 2021-06-06
        • 1970-01-01
        相关资源
        最近更新 更多