程序员必备基础:10种常见安全漏洞浅析
前言
我们日常开发中,很多小伙伴容易忽视安全漏洞问题,认为只要正常实现业务逻辑就可以了。其实,安全性才是最重要的。本文将跟大家一起学习常见的安全漏洞问题,希望对大家有帮助哈。如果本文有什么错误的话,希望大家提出哈,感谢感谢~
1. SQL 注入
1.1 什么是SQL注入?
SQL注入是一种代码注入技术,一般被应用于攻击web应用程序。它通过在web应用接口传入一些特殊参数字符,来欺骗应用服务器,执行恶意的SQL命令,以达到非法获取系统信息的目的。它目前是黑客对数据库进行攻击的最常用手段之一。
1.2 SQL注入是如何攻击的?
举个常见的业务场景:在web表单搜索框输入员工名字,然后后台查询出对应名字的员工。
这种场景下,一般都是前端页面把一个名字参数name传到后台,然后后台通过SQL把结果查询出来
name = "AA"; //前端传过来的
SQL= "select * from staff where name=" + name; //根据前端传过来的name参数,查询数据库员工表staff
因为SQL是直接拼接的,如果我们完全信任前端传的参数的话。假如前端传这么一个参数时'' or '1'='1'
,SQL就变成酱紫的啦。
select * from staff where name='' or '1'='1';
这个SQL会把所有的员工信息全都查出来了,酱紫请求用户已经越权啦。请求者可以获取所有员工的信息,其他用户信息已经暴露了啦。
1.3 如何预防SQL注入问题
1.3.1 使用#{}而不是${}
在MyBatis中,使用#{}
而不是${}
,可以很大程度防止sql注入。
因为
#{}
是一个参数占位符,对于字符串类型,会自动加上"",其他类型不加。由于Mybatis采用预编译,其后的参数不会再进行SQL编译,所以一定程度上防止SQL注入。${}
是一个简单的字符串替换,字符串是什么,就会解析成什么,存在SQL注入风险
”
1.3.2 不要暴露一些不必要的日志或者安全信息,比如避免直接响应一些sql异常信息。
如果SQL发生异常了,不要把这些信息暴露响应给用户,可以自定义异常进行响应
1.3.3 不相信任何外部输入参数,过滤参数中含有的一些数据库关键词关键词
可以加个参数校验过滤的方法,过滤union,or
等数据库关键词
1.3.4 适当的权限控制
在你查询信息时,先校验下当前用户是否有这个权限。比如说,实现代码的时候,可以让用户多传一个企业Id什么的,或者获取当前用户的session信息等,在查询前,先校验一下当前用户是否是这个企业下的等等,是的话才有这个查询员工的权限。
2. JSON反序列化漏洞——如Fastjson安全漏洞
2.1 什么是JSON序列化,JSON发序列化
序列化:把对象转换为字节序列的过程
反序列:把字节序列恢复为Java对象的过程
Json序列化就是将对象转换成Json格式的字符串,JSON反序列化就是Json串转换成对象
2.2 JSON 反序列化漏洞是如何被攻击?
不安全的反序列化可以导致远程代码执行、重放攻击、注入攻击或特权升级攻击。之前Fastjson频繁爆出安全漏洞,我们现在分析fastjson 1.2.24版本的一个反序列化漏洞吧,这个漏洞比较常见的利用手法就是通过jndi注入的方式实现RCE。
我们先来看fastjson一个反序列化的简单例子:
public class User {
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
System.out.println("调用了name方法");
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
System.out.println("调用了age方法");
this.age = age;
}
public static void main(String[] args) {
String str = "{\"@type\":\"cn.eovie.bean.User\",\"age\":26,\"name\":\"捡田螺的小男孩\"}";
User user = JSON.parseObject(str,User.class);
}
}
运行结果:
调用了age方法
调用了name方法
加了@type
属性就能调用对应对象的setXXX
方法,而@type
表示指定反序列化成某个类。如果我们能够找到一个类,而这个类的某个setXXX
方法中通过我们的精心构造能够完成命令执行,即可达到攻击的目的啦。
public void setDataSourceName(String var1) throws SQLException {
if (this.getDataSourceName() != null) {
if (!this.getDataSourceName().equals(var1)) {
super.setDataSourceName(var1);
this.conn = null;
this.ps = null;
this.rs = null;
}
} else {
super.setDataSourceName(var1);
}
}
public void setAutoCommit(boolean var1) throws SQLException {
if (this.conn != null) {
this.conn.setAutoCommit(var1);
} else {
this.conn = this.connect();
this.conn.setAutoCommit(var1);
}
}
private Connection connect() throws SQLException {
if (this.conn != null) {
return this.conn;
} else if (this.getDataSourceName() != null) {
try {
InitialContext var1 = new InitialContext();
DataSource var2 = (DataSource)var1.lookup(this.getDataSourceName());
return this.getUsername() != null && !this.getUsername().equals("") ? var2.getConnection(this.getUsername(), this.getPassword()) : var2.getConnection();
} catch (NamingException var3) {
throw new SQLException(this.resBundle.handleGetObject("jdbcrowsetimpl.connect").toString());
}
} else {
return this.getUrl() != null ? DriverManager.getConnection(this.getUrl(), this.getUsername(), this.getPassword()) : null;
}
}
setDataSourceName
简单设置了设置了dataSourceName的值,setAutoCommit
中有connect操作,connect方法中有典型的jndi的lookup
方法调用,参数刚好就是在setDataSourceName
中设置的dataSourceName。public class FastjsonTest {
public static void main(String[] argv){
testJdbcRowSetImpl();
}
public static void testJdbcRowSetImpl(){
//JDK 8u121以后版本需要设置改系统变量
System.setProperty("com.sun.jndi.rmi.object.trustURLCodebase", "true");
//RMI
String payload2 = "{\"@type\":\"com.sun.rowset.JdbcRowSetImpl\",\"dataSourceName\":\"rmi://localhost:1099/Exploit\"," +
" \"autoCommit\":true}";
JSONObject.parseObject(payload2);
}
}
如何解决json反序列化漏洞问题
可以升级版本,比如fastjson后面版本,增强AutoType打开时的安全性 fastjson,增加了AutoType黑名单等等,都是为了应对这些安全漏洞。 反序列化有fastjson、gson、jackson等等类型,可以替换其他类型。 升级+打开safemode
3. XSS 攻击
3.1 什么是XSS?
3.2 XSS是如何攻击的?
<input type="text" name="name" />
<input type="submit" value="搜索" onclick="http://127.0.0.1/search?name=">
</body>
用户输入搜索信息,点击搜索按钮,就是到达正常服务器的。如果黑客在url后面的参数中加入如下的恶意攻击代码。
http://127.0.0.1/search?keyword="<a href ="http://www.baidu.com"><script>alert('XSS');</script></a>
当用户打开带有恶意代码的URL的时候,正常服务器会解析出请求参数 name,得到"",拼接到 HTML 中返回给浏览器。形成了如下的 HTML: 用户浏览器接收到响应后执行解析,其中的恶意代码也会被执行到。
3.3 如何解决XSS攻击问题
不相信用户的输入,对输入进行过滤,过滤标签等,只允许合法值。 HTML 转义 对于链接跳转,如 <a href="xxx"
等,要校验内容,禁止以script开头的非法链接。限制输入长度等等
4. CSRF 攻击
4.1 什么是CSRF 攻击?
4.2 CSRF是如何攻击的呢?
Tom 登陆银行,没有退出,浏览器包含了Tom在银行的身份认证信息。 黑客Jerry将伪造的转账请求,包含在在帖子 Tom在银行网站保持登陆的情况下,浏览帖子 将伪造的转账请求连同身份认证信息,发送到银行网站 银行网站看到身份认证信息,以为就是Tom的合法操作,最后造成Tom资金损失。
4.3 如何解决CSRF攻击
检查Referer字段。HTTP头中有一个Referer字段,这个字段用以标明请求来源于哪个地址。 添加校验token。
5. 文件上传下载漏洞
5.1 文件上传漏洞
限制服务器相关文件目录的权限 校验上传的文件,如后缀名 禁止上传恶意代码的文件 尽量禁止使用前端上传的文件名
5.2 文件下载漏洞
6. 敏感数据泄露
7. XXE 漏洞
7.1 什么是XXE
7.2 XXE三种攻击场景
场景1. 攻击者尝试从服务端提取数据
<?xml version="1.0"?>
<!DOCTYPE foo [
<!ELEMENT foo (#ANY)>
<!ENTITY file SYSTEM "file:///etc/passwd">]>
]>
<foo>&xxe;</foo>
场景2. 攻击者通过将上面的实体行更改为一下内容来探测服务器的专用网络
<!ENTITY xxe SYSTEM "https://192.168.1.1/private">]>
场景3. 攻击者通过恶意文件执行拒绝服务攻击
<!ENTITY xxe SYSTEM "file:///dev/random">]>
7.3 如何防御XXE
使用开发语言提供的禁用外部实体的方法 过滤用户提交的XML数据,过滤<!DOCTYPE和<!ENTITY等关键词。
8. DDoS 攻击
8.1 什么是DDos攻击
8.2 如何应对 DDoS 攻击?
高防服务器,即能独立硬防御 50Gbps 以上的服务器,能够帮助网站拒绝服务攻击,定期扫描网络主节点等 黑名单 DDoS 清洗 CDN 加速
9. 框架或应用漏洞
Struts 框架漏洞:远程命令执行漏洞和开放重定向漏洞 QQ Browser 9.6:API 权限控制问题导致泄露隐私模式 Oracle GlassFish Server:REST CSRF WebLogic: 未授权命令执行漏洞 Hacking Docker:Registry API 未授权访问 WordPress 4.7 / 4.7.1:REST API 内容注入漏洞
10. 弱口令、证书有效性验证、内部接口在公网暴露、未鉴权等权限相关漏洞
10.1 弱口令
空口令 口令长度小于8 口令不应该为连续的某个字符(QQQQQQ) 账号密码相同(例:root:root) 口令与账号相反(例:root:toor) 口令纯数字(例:112312324234, 电话号) 口令纯字母(例:asdjfhask) 口令已数字代替字母(例:hello word, hell0 w0rd) 口令采用连续性组合(例:123456,abcdef,654321,fedcba) 服务/设备默认出厂口令
10.2 证书有效性验证漏洞
如果是客户生成的证书,需要跟系统可信根CA形成信任链,不能为了解决ssl证书报错的问题,选择在客户端代码中信任客户端中所有证书的方式。 证书快过期时,需要提前更换。
10.3 未鉴权等权限相关漏洞
参考与感谢
【入坑JAVA安全】fastjson中的jndi注入 Web渗透之文件上传漏洞总结 XXE漏洞利用技巧:从XML到远程代码执行 WEB应用常见15种安全漏洞一览 什么是 DDoS 攻击? 弱口令总结(什么是弱口令)
有道无术,术可成;有术无道,止于术
欢迎大家关注Java之道公众号
好文章,我在看❤️