目前公司多个项目需要进行安全整改,因为客户在交付之前要求进行等保测试,现在尤其是政府单位或是国企在安全上的要求越来越高了,可能也是这些单位一旦被攻击,后果可能比较严重,所以要求都比较严格,等保测试一般分为黑盒测试和白盒测试,黑盒测试一般为安全扫描,功能测试,功能测试这里就不说了,而白盒测试则为静态代码扫描。
安全扫描
安全扫描常见问题
tomcat
默认配置- 泄露
tomcat
默认配置页面 - 泄露
tomcat
版本信息- 非正常手段占据
tomcat
资源
- 非正常手段占据
session
长时间未失效- 关闭不安全的
http
方法
- 关闭不安全的
refers
未校验- 会话标识未刷新
XSS
注入SQL
注入- 敏感信息未加密
- 请求头缺失问题
- 文件上传漏洞
如何处理这些问题
以上问题主要可以分为三类问题,这三类问题主要是
web
服务器安全漏洞(不同的平台有各自的漏洞,IIS
、apache
、weblogic
、tomcat
)- 会话漏洞
- 注入漏洞
- 接口安全
如何处理web服务器安全漏洞
这里主要针对tomcat
进行处理,目前最简单的做法就是 删 ,删除tomcat\webapps
下的所有文件夹,很多的安全扫描软件,会针对市面上主流的web
服务器做一些深入的测试,所以将这些非必须的文件删除掉比较好,可以省去很多问题,用AppScan
扫一下会发现少了很多问题。
在http
请求中会泄露服务器的版本信息,某些特定版本的服务器有些固定的漏洞,所以最好将服务器版本升级到最新的安全版本,或者隐藏服务器的版本信息。
tomcat
配置文件中默认的请求时长为20000毫秒,这样的请求时长还是比较长的,通过一些特定的请求方式(低网速环境下请求),在tomcat
连接数量固定的前提下,同时发起大量的长连接,会导致tomcat
连接资源被迅速耗尽,通过修改请求时长可以解决这个问题。
如何处理会话漏洞
会话漏洞,主要通过非常规手段获取会话标识,通过会话标识模拟登陆,从而实现登陆,目前主流的会话状态保持方式有通过session
、token
的方式,session
的方式更为常见,因为使用简单方便,关于session
的问题主要为session
过期问题和session
会话凭据问题:
-
session长时间未过期
可以通过配置
tomcat
设置session过期时间,也可以在代码中创建session
时指定session
的失效时间。 -
session会话凭据未刷新
可以通过拦截器或是
filter
强制刷新会话标识。
如何处理注入漏洞
注入漏洞存在很久,随着项目的依赖的变化,注入的内容也可能发生变化,所以这里推荐使用黑名单的方式处理特定的注入字符串,但是可能会导致一些正常的接口发生异常。
关于注入问题,都是通过拦截器或是过滤器的方式统一对所有的请求进行过滤,将黑名单的中的非法字符串过滤掉。
如何处理接口安全
永远不要相信客户端提交的数据,我们只应相信服务器端的数据,所有提交至后端的数据都应该进行校验,而不是直接使用。
如何防止自己的接口被滥用,比如自己的接口被别人盗用了,通过校验refer
可以判断是否被盗用,在拦截器中进行校验。
如何加密敏感信息,这里推荐使用AES
对敏感信息进行加密,其实网页端对敏感信息加密的作用不大,应为秘钥肯定是要写在HTML当中的,第三方可以通过抓包获取到敏感信息,那么从网页中提取出AES
秘钥应该也没什么问题,但是对于客户端应该是有作用的。
对于文件上传部分需要特别注意:
- 需要限定可上传文件的类型,不要通过后缀名进行简单判断;
- 需要限定上传文件可保存的目录,防止服务器文件目录被恶意遍历;
- 需要限定上传接口的权限,防止恶意上传大文件。
静态代码扫描
静态代码扫描常见问题
- 变量命名方式(命名方式及是否占用敏感词)
- if判断不要省略括号
- 文件或流操作要添加异常处理
- try catch 中需要具体化异常类型
- 部分静态代码扫描工具会对代码中出现的特定敏感单词报错(比如
pwd
、password
)
生产事故
for循环中调用DAO层
当时的情况是系统偶发性的数据库服务器CPU飙升到100%,而且会经久不衰,数据库服务器重启后还会迅速飙升到100%,导致这个问题的原因有2个,一个是频繁的创建数据库连接,耗尽数据库资源,导致数据库服务器CPU飙升到100%,而
service
滥用事务又导致了数据库中积累了大量未执行完的事务,导致重启后CPU又快速飙升到100%。
事故简介,一个主表有时候需要关联多条子表数据,最常见的是订单主表与订单字表,以及关联用户信息表,大致数据结构可以分为以下:
class User {
String userid;
String username;
}
class Detail {
String orderid;
String detailid;
String prdid;
String prdname;
int prdnum;
}
class Order {
String orderid;
String userid;
Date createdate;
int orderstatus;
String orderstatusname;
User user;
List<Detail> details;
}
面对这样的数据结构,如果需要导出1000条订单的详细信息,获取主表信息会非常的简单,直接就可以获取了,但是订单用户详细信息及订单字表信息该如何获取呢?如果通过for
循环获取,会导致一系列的问题,其实如果一切交给交给spring
应该也没什么问题,但是如果你是手动管理数据库session的话,则会导致频繁的创建和销毁session,而且项目整体没有对连接数量做出限制。
这样的问题该如何解决呢?最简单的方法可能是交给spring
来管理,spring
的作用就是管理你的代码的下限,但是频繁的调用也有可能导致问题,目前解决这个问题的方式我想出了2个思路:
- 创建视图,在视图中整理出你需要的数据结果;
- 通过
mybatis
关联查询,这个相对来说可能会好一点。
事务的不正确使用
目前接触到的项目中的关于事务的操作方法主要有2中,一种是通过session手动控制,在代码发生异常时,统一回滚,或者使用spring提供的transestional 注解进行自动回滚,首先我们要知道我们为什么使用事务,使用事务主要是为了业务的原子性,比如说在销售的时候,订单需要与商品库存保持一致,这就要求,只有在订单保存成功的前提下库存数量才能变化,那么那些操作需要使用到事务呢?
事务一般使用在一个业务需要修改多张表数据时,各个表的数据修改之间存在一定的关系,所以不要在查询业务中使用事务,滥用事务,会消耗数据库服务器的CPU资源。
敏感接口未添加校验
这个事故可以算是被入侵了,用户通过跨域请求短信发送接口,将系统中的短信接口作为一个短信群发接口。
其实这个问题已经被各个应用广泛的处理了,那就是添加图形验证码,进行防刷操作。
linux常见命令要学会
这次事故,教育我要好好的悬系linux
命令,简单的说一下,就是应用服务器磁盘已满导致的nginx
无法显示图片。
最后安利下自己的小程序,一款程序员刷题小程序。