如何防止 SQL 注入 Oracle Apex

how to prevent sql injection oracle apex

提问人:potitit 提问时间:5/22/2020 更新时间:5/26/2020 访问量:940

问:

有人可以向我解释一下我在 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;
PLSQL Oracle-Apex SQL注入

评论

0赞 Scott 5/22/2020
你为什么要这样写SQL?为什么你认为存在漏洞?通常,如果有,这不是需要修补的错误,而是需要纠正的代码编写得不好。
0赞 potitit 5/22/2020
谢谢斯科特,我注意到使用 apexsec 工具进行易受攻击的 sql 注入。对不起,代码写得不好,你能向我解释哪些代码需要更正吗?
1赞 Koen Lostrie 5/22/2020
你把一个完整的陈述作为一个论据。这意味着您正在为“DROP TABLE xxx”、“CREATE PROCEDURE <something_malicious>”等语句打开大门。您在此处作为参数传递的语句应该是数据库中的代码。需要此代码吗?它在您的应用中的附加值是什么?您的问题类似于“我拆除了我的前门,以便我可以轻松进入。我怎样才能防止小偷进来?答:“把门放回去”。简而言之,除非您绝对需要它,否则请尝试摆脱此功能。
0赞 Jeffrey Kemp 5/26/2020
我知道我以前见过这段代码。github.com/RonnyWeiss/APEX-CLOB-Load-2/blob/master/......
0赞 Dan McGhan 5/26/2020
嗨,potitit,你还需要帮助还是克里斯的回答就足够了?如果足够了,请接受未来观众的答案。ApexSec 标记潜在问题。您必须知道此代码的使用位置,以及其使用仅限于开发人员(受信任)还是向最终用户公开(不受信任)。如果代码来自 Jeffrey 提到的插件,那么你可能没问题,前提是它正在执行的 SQL 来自开发人员,而不是从最终用户那里获取值的更动态的东西(绑定变量值除外,它们不容易受到 SQL 注入的影响)。

答:

0赞 Kris Rice 5/26/2020 #1

DBMS_SQL,立即执行,...它们本身并不脆弱,因为它们是实用程序,如果使用不当,它们的使用非常容易受到攻击。例如,有关安全使用 execute immediate 的示例,请参阅以下答案:Oracle - 为什么在存储过程中允许 EXECUTE IMMEDIATE ?

只有 2 种方法可以使此代码“安全”。

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

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

当且仅满足这两件事之一时,它才能用DBMS_ASSERT包裹。NOOP(P_IN_SQL_STATEMENT) 指示该值是可信的。