任何可以用来绕过系统安全策略限制的缺陷都是安全漏洞。
构建安全可靠的服务需要通过整体性的安全设计和综合性的防范手段。
Java的安全机制
1. 运行时安全机制
字节码校验
类加载过程中,字节码验证,防止不合规的代码影响JVM运行或载入恶意代码。
如,自行编译String类替换JDK的String类就无法通过类加载。
Class Loader 隔离代码
-
应用无法获取 Bootstrap Class-Loader 对象实例。
-
不同的 Class Loader 可以起到容器的作用,隔离模块间不必要可见性。
SecurityManager 机制
利用 SecurityManager 机制和相关组件,限制代码运行时行为能力。
对安全要求非常高的应用可以开启 SecurityManager:
Shell代码
-
-Djava.security.manager
注意:启用 Security会导致 10%~15% 的性能下降。
Oracle 官方有非常保守的建议:如果你确定你的应用不会运行恶意代码,也没有用户身份验证,那么可以禁用SecurityManager。
2. 安全框架API
这些API与JDK厂商有关,不同的JDK实现者可能会定制自己的加密算法实现。
-
加密、解密 API
-
授权、鉴权 API
-
安全通信相关类库。如 TLS、OSCP等协议的标准实现
3. JDK集成的安全工具
JDK包中附带了一些安全相关的工具。如:
-
keytool:可用于管理秘钥、证书、keystore文件等。
-
jarsigner:对jar文件进行签名或验证
常见攻击类型
中间人攻击(Man-in-the-middle attack)
顾名思义,就是攻击者在客户端与服务端之间实施攻击,让客户端以为攻击者是服务端,让服务端以为攻击者是客户端。
即使是HTTPS协议,也可能被中间人攻击。因为在连接未完整建立前,最初的通信不安全。
注入攻击
基本特征:攻击者将不可信的动态内容注入到程序中,并将其执行,改变原执行过程,产生恶意效果。
原则上,提供动态执行能力特性的语言,都需要预防注入攻击。
几种常见的注入攻击途径:
SQL注入攻击
典型场景:利用Web系统的用户登录功能,向服务端发送非法内容;
这些内容被服务端“误”拼接到SQL语句中,并被数据库执行。
常见应对方法:
-
校验用户输入。如,禁止提交有特殊字符的请求。
-
生成SQL时使用 PreparedStatement,而不是简单的字符串拼接。
-
数据库本身对不同的资源和操作使用不同权限控制,拦截恶意注入代码(如,恶意的删除代码)
操作系统命令注入
很多语言提供了执行操作系统命令的能力。如,Java中通过Runtime.exec(...)方法执行一段命令。
如果这段命令是来自攻击者的恶意命令,则可能产生恶意效果。
XML注入攻击
XML自身可以包含动态内容,如 XPath,如果使用不当,可能导致访问恶意内容。
其它
一些允许动态内容的协议,如 LDAP,可能被攻击者利用,通过特定命令,构造注入攻击。 动态页面中的XSS(Cross-site Scripting)攻击等。