Java安全编码实践总结(上)

摘要: Java作为企业主流开发语言已流行多年,各种java安全编码规范也层出不穷,本文将从实践角度出发,整合工作中遇到过的多种常见安全漏洞,给出不同场景下的安全编码方式。

本文漏洞复现的基础环境信息:jdk版本:1.8 ,框架:springboot1.5,数据库:mysql5.6和mongodb3.6,个别漏洞使用到不同的开发框架会特别标注。

安全编码实践

Sql注入防范

常见安全编码方法:预编译+输入验证

预编译适用于大多数对数据库进行操作的场景,但预编译并不是万能的,涉及到查询参数里需要使用表名、字段名的场景时(如order by、limit、group by等),不能使用预编译,因为会产生语法错误。常见的预编译写法如下

jdbc:

1592132332_5ee602ec22c59.png!small

Hibernate

1592132350_5ee602fe0d657.png!small

Ibatis

1592132360_5ee60308412f5.png!small

Mybatis

1592132370_5ee603126ca8c.png!small

在无法使用预编译的场景,可以使用数据校验的方式来拦截非法参数,数据校验推荐使用白名单方式。

错误写法:不能使用预编译的场景(直接拼接用户的查询条件)

1592132420_5ee60344885bc.png!small

漏洞利用验证:

1592132430_5ee6034e4e8c6.png!small

不能使用预编译的正确写法(通过白名单验证用户输入):

1593317117_5ef816fdc689c.png!small

漏洞修复验证:

1592132527_5ee603af4d4e5.png!small

Nosql注入防范

涉及到非关系型数据库mongdb在查询时不能使用拼接sql的方式,需要绑定参数进行查询,跟关系型数据库的预编译类似

错误写法(拼接用户的查询条件):

1592132580_5ee603e402891.png!small

漏洞利用验证:

1592132584_5ee603e84d1f7.png!small

正确写法(参数绑定):

1592132593_5ee603f1bcec3.png!small

漏洞修复验证:

1592132598_5ee603f60d013.png!small

Xss防范

白名单校验
适用于纯数字、纯文本等地方,如用户名
Esapi
适用于常规的输入输出,如用户评论

1592132618_5ee6040a32f77.png!small

错误写法(对用户输入内容不做处理):

1592132629_5ee6041554277.png!small

正确写法(通过esapi的黑白名单配置来实现富文本xss的过滤):

1592132636_5ee6041c69e71.png!small

漏洞利用及修复验证:

1592132643_5ee60423ded67.png!small

XXE注入防范

为了避免 XXE injections,应为 XML 代理、解析器或读取器设置下面的属性:

factory.setFeature("http://xml.org/sax/features/external-general-entities",false);
factory.setFeature("http://xml.org/sax/features/external-parameter-entities",false);

如果不需要 inline DOCTYPE 声明,可使用以下属性将其完全禁用:

factory.setFeature("http://apache.org/xml/features/disallow-doctype-decl",true);

错误写法(以xmlReader为例,允许解析外部实体):

XMLReaderxmlReader = XMLReaderFactory.createXMLReader();
xmlReader.parse(newInputSource(newStringReader(body)));

漏洞利用验证:

1592132814_5ee604ced2dba.png!small

1592132836_5ee604e40ebf3.png!small

正确写法(禁止解析部实体):

XMLReaderxmlReader = XMLReaderFactory.createXMLReader();
xmlReader.setFeature("http://xml.org/sax/features/external-general-entities",false);
xmlReader.setFeature("http://xml.org/sax/features/external-parameter-entities",false);
xmlReader.parse(newInputSource(newStringReader(body)));

文件上传漏洞

文件名随机,防止被猜解上传路径

限制上传文件大小,防止磁盘空间被恶意占用

限制上传文件类型,防止上传可执行文件

正确写法(限制文件类型大小,通过uuid生成随机文件名保存):

1592132968_5ee60568a0b40.png!small

漏洞利用验证

1592132978_5ee6057228e05.png!small

漏洞修复验证:

1592132984_5ee60578d1c3f.png!small

文件包含

限制文件在指定目录,逻辑名称绑定文件路径,跟文件上传的处理类似,通过文件id读取对应资源文件

错误写法(直接请求用户设置的资源):

String returnURL = request.getParameter("returnURL");
returnnew ModelAndView(returnURL);

漏洞利用验证:

1592135166_5ee60dfed9e05.png!small

正确写法(通过文件id和真实路径的映射设置白名单):

if(SecurityUtil.checkid(file_id) ==null) {
    return"资源文件不存在!";
}
returnget_file(SecurityUtil.find_path(file_id));
}

文件上传后对应的路径会存储在数据库里,表结构如下:

1592132998_5ee6058698f87.png!small

漏洞修复验证

1592133006_5ee6058ecb9c5.png!small

Csrf

常见的框架已经自带了防范csrf的功能,只需要正确的配置启用即可

struts2

JSP使用<s:token/>标签,在struts配置文件中增加token拦截器

页面代码:

1592133330_5ee606d2eb88f.png!small

漏洞修复验证:

1592133368_5ee606f8049b1.png!small

Spring

正确写法:使用spring-security

1592133379_5ee6070329678.png!small

漏洞修复验证

1592133385_5ee607092df4e.png!small

原文地址:https://www.freebuf.com/vuls/240172.html

上一篇:Java安全编码实践总结(下...
下一篇:BBPress未经身份验证的...