【问题标题】:how to prevent sql injection oracle apex如何防止sql注入oracle apex
【发布时间】:2020-09-08 12:03:39
【问题描述】:

有人可以向我解释一下我在 oracle apex 中的代码吗,它似乎容易受到 sql 注入的影响。 似乎 DBMS_SQL.EXECUTE(VR_CURS) 很容易受到攻击。 我的问题是如何利用这个查询,以及如何修补这个错误? 如果我使用 dbms.assert 怎么样?那更安全吗? 这是我的查询:

  FUNCTION SQL_TO_SYS_REFCURSOR (
   P_IN_SQL_STATEMENT   CLOB,
   P_IN_BINDS           SYS.DBMS_SQL.VARCHAR2_TABLE
    ) RETURN SYS_REFCURSOR AS
  VR_CURS         BINARY_INTEGER;    VR_REF_CURSOR   SYS_REFCURSOR;
  VR_EXEC         BINARY_INTEGER;
  * TODO make size dynamic */
  VR_BINDS        VARCHAR(100);
  BEGIN
  VR_CURS         := DBMS_SQL.OPEN_CURSOR;
  DBMS_SQL.PARSE(
      VR_CURS,
      P_IN_SQL_STATEMENT,
      DBMS_SQL.NATIVE
  );
  IF P_IN_BINDS.COUNT > 0 THEN
      FOR I IN 1..P_IN_BINDS.COUNT LOOP
      /* TODO find out how to prevent ltrim */
          VR_BINDS   := LTRIM(
              P_IN_BINDS(I),
              ':'
        );
          DBMS_SQL.BIND_VARIABLE(
              VR_CURS,
              VR_BINDS,
              V(VR_BINDS)
          );
      END LOOP;
  END IF;

  VR_EXEC         := DBMS_SQL.EXECUTE(VR_CURS);
VR_REF_CURSOR   := DBMS_SQL.TO_REFCURSOR(VR_CURS);
RETURN VR_REF_CURSOR;
EXCEPTION
  WHEN OTHERS THEN
      IF DBMS_SQL.IS_OPEN(VR_CURS) THEN
          DBMS_SQL.CLOSE_CURSOR(VR_CURS);
      END IF;
      RAISE;
END;

【问题讨论】:

  • 为什么要这样写SQL?为什么你认为存在漏洞?通常,如果存在,这不是需要修补的错误,而是需要纠正的编写不佳的代码。
  • 感谢 scott,我注意到使用 apexsec 工具进行的易受攻击的 sql 注入。我很抱歉代码写得不好,你能告诉我哪些代码需要更正吗?
  • 您将完整的陈述作为论据。这意味着您正在为“DROP TABLE xxx”、“CREATE PROCEDURE ”等语句打开大门。您在此处作为参数传递的语句应该是数据库中的代码。需要这个代码吗?它在您的应用程序中的附加价值是什么?您的问题类似于“我卸下了前门,以便可以轻松进入。如何防止小偷进入?”。答案:“把门放回去”。简而言之,除非您绝对需要,否则请尝试摆脱此功能。
  • 我知道我以前看过这段代码。 github.com/RonnyWeiss/APEX-CLOB-Load-2/blob/master/…
  • 嗨,potitit,您还需要帮助吗?或者 Kris 的回答是否足够?如果足够,请接受未来观众的答案。 ApexSec 标记潜在问题。您必须知道此代码在哪里使用,以及它的使用是否仅限于开发人员(受信任)或暴露给最终用户(不受信任)。如果代码来自 Jeffrey 提到的插件,那么您可能没问题,只要它执行的 SQL 来自开发人员,而不是从最终用户那里获取值的更动态的东西(除了绑定变量值,它们是不易受到 SQL 注入的攻击)。

标签: oracle plsql oracle-apex sql-injection


【解决方案1】:

DBMS_SQL, EXECUTE IMMEDIATE , ... 因为它们是实用程序,所以它们本身并不容易受到攻击,当使用错误时,它们的使用很容易受到攻击。有关安全使用立即执行的示例,请参阅此答案:Oracle - Why is EXECUTE IMMEDIATE allowed in stored procedures?

此代码只有两种“安全”方式。

a) 调用者高度信任。这意味着该函数的任何和所有用法都是已知的,并且该调用者中用于构建 sql 语句的机制是可信任的。甚至可以添加调用堆栈检查来拒绝未知调用者,这可能来自owa_util.who_called_me

b ) 在与 DBMS_SQL.PARSE 一起使用之前对 P_IN_SQL_STATEMENT 进行完整解析。这意味着编写一个完整的 sql 和 pl/sql 解析器来分析潜在注入的输入。

IF 并且仅当满足这两个条件之一时,才可以使用 DBMS_ASSERT.NOOP(P_IN_SQL_STATEMENT) 将其包装以表明该值是可信的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-09-07
    • 2013-04-18
    • 2011-06-21
    • 2011-10-02
    • 1970-01-01
    • 2011-06-12
    • 1970-01-01
    相关资源
    最近更新 更多