收藏 分享(赏)

华为技术有限公司内部技术规范.docx

上传人:刘岱文 文档编号:5590 上传时间:2018-05-20 格式:DOCX 页数:70 大小:306.73KB
下载 相关 举报
华为技术有限公司内部技术规范.docx_第1页
第1页 / 共70页
华为技术有限公司内部技术规范.docx_第2页
第2页 / 共70页
华为技术有限公司内部技术规范.docx_第3页
第3页 / 共70页
华为技术有限公司内部技术规范.docx_第4页
第4页 / 共70页
华为技术有限公司内部技术规范.docx_第5页
第5页 / 共70页
点击查看更多>>
资源描述

1、Java 语言编程规范 下卷 安全篇 仅内部使用2018-5-20 华为技术有限公司 Page 1 of 70华为技术有限公司内部技术规范DKBA 6915-2014.07Java语言编程规范下卷 安全篇华为技术有限公司版权所有 侵权必究Java 语言编程规范 下卷 安全篇 仅内部使用2018-5-20 华为技术有限公司 Page 2 of 70修订声明本规范拟制与解释部门:网络安全能力中心本规范的相关系列规范或文件:Java 语言编程规范 上卷 综合篇 (DKBA1040-2014.07) 、 C/.拒绝已知坏的数据这种策略被称为“黑名单”或者“负向”校验,相对于正向校验,这是一种较弱的校验

2、方式。这种策略比较危险,因为潜在的不合法数据可能是一个不受约束的无限集合。采取这种策略意味着你必须一直维护一个已知不合法字符或者模式的列表。除非对不合法的正则表达式进行日常更新以及定期研究新的攻击方式,否则程序中的校验就会很快过时。public String removeJavascript(String input) Pattern p = Ppile(“javascript“, Pattern.CASE_INSENSITIVE); Matcher m = p.matcher(input); return (!m.matches() ? input : “; “白名单 ”方式净化对数据中任何

3、不属于某个已验证的、合法字符列表的字符进行删除、编码、或者替换,然后后再使用这些净化后的数据。以下给出了一些列子:如果你期望接收一个电话号码,那么你可以剔除掉输入中所有的非数字字符,因此,“(555)123-1234”,“555.123.1234”,与“555“;DROP TABLE USER;-123.1234”全部会被转换成“5551231234”。注意,这里你还需要继续对转换的结果进行校验。正如你所看到的,这样做不仅有利于安全,同时它允许你接收和使用一个更宽泛的有效用户输入。但是,对于一个用户评论栏的文本输入,确定一个合法的数据集合是非常困难的,因为几乎所有的字符都可以被用到。一种解决方

4、案是:将所有非字母数字替换成其编码后的版本,那么“I like your web page!”被净化后将输出为“I+like+your+web+page%21”,这里使用了URL编码。“黑名单 ”方式净化为了确保输入数据是“安全”的,可以剔除或者转换某些字符(例如,删除引号、转换成HTML实体)。跟“黑名单” 校验类似,这种策略需要对不合法字符进行日常维护,并且Java 语言编程规范 下卷 安全篇 仅内部使用2018-5-20 华为技术有限公司 Page 8 of 70不合法字符的范围很难保证是完整的。实际上大部分输入字段都有其特定的语法格式,相对于为了应对当前和未来所有攻击方式而引入一个复杂

5、、迟钝的净化程序,执行一个单纯针对正确输入的正向校验更加简单,高效,与安全。public static String quoteApostrophe(String input)if (input != null)return input.replaceAll(“, “);elsereturn null;规则 1.2 禁止直接使用不可信数据来拼接 SQL 语句说明:SQL注入是指原始SQL查询被动态更改成一个与程序预期完全不同的查询。执行这样一个更改后的查询可能导致信息泄露或者数据被篡改。防止SQL注入的方式主要可以分为两类: 使用参数化查询 对不可信数据进行校验参数化查询是一种简单有效的防止S

6、QL注入的查询方式,应该被优先考虑使用。另外,参数化查询还能改进数据库访问的性能,例如,SQL Server与Oracle数据库会为其缓存一个查询计划,以便在多次重复执行相同的查询语句时重复使用。错误示例(Java 代码动态构建 SQL):Statement stmt = null;ResultSet rs = null;tryString userName = ctx.getAuthenticatedUserName(); /this is a constantString sqlString = “SELECT * FROM t_item WHERE owner=“ + userName

7、+ “ AND itemName=“ + request.getParameter(“itemName“) + “;stmt = connection.createStatement();rs = stmt.executeQuery(sqlString);/ . result set handlingcatch (SQLException se)/ . logging and error handling这里将查询字符串常量与用户输入进行拼接来动态构建SQL查询命令。仅当itemName不包含单引号时,这条查询语句的行为才会是正确的。如果一个攻击者以用户名wiley发起一个请求,并使用以下条目

8、名称参数进行查询:name OR a = a那么这个查询将变成:SELECT * FROM t_item WHERE owner = wiley AND itemname = name OR a=a;此处,额外的OR a=a条件导致整个 WHERE子句的值总为真。那么,这个查询便等价于如下非常简单的查询:SELECT * FROM t_itemJava 语言编程规范 下卷 安全篇 仅内部使用2018-5-20 华为技术有限公司 Page 9 of 70这个简化的查询使得攻击者能够绕过原有的条件限制:这个查询会返回items表中所有储存的条目,而不管它们的所有者是谁,而原本应该只返回属于当前已认

9、证用户的条目。正确示例(使用 PreparedStatement 进行参数化查询):PreparedStatement stmt = nullResultSet rs = nulltryString userName = ctx.getAuthenticatedUserName(); /this is a constantString itemName = request.getParameter(“itemName“);/ .Ensure that the length of userName and itemName is legitimate/ .String sqlString = “

10、SELECT * FROM t_item WHERE owner=? AND itemName=?“;stmt = connection.prepareStatement(sqlString);stmt.setString(1, userName);stmt.setString(2, itemName);rs = stmt.executeQuery();/ . result set handlingcatch (SQLException se)/ . logging and error handling如果使用参数化查询,则在SQL语句中使用占位符表示需在运行时确定的参数值。参数化查询使得SQ

11、L查询的语义逻辑被预先定义,而实际的查询参数值则等到程序运行时再确定。参数化查询使得数据库能够区分SQL语句中语义逻辑和数据参数,以确保用户输入无法改变预期的SQL查询语义逻辑。在Java中,可以使用java.sql.PreparedStatement来对数据库发起参数化查询。在这个正确示例中,如果一个攻击者将itemName输入为name OR a = a,这个参数化查询将免受攻击,而是会查找一个itemName匹配name OR a = a这个字符串的条目。错误示例(在存储过程中动态构建 SQL):Java代码:CallableStatement = nullResultSet resul

12、ts = null;tryString userName = ctx.getAuthenticatedUserName(); /this is a constantString itemName = request.getParameter(“itemName“);cs = connection.prepareCall(“call sp_queryItem(?,?)“);cs.setString(1, userName);cs.setString(2, itemName);results = cs.executeQuery();/ . result set handlingcatch (SQL

13、Exception se)/ . logging and error handlingSQL Server存储过程:CREATE PROCEDURE sp_queryItemuserName varchar(50),itemName varchar(50) AS BEGIN DECLARE sql nvarchar(500); SET sql = SELECT * FROM t_item WHERE owner = + userName + AND itemName = + itemName + ;EXEC(sql); Java 语言编程规范 下卷 安全篇 仅内部使用2018-5-20 华为技

14、术有限公司 Page 10 of 70END GO在存储过程中,通过拼接参数值来构建查询字符串,和在应用程序代码中拼接参数一样,同样是有SQL注入风险的。正确示例(在存储过程中进行参数化查询):Java 代码:CallableStatement = nullResultSet results = null;tryString userName = ctx.getAuthenticatedUserName(); /this is a constantString itemName = request.getParameter(“itemName“);/ . Ensure that the len

15、gth of userName and itemName is legitimate/ . cs = connection.prepareCall(“call sp_queryItem(?,?)“);cs.setString(1, userName);cs.setString(2, itemName);results = cs.executeQuery();/ . result set handlingcatch (SQLException se)/ . logging and error handlingSQL Server存储过程:CREATE PROCEDURE sp_queryItem

16、userName varchar(50), itemName varchar(50) AS BEGIN SELECT * FROM t_item WHERE userName = userNameAND itemName = itemName; END GO这个存储过程使用参数化查询,而未包含不安全的动态SQL构建。数据库编译此存储过程时,会生成一个SELECT查询的执行计划,只允许原始的SQL 语义被执行。任何参数值,即使是被注入的SQL语句也不会被执行,因为它们不是执行计划的一部分。错误示例(Hibernate: 动态构建 SQL/HQL):原生SQL查询:String userName

17、= ctx.getAuthenticatedUserName(); /this is a constantString itemName = request.getParameter(“itemName“);Query sqlQuery = session.createSQLQuery(“select * from t_item where owner = “ + userName + “ and itemName = “ + itemName + “);List rs = (List) sqlQuery.list();HQL查询:String userName = ctx.getAuthen

18、ticatedUserName(); /this is a constantString itemName = request.getParameter(“itemName“);Query hqlQuery = session.createQuery(“from Item as item where item.owner = “ + userName + “ and item.itemName = “ + itemName + “);List hrs = (List) hqlQuery.list();即使是使用Hibernate ,如果在动态构建 SQL/HQL查询时包含了不可信输入,同样也会面临SQL/HQL注入的问题。正确示例(Hibernate: 参数化查询):HQL中基于位置的参数化查询:String userName = ctx.getAuthenticatedUserName(); /this is a constant

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 网络技术 > 后端技术

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:文库网官方知乎号:文库网

经营许可证编号: 粤ICP备2021046453号世界地图

文库网官网©版权所有2025营业执照举报