如何防止sql注入oracle apex
Posted
技术标签:
【中文标题】如何防止sql注入oracle apex【英文标题】:how to prevent sql injection 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 PROCEDUREDBMS_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) 将其包装以表明该值是可信的。
【讨论】:
以上是关于如何防止sql注入oracle apex的主要内容,如果未能解决你的问题,请参考以下文章