SQL注入,一个老掉牙的安全问题,有SQL的地方就会有SQL注入。一般做企业应用的只关注Java层面的编写规范,比如使用preparedStatement,或者干脆直接过滤掉危险字符等等。
其实在编写PL/SQL的function或procedure的时候,也存在注入的问题,我们来简单探讨一下。
例如有这样一个procedure,功能为禁用某个table的constraint:
CREATE OR REPLACE PROCEDURE Disable_Constraint ( p_constraint_name VARCHAR2, p_table VARCHAR2 )
AUTHID CURRENT_USER
AS
p_schema VARCHAR2(32) := USER;
sql_stmt VARCHAR2(2000) := 'ALTER TABLE '
|| p_schema
|| '.'
|| p_table
|| ' DISABLE CONSTRAINT '
|| p_constraint_name ;
BEGIN
EXECUTE IMMEDIATE sql_stmt;
END;
/
了解SQL注入的同学应该可以看出来,上面的procedure存在几个危险的变量:
1. p_table
2. p_constraint_name
3. p_schema
前两者容易发现,但为什还有p_schema呢?因为当前的USER名字也有可能是用户构造的危险字符串。
好了,根据一般规律,我们应该遵循以下顺序进行修改:
1. 静态SQL。能不使用变量就不使用。
2. 绑定变量。与Java中的PreparedStatement类似,不把数据直接拼接在sql里,而是存入变量中,直接被数据库使用。
3. 检查变量的值。
显然,前两个方法对这个procedure不适用。我们只能使用最不爽的第3个方法。
好在对于PL/SQL来说,我们不用自己编写复杂的字符判断。Oracle有个SYS.DBMS_ASSERT包,提供了一些预置的function,如下:
NOOP |
No Operation. Returns string unchanged |
SIMPLE_SQL_NAME |
Verify that the input string is a simple SQL name. |
QUALIFIED_SQL_NAME |
Verify that the input string is a qualified SQL name. |
SCHEMA_NAME |
This function verifies that the input string is an existing schema name. |
SQL_OBJECT_NAME |
This function verifies that the input parameter string is a qualified SQL identifier of an existing SQL object. |
ENQUOTE_NAME |
This function encloses a name in double quotes. |
ENQUOTE_LITERAL |
Add leading and trailing single quotes to a string literal. |
(请参考:http://download.oracle.com/docs/cd/B28359_01/appdev.111/b28419/d_assert.htm)
在执行这些function时,如果传入的变量不满足规定的格式或条件,则会抛异常,从而保护我们自己的procedure不被SQL注入。
我们判断这些方法是否可用:
1. SIMPLE_SQL_NAME, QUALIFIED_SQL_NAME
这些方法要求用户出入的参数本身是一个有效的sql名字。比如,如果有个table名为"Table One",那么就要求传入的值中包含双引号。使用这些方法存在一个问题,直接从data-dictionary读取出来的table名字是不带双引号的。如果用户直接从data-dictionary中读取table名字,然后直接传入我们的procedure,则会因为它不满足simple sql name的要求而抛异常,但实际上这个table名字应该是正确的。所以不能直接使用这些function。
2. SCHEMA_NAME, SQL_OBJECT_NAME
这些方法要求传入的参数值是数据库中已经存在的对象名字。如果数据库中本来有个table名为 "Table One",那么如果用户传入Table One,则被视为正确。使用这些方法,避免了第一个方法的data-dictionary问题,而且也能够避免遭受类似table' -- 的问题。但存在所谓二次攻击的问题。如果用户提前创建了一个包含危险字符的table,然后再调用我们的procedure,依旧会造成SQL注入。
3. ENQUOTE_NAME, ENQUOTE_LITERAL
这些方法直接把参数的值用双引号或单引号括起来。如果括起来之后的值本身还存在危险的话,会抛异常。对于我们举例的procedure来说,只需要使用ENQUOTE_NAME。ENQUOTE_NAME需要两个参数,一个是需要enquote的变量,另一个为是否转换为大写。现在,对于我们的procedure,应该使用ENQUOTE_NAME(p_table, FALSE),保证Table One不被转换为"TABLE ONE"。
这是我们的最终解决方案。但需要注意的是,由于使用了ENQUOTE_NAME,对于我们的procedure来说,table和constraint的名字对大小写敏感。如果名为table_1,则必须传入TABLE_1,否则会执行错误。
修改后的代码如下:
CREATE OR REPLACE PROCEDURE Disable_Constraint ( p_constraint_name VARCHAR2, p_table VARCHAR2 )
AUTHID CURRENT_USER
AS
p_schema VARCHAR2(32) := SYS.DBMS_ASSERT.ENQUOTE_NAME(USER, FALSE);
sql_stmt VARCHAR2(2000);
safe_table VARCHAR2(32);
safe_constraint VARCHAR2(32);
BEGIN
safe_table := SYS.DBMS_ASSERT.ENQUOTE_NAME(p_table, FALSE);
safe_constraint := SYS.DBMS_ASSERT.ENQUOTE_NAME(p_constraint_name, FALSE);
sql_stmt := 'ALTER TABLE '
|| p_schema
|| '.'
|| safe_table
|| ' DISABLE CONSTRAINT '
|| safe_constraint ;
EXECUTE IMMEDIATE sql_stmt;
END;
/
分享到:
相关推荐
- 利用绑定变量,防止SQL注入,同时提高查询执行计划的复用性。 - 适当使用嵌套事务和保存点,以控制回滚范围,提高事务处理效率。 - 应用包缓存,减少内存分配开销,提高程序运行速度。 5. 表函数: - 表函数...
5. **输入验证**:对用户输入进行严格的检查,防止SQL注入和其他安全问题。使用内置的验证函数,如`VALIDATE_CONVERSION`检查数据类型转换。 6. **事务管理**:明确定义事务边界,使用`COMMIT`和`ROLLBACK`确保数据...
- **安全性**:在编写和执行PL/SQL代码时,确保遵循最佳安全实践,避免SQL注入等风险。 - **性能优化**:合理使用索引、物化视图、并行执行等技术,提升查询速度。 - **错误处理**:利用异常处理机制,捕获并处理...
9. **绑定变量**:绑定变量提高了SQL语句的可重用性和安全性,防止了SQL注入攻击。在PL/SQL中,可以使用":"符号定义变量并将其绑定到SQL语句中。 10. **性能优化**:PL/SQL提供了诸如分析和优化SQL语句、使用索引、...
- 安全性:限制权限,使用程序包进行权限封装,防止SQL注入。 6. 维护和升级 - PL/SQL的版本控制:使用Git或其他版本控制系统管理代码。 - 代码重构:改善代码结构,提高可读性和维护性。 - 升级策略:当Oracle...
确保对PL/SQL过程的调用经过适当的验证和授权,防止SQL注入攻击和其他恶意行为。使用绑定变量和预编译语句可以有效防御此类攻击。 4. **事务管理**:网上商店涉及大量的数据库操作,如添加购物车、结算订单等,这些...
3. **安全性考量**:确保所有的数据库操作都在适当的安全上下文中进行,防止SQL注入等安全威胁。 #### 七、总结 《Oracle的PL/SQL编程手册》是一份全面介绍了Oracle 10g Release 1 (10.1)版本下PL/SQL编程的重要...
11. **绑定变量**:绑定变量用于在SQL语句中使用动态参数,有助于防止SQL注入攻击,并提升执行性能。 12. **PL/SQL记录和表类型**:可以定义自己的记录类型来模拟表格,便于处理复杂的业务逻辑。 通过《Oracle ...
动态SQL允许在运行时构建和执行SQL语句,增强了灵活性,但需谨慎处理SQL注入问题。 通过练习PL/SQL题目,你可以加深对这些概念的理解,提升数据库编程技能。这些题目可能涵盖以上提到的所有知识点,从简单的变量...
- **安全防护**:介绍如何防止SQL注入等攻击方式。 - **权限管理**:探讨如何合理分配用户权限,确保数据安全。 - **审计跟踪**:利用PL/SQL记录操作日志,便于追踪问题和合规性检查。 #### 七、第三方开发工具的...
### PL/SQL命令技巧详解 #### 一、PL/SQL基础命令概述 PL/SQL(Procedural Language for SQL)是一种强大的过程化编程语言,它将SQL语句与传统过程化编程语言的功能相结合,用于增强数据库应用程序的功能性、性能...
- **SQL注入防护**:对用户输入的PL/SQL语句进行参数化处理或预编译,防止恶意SQL注入。 - **性能优化**:通过索引、批量处理、缓存等手段提高SQL执行效率。 - **权限控制**:限制不同用户对数据库的访问权限,...
- **绑定变量**:绑定变量用于在SQL语句中代替具体的值,可以提高性能并防止SQL注入攻击。 综上所述,掌握这些PL/SQL最佳实践对于开发高效、健壮的Oracle数据库应用程序至关重要。通过遵循这些指导原则,开发人员...
4. 安全性:遵循最小权限原则,为应用程序分配合适的数据库权限,避免SQL注入攻击。 总的来说,64位PL/SQL 12结合CX_ORACLE,为Windows 7用户提供了高效且强大的Oracle数据库开发和管理工具。通过深入理解这些工具...
- **参数化查询**:使用参数化查询防止SQL注入攻击。 - **最小权限原则**:为数据库用户分配尽可能小的权限,降低安全风险。 ### 五、总结 Oracle PL/SQL 10g作为Oracle数据库的重要组成部分,在企业级应用开发中...
它们可以防止SQL注入攻击,并提高查询性能,因为数据库可以重用已解析的SQL语句。 9. **游标表达式(FOR LOOP)**:PL/SQL提供了一种简洁的语法来遍历游标,简化了处理查询结果的代码。 10. **与Java、C++等的集成...
- **绑定变量**:避免SQL注入,同时提高查询性能。 - **PL/SQL执行计划**:理解和分析PL/SQL的执行计划,识别性能瓶颈。 10. **安全性** - **角色和权限**:分配权限给用户,通过角色进行权限管理。 - **程序...
绑定变量允许我们编写通用的SQL语句,其中的值在执行时再指定,这样可以提高性能并防止SQL注入攻击。 此外,PL/SQL还支持各种控制结构,如循环(WHILE、FOR)、条件语句(IF-THEN-ELSIF-ELSE)、异常处理(BEGIN-...