1 - 输入校验

编码原则:针对各种语言本身的保留字符,做到数据与代码相分离

1.1 SQL 注入防范

严重性高,可能性低。

(1) 参数校验,拦截非法参数(推荐白名单):

public String sanitizeUser(String username) {
return Pattern.matches("[A-Za-z0-9_]+", username)
? username : "unauthorized user";
}

(2) 使用预编译:

String sql = "UPDATE EMPLOYEES SET SALARY = ? WHERE ID = ?";
PreparedStatement statement = conn.prepareStatement(sql);
statement.setBigDecimal(1, 285500.00);
statement.setInt(2, 30015800);

1.2 XSS防范

严重性中,可能性高。防范方法有:

(1) 输入输出校验(推荐白名单);

(2) org.apache.commons.lang 工具包处理;

(3) 富文本可用 owasp antisampjava html sanitizer 处理;

(4) ESAPI 处理:

// HTML 实体
ESAPI.encoder().encodeForHTML(data); // HTML 属性
ESAPI.encoder().encodeForHTMLAttribute(data); // JavaScript
ESAPI.encoder().encodeForJavaSceipt(data); // CSS
ESAPI.encoder().encodeForCSS(data); // URL
ESAPI.encoder().encodeForURL(data);

1.3 代码注入/命令执行防范

严重性高,可能性低。

(1) 参数校验,拦截非法参数(推荐白名单);

(2) 不直接执行用户传入参数:

if("open".equals(request.getParameter("choice"))) {
Runtime.getRuntime().exec("your command...");
}

(3) 及时更新升级第三方组件:

比如Struts、Spring、ImageMagick等。

1.4 日志伪造防范

严重性低,可能性高。

(1) 不要log用户可控的信息;

(2) 输入参数校验(推荐白名单):

// 处理回车、换行符
Pattern p = Pattern.compile("%0a|%0d0a|\n|\r\n");
Matcher m = p.matcher(data);
dest = m.replaceAll("");

(3) 使用 Log4j2。

1.5 XML 外部实体攻击

严重性中,可能性中。

(1) 关闭内联 DTD 解析,使用白名单来控制允许使用的协议;

(2) 禁用外部实体:

DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
factory.setExpandEntityReferences(false);

(3) 过滤用户提交的 XML 数据:

比如 !DOCTYPE<!ENTITYSYSTEMPUBLIC 等。

1.6 XML 注入防范

严重性中,可能性低。

(1) 教研用户输入(推荐白名单):

OutputFormat format = OutputFormat.createPrettyPrint();

(2) 使用安全的 XML 库(比如 dom4j)。

1.7 URL 重定向防范

严重性中,可能性低。

(1) 设置严格白名单几网络边界:

String url = request.getParameter("url");
String host = getHostFromUrl(url);
if(!validateHost(host)) {
return;
}

(2) 加入有效性验证的 Token;

(3) referer 适用于检测监控 URL 重定向、CSRF 等,多数场景下也可用作防范措施。

2 - 异常处理

编码原则:不要泄露详细异常信息。

2.1 敏感信息泄露防范

严重性低,可能性中。

屏蔽敏感信息示例:

catch(IOException e) {
System.out.println("Invalid file");
// System.out.println("Error code: 0001");
return;
}

2.2 保持对象一致性

严重性中,可能性低。

(1) 重排逻辑,使得产生异常的代码在改变对象状态的代码之前执行;

catch(Exception e) {
// revert
money -= PADDING;
return -1;
}

(2) 在出现异常导致操作失败的情况下,使用事务回滚机制;

(3) 在对象的临时拷贝上执行操作,成功后再提交给正式的对象;

(4) 回避修改对象的需求,尽量不去修改对象。

3 - I/O 操作

编码规则:可写的文件不可执行,可执行的文件不可写。

3.1 资源释放

严重性低,可能性高。

Java 垃圾回收器回自动释放内存资源,非内存资源需要开发人员手动释放,比如 DataBase,Files,Sockets,Streams,Synchronization 等资源的释放。

try {
Connection conn = getConnection();
Statement statement = conn.createStatement();
ResultSet resultSet = statement.executeQuery(sqlQuery);
processResults(resultSet);
} catch(SQLException e) {
// forward to handler
} finally {
if (null != conn) {
conn.close();
}
}

3.2 清除临时文件

严重性中,可能性中。

(1) 自动清除:

File tempFile = Files.createTempFile("tempname", ".tmp");
try {
BufferedWriter writer = Files.newBufferedWriter(tempFile.toPath(),
StandardCharsets.UTF_8, StandardOpenOption.DELETE_ON_CLOSE)
// operate the file
writer.newLine();
} catch (IOException e) {
e.printStackTrace();
}

(2) 手动清除。

3.3 避免将 bufer 暴露给不可信代码

严重性中,可能性中。

wrap、duplicate 创建的 buffer 应该以只读或拷贝的方式返回:

Charbuffer buffer;
public Duplicator() {
buffer = CharBuffer.allocate(10);
} /** 获取只读的 Buffer */
public CharBuffer getBufferCopy() {
return buffer.asReadOnlyBuffer();
}

3.4 任意文件下载/路径遍历防范

严重性中,可能性高。

(1) 校验用户可控的参数(推荐白名单);

(2) 文件路径保存到数据库,让用户提交文件对应的 ID 去下载文件:

<%
String filePath = getFilePath(request.getParameter("id"));
download(filePath);
%>

(3) 判断目录和文件名:

if(!"/somedir/".equals(filePath) || !"jpg".equals(fileType)) {
...
return -1;
}

(4) 下载文件前做权限判断。

补充:禁止将敏感文件(如日志文件、配置文件、数据库文件等)存放在 web 内容目录下。

3.5 非法文件上传防范

严重性高,可能性中。

在服务器端用白名单方式过滤文件类型,使用随机数改写文件名和文件路径。

if(!ESAPI.validator().isValidFileName(
"upload", filename, allowedExtensions, false)) {
throw new ValidationUploadException("upload error");
}

补充:如果使用第三方编辑器,请及时更新版本。

4 - 序列化/反序列化操作

编码原则:不信任原则。

4.1 敏感数据禁止序列化

严重性高,可能性低。

使用 transientserialPersistentFields 标注敏感数据:

private static final ObjectStreamField[] serialPersistentFields = {
new ObjectStreamField("name", String.class),
new ObjectStreamField("age", Integer.TYPE)
}

当然,正确加密的敏感数据可以序列化。

4.2 正确使用安全管理器

严重性高,可能性低。

如果一个类的构造方法中含有各种安全管理器的检查,在反序列化时也要进行检查:

private void writeObject(ObjectOutputStream out) throws IOException {
performSecurityManagerChek();
out.writeObject(xxx);
}

补充:第三方组件造成的反序列化漏洞可通过更新升级组件解决;

禁止 JVM 执行外部命令,可减小序列化漏洞造成的危害。

5 - 运行环境

编码原则:攻击面最小化原则。

5.1 不要禁用字节码验证

严重性中,可能性低。

启用 Java 字节码验证:Java -Xverify:all ApplicationName

5.2 不要远程调试/监控生产环境的应用

严重性高,可能性低。

(1) 生产环境中安装默认的安全管理器,并且不要使用 -agentlib-Xrunjdwp-Xdebug 命令行参数:

${JAVA_HOME}/bin/java -Djava.security.manager ApplicationName

(2) iptables 中关闭相应 jdwp 对外访问的端口。

5.3 生产应用只能有一个入口

严重性中,可能性中。

移除项目中多余的 main 方法。

6 - 业务逻辑

编码原则:安全设计 API。

6.1 用户体系

过程如下:

(1) identification <-- 宣称用户身份(鉴定提供唯一性)

|

|--> (2) authentication <-- 验证用户身份(验证提供有效性)

|

|--> (3) authorization <-- 授权访问相关资源(授权提供访问控制)

|

|--> RESOURCE

|

|--> (4) accountability <-- 日志追溯

(1) 身份验证:

严重性高,可能性中。

多因素认证;

暴力破解防范:验证码、短信验证码、密码复杂度校验、锁定账号、锁定终端等;

敏感数据保护:存储、传输、展示(API 接口、HTML 页面掩码);

禁止本地验证:重要操作均在服务器端进行验证。

(2) 访问控制:

严重性高,可能性中。

从 Session 中获取身份信息;

禁用默认账号、匿名账号,限制超级账号的使用;

重要操作做到职责分离;

用户、角色、资源、权限做好相互校验;

权限验证要在服务器端进行;

数据传输阶段做好加密防篡改。

补充:oauth 授权时授权方和应用方都要做好安全控制。

(3) 会话管理:

严重性高,可能性中。

漏洞名称 防御方法
会话 ID 中嵌入 URL 会话 ID 保存在 Cookie 中
无 Session 验证 所有的访问操作都应基于 Session
Session 未清除 注销、超时、关闭浏览器时,都要清除 Session
Session 固定攻击 认证通过后更改 Session ID
Session ID 可猜测 使用开发工具中提供的会话管理机制
重放攻击 设置一次失效的随机数,或设置合理的时间窗

补充:设置认证 Cookie 时,需加入 secure 和 httponly 属性。

(3) 日志追溯:

严重性中,可能性中。

  • 记录每一个访问敏感数据的请求,或执行敏感操作的事件;
  • 防范日志伪造攻击(输入校验);
  • 任何对日志文件的访问(读、写、下载、删除)尝试都必须被记录。

6.2 在线支付

严重性高,可能性中。

支付数据做签名,并确保签名算法的可靠;

重要参数进行校验,并做有效性验证;

验证订单的唯一性,防止重放攻击。

6.3 顺序执行

严重性高,可能性中。

对每一步的请求都要严格验证,并且要以上一步的执行结果为依据;

给请求参数加入随机 key,贯穿验证的始终。

参考资料

安全编码指南Secure Coding Guidelines for Java SE

安全编码示例SEI CERT Oracle Coding Standard for Java

版权声明

作者: 瘦风(https://healchow.com)

出处: 博客园 瘦风的博客(https://www.cnblogs.com/shoufeng)

感谢阅读, 右侧导航栏有「瘦风的南墙」公众号二维码,输出更及时、更体系,欢迎扫码关注

Java - Java开发中的安全编码问题的更多相关文章

  1. Java Web开发中路径问题小结

     Java Web开发中,路径问题是个挺麻烦的问题,本文小结了几个常见的路径问题,希望能对各位读者有所帮助. (1) Web开发中路径的几个基本概念 假设在浏览器中访问了如下的页面,如图1所示: 图1 ...

  2. Java Web 开发中路径相关问题小结

    Java Web开发中路径问题小结 (1) Web开发中路径的几个基本概念 假设在浏览器中访问了如下的页面,如图1所示: 图1 Eclipse中目录结构如图2所示: 图2 那么针对这个站点的几个基本概 ...

  3. 《Maven在Java项目开发中的应用》论文笔记(十七)

    标题:Maven在Java项目开发中的应用 一.基本信息 时间:2019 来源:山西农业大学 关键词:Maven:Java Web:仓库:开发人员:极限编程; 二.研究内容 1.Maven 基本原理概 ...

  4. Java项目开发中实现分页的三种方式一篇包会

    前言   Java项目开发中经常要用到分页功能,现在普遍使用SpringBoot进行快速开发,而数据层主要整合SpringDataJPA和MyBatis两种框架,这两种框架都提供了相应的分页工具,使用 ...

  5. Java应用开发中的字符集与字符编码

    事出有因 在向HttpURLConnection的输出流写入内容时,因没有设置charset,导致接收方对数据的验签不一致. URL url = new URL(requestUrl); //打开连接 ...

  6. Java Web开发中MVC设计模式简介

    一.有关Java Web与MVC设计模式 学习过基本Java Web开发的人都已经了解了如何编写基本的Servlet,如何编写jsp及如何更新浏览器中显示的内容.但是我们之前自己编写的应用一般存在无条 ...

  7. Java Web开发中的名词解释

    1.JVM Java虚拟机,class文件的运行时环境,就好比软件运行在操作系统一样,java要运行在JVM中才行,这也是Java之所以支持扩平台的基础. 2.Servlet/JSP 是满足一定接口需 ...

  8. java 组件开发中的日志记录问题

    今天帮别人写封装几个url 请求,打成jar 包,可以以java接口的方式提供给外部访问. 遇到两个问题: 1. 是否把依赖的jar包也 打入 我要生成的jar包中,如果你不打入,别人直接调用接口会报 ...

  9. java web开发中常用的协议的使用和java-web 常见的缓冲技术

    一.DNS协议 作用将域名解析为IP   类似于我们只需要知道中央一台,中央二台,而不需要知道它的频率,方便记忆. java dns 域名解析协议实现 1 域名解析,将域名可转换为ip地址InetAd ...

  10. Java web开发中主要用到的jar包

    1.Java开发中主要用到的jar包介绍:(1)java JDK基础开发包:java包和javax包.书写方式:import java.lang.reflect.InvocationTargetExc ...

随机推荐

  1. 从iPhone下滑 看科技转型之困

    看科技转型之困" title="从iPhone下滑 看科技转型之困"> 毫无疑问,苹果正在面临一次关键转型.最近苹果股价较高点134.54美元下跌21%以上的实事, ...

  2. 【转载】Java for循环

    转载只为个人学习,阅读请前往原地址:Java for循环的几种用法详解 本文主要是来了解一下Java中的几种for循环用法,分析得十分详细,一起来看看. J2SE 1.5提供了另一种形式的for循环. ...

  3. VUE实现Studio管理后台(二):Slot实现选项卡tab切换效果,可自由填装内容

    作为RXEditor的主界面,Studio UI要使用大量的选项卡TAB切换,我梦想的TAB切换是可以自由填充内容的.可惜自己不会实现,只好在网上搜索一下,就跟现在你做的一样,看看有没有好事者实现了类 ...

  4. Java树结构

    今天在项目中,运用到了Java树结构,是在一个查询中,选择树结构例如图片 该结构采用了前段的最新的知识,通过xml结构的数据库,后端Spring的映射实现的. 代码示例: 数据库: <!-- 取 ...

  5. Hibernate入门之注解@Column详解

    前言 上一节我们讲解了Hibernate的主键生成策略,本节我们继续来讲讲Hibernate中针对列的映射即@Column注解,文中若有错误之处,还望指正. @Column注解详解 我们看到如上针对列 ...

  6. css布局中的各种FC(BFC、IFC、GFC、FFC)

    什么是FC?FC(Formatting Context)格式化上下文,其实指的是一个渲染区域,拥有一套渲染规则,它决定了其子元素如何定位,以及与其他元素之间的关系和相互作用. 什么是BFC? BFC( ...

  7. 前端---css3优化

    一.视差滚动(经过优化后的代码) .front::before { content: ''; position: fixed; // 代替background-attachment width: 10 ...

  8. 负margin在页面布局中的应用

    关于负margin的原理建议大家看看这篇文章:http://www.cnblogs.com/2050/archive/2012/08/13/2636467.html#2457812 一. 左右列固定, ...

  9. 编译putty 源码去掉 Are you sure you want to close this session? 提示

    0, 为什么要编译 putty ?在关闭窗口的时候,会弹出一个 Are you sure you want to close this session?要把这个去掉.当然也可以用 OD 之类的来修改. ...

  10. Java自学路线图之Java框架自学

    Java自学路线图的框架分为两个阶段,第一阶段的Java框架包含六个内容:MyBatis,Spring,SpringMVC,Maven高级,Git,Dubbo. 在Java自学过程中掌握框架的使用,对 ...