互联网金融产品实战——安全开发篇
说到安全开发,总绕不开两个词:OWASP(Open Web Application Security Project)和CWE(Common Weakness Enumeration),针对其中的某些关键点再结合自身业务的特点,逐个作出应对。
(看不清时,点击查看大图)
下文针对某些点,并结合之前的项目经历,简单列出几个解决方法供大家参考。
一、CSRF跨站请求伪造过滤器,杜绝不信任的站点非法请求服务。一些图片防盗链的网站采用类似Refer机制完成的。
@Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
String sourceRefer = req.getHeader("Referer");
//允许配置多个可信赖Referer,存储在资源文件中
String allowRefers = bundle.getString("CSRF.NORMAL.REFERER");
List<String> urlList = new ArrayList<String>();
if (StringUtil.isNotEmpty(allowRefers)) {
String[] refers = allowRefers.split("#");
if (ArrayUtils.isNotEmpty(refers)) {
for (int i = 0; i < refers.length; i++) {
String string = refers[i];
urlList.add(string);
}
}
}
if (StringUtil.isNotBlank(sourceRefer)) {
//将http or https等协议头 过滤掉,形如http://www.baidu.com
String[] srcRef = sourceRefer.trim().split("//");
if (ArrayUtils.isNotEmpty(srcRef)) {
//非正式环境下,有端口配置,再重新分隔,形如http://test.backkom.com:8080/ofs
String[] srcRefer = srcRef[1].split(":");
if (srcRefer.length == 1) {
//正式环境下,均是域名,形如http://www.web2.0bk.com/news/12123.html
String[] srcReferSplit = srcRefer[0].split("/");
if (!urlList.contains(srcReferSplit[0])) {
logger.info("UnReliable referer :" + srcReferSplit[0]);
//不信任时不作任何展示,直接跳转至500页面,前端js拿到此响应码,跳转到500页面
resp.setStatus(500);
String redirectUrl = bundle.getString("CSRF.REDIRECT.URL");
resp.setHeader("Location", redirectUrl);
} else {
chain.doFilter(req, resp);
}
} else {
if (!urlList.contains(srcRefer[0])) {
logger.info("UnReliable referer :" + srcRefer[0]);
//不信任时不作任何展示,直接跳转至500页面,前端js拿到此响应码,跳转到500页面
resp.setStatus(500);
String redirectUrl = bundle.getString("CSRF.REDIRECT.URL");
resp.setHeader("Location", redirectUrl);
} else {
chain.doFilter(req, resp);
}
}
} else {
chain.doFilter(req, resp);
}
} else {
chain.doFilter(req, resp);
}
}
二、Session超时过滤器,过滤请求,判断请求是否失效,失效后直接退出要求再次登陆
@Override
public void init(FilterConfig filterConfig) throws ServletException {
String countStr = bundle.getString("filter.url.count");
int urlCnts = Integer.valueOf(countStr);
String tempStr = "filter.url";
StringBuffer urlPre = new StringBuffer();
for (int i = 0; i < urlCnts; i++) {
String filterUrl = bundle.getString(urlPre.append(tempStr).append(i).toString());
if (StringUtils.isNotEmpty(filterUrl)) {
urlList.add(filterUrl);
}
urlPre.setLength(0);
}
// 初始化需要拦截的文件夹
String include = filterConfig.getInitParameter("include");
if (include != null) {
StringTokenizer st = new StringTokenizer(include, ",");
list.clear();
while (st.hasMoreTokens()) {
list.add(st.nextToken());
}
}
}
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest req = (HttpServletRequest) request;
HttpServletResponse resp = (HttpServletResponse) response;
//不含参数的路径
String servletPath = req.getServletPath();
StringBuilder jsStr = new StringBuilder("");
StringBuilder sb = new StringBuilder();
Date d = new Date();
String ts = String.valueOf(d.getTime());
sb.append(bundle.getString("tomcat.admin.login.url")).append(EztpfpConstants.LOGIN_ADMIN_URL).append(bundle.getString("tomcat.admin.url")).append("?ts=").append(ts);
//当用户没有登录时,需要跳转到的登陆链接
String adminLoginReturnUrl = sb.toString();
String adminJumpUrl = null;
if (StringUtils.isNotEmpty(adminLoginReturnUrl)) {
adminJumpUrl = jsStr.append(adminLoginReturnUrl).toString();
}
//获取用户信息,判断用户是否登录
UserInfoBean userInfoBean = (UserInfoBean) getSession().getAttribute("online.user")
//是否是ajax请求
String xRequested = req.getHeader("X-Requested-With");
if (userInfoBean == null) {
//至过滤*.action,*.html的链接
if ((servletPath.contains(".action") || servletPath.contains(".html")) && !urlList.contains(servletPath)) {
logger.info(FunIMsgFormat.MsgStyle.DEFAULT_LOG
.getFormat(EztpfpConstants.LOGGER_TXT_MONITOR),
new Object[] { "", "doFilter", "进入session过滤器拦截路径!", new Date() });
//如果是ajax请求,返回给前台
if ("XMLHttpRequest".equals(xRequested)) {
setJsonResponse(resp, adminLoginReturnUrl);
} else {
//不是ajax请求,直接跳转登陆页面,由JS处理跳转功能
req.setAttribute("msg", "您还没有登录或登录已超时,请重新登录!");
resp.sendRedirect(adminJumpUrl);
}
} else {
chain.doFilter(req, resp);
}
} else {
chain.doFilter(req, resp);
}
}
private void setJsonResponse(HttpServletResponse res, String redirectUrl) throws IOException {
res.setStatus(800);
res.setHeader("Location", redirectUrl);
}
}
三、关键交易防重技术
(看不清时,点击查看大图)
四、XSS过滤器
可以利用OWASP的一个开源项目:AntiSamy,来解决XSS攻击问题。AntiSamy是可以确保前端输入的HTML、CSS、JavaScript符合规范的API。确保用户无法在HTML中提交恶意代码,而这些恶意代码通常被输入到个人资料、评论等会被服务端存储的数据中,以造成服务的不友好或者破坏正常服务。项目地址:https://code.google.com/archive/p/owaspantisamy/downloads,扩展阅读可网络中查找相关资料。
另MyBatis中已经实现了对SQL的预编译,但针对${xxx}参数的情况需要着重关注,因为存在SQL注入的可能性。
五、校验再校验
特别针对后台权限开发时,以往的做法是这样的:根据登陆用户的不同,找到其对应的菜单展现出来,这样权限就控制住了。这种做法存在一种隐患,如果此用户通过其它渠道得到某个功能的访问链接地址,直接在URL中输入此链接来操作对应的功能,那么权限控制就无从谈起。
针对此种情况,可适当增加权限再校验的步骤,根据提交过来的请求,再次校验权限是否足够,可通过拦截器实现。
其它安全注意项,还很多,这里不一一展开了,可在项目中实际摸索,找出合适的解决方案。
乾坤大挪移--->:
余额理财产品—开发实战
互联网金融产品实战——备战篇
互联网金融产品实战——设计篇
互联网金融产品实战——开发篇
歪脖贰点零 ∣一个有逼格的WEB2.0
长按,识别二维码,加关注
互联网金融产品实战——安全开发篇相关推荐
- .NET Core实战项目之CMS 第十四章 开发篇-防止跨站请求伪造(XSRF/CSRF)攻击处理...
通过 ASP.NET Core,开发者可轻松配置和管理其应用的安全性. ASP.NET Core 中包含管理身份验证.授权.数据保护.SSL 强制.应用机密.请求防伪保护及 CORS 管理等等安全方面 ...
- .NET Core实战项目之CMS 第十三章 开发篇-在MVC项目结构介绍及应用第三方UI
作为后端开发的我来说,前端表示真心玩不转,你如果让我微调一个位置的样式的话还行,但是让我写一个很漂亮的后台的话,真心做不到,所以我一般会选择套用一些开源UI模板来进行系统UI的设计.那如何套用呢?今天 ...
- .NET Core实战项目之CMS 第十一章 开发篇-数据库生成及实体代码生成器开发
上篇给大家从零开始搭建了一个我们的ASP.NET Core CMS系统的开发框架,具体为什么那样设计我也已经在第十篇文章中进行了说明.不过文章发布后很多人都说了这样的分层不是很合理,什么数据库实体应该 ...
- 探秘互联网金融产品开发的技术路线图
探秘互联网金融产品开发的技术路线图 发表于2015-12-29 11:16| 1494次阅读| 来源CSDN| 2 条评论| 作者蒲婧 CTO俱乐部CTOCTO讲堂互联网金融Fintech云信 wid ...
- 名师讲坛——Java Web开发实战经典基础篇(JSP、Servlet、Struts、Ajax)
[书名]<名师讲坛--Java Web开发实战经典基础篇(JSP.Servlet.Struts.Ajax)> [作者]李兴华.王月清 [ISBN]9787302231585 }:YKf: ...
- 名师讲坛—Java Web开发实战经典基础篇(JSP、Servlet、Struts、Ajax)
名师讲坛-Java Web开发实战经典基础篇(JSP.Servlet.Struts.Ajax) 基本信息 作者: 李兴华 王月清 出版社:清华大学出版社 ISBN:9787302231585 ...
- 陈华编程学院 | Laravel5.6模块化实战项目开发之公共模块篇(99元)
Laravel5.6模块化实战项目开发系列课程之公共模块篇,共47课时/13时57分.本课以Laravel5.6为开发框架,系统讲解Laravel5框架的安装和配置.后台框架结构布局.用户管理模块.网 ...
- 微前端框架qiankun项目实战(一)--本地开发篇
❝ 作者:黑化程序员 https://juejin.cn/post/6970310177517993998 ❞ 大家好,我是小黑. 公司使用技术栈是vue,最近遇到了一个需求,要把原有后台管理系统的功 ...
- 视频教程-Angular+Django前后端分离实战项目开发教程-AngularJS
Angular+Django前后端分离实战项目开发教程 胜蓝博创(韬略课堂)创始人,IT培训讲师,先后在蓝港在线,热酷,乐元素等大型游戏公司任职,参与过多款大型网游.手游的设计和开发,精通页游.手游前 ...
最新文章
- 2020年春天故事之巧遇史上最奇葩SAP用户
- cocoapods 终极方案
- mxnet 常用层,卷积激活损失
- python课程是学什么的-学习Python课程有什么好的学习方法吗?老男孩IT教育
- spring boot进行上传文件
- Sql Server 从日志中恢复误删除或误Update的数据
- 《敏捷无敌》试读:第5章 成长的烦恼
- java筛选excel数据_Excel中的筛选技巧有哪些,总结四种筛选技巧分享给大家
- 孔子做人精要,看完启发很多
- RAC知识更新之-RAC节点删除添加服务+维护RAC ocr表(摘自文平书)
- C#获取标准北京时间
- mysql修改游戏数据_Sqlite3 数据库工具修改游戏数据库文件图文教程
- 基于yolov5+deepsort的智能售货机商品目标检测种类识别计数
- 探究 LightHouse 工作流程
- 云计算平台为什么是必需的
- PowerBI-时间智能函数-DATEADD
- Servlet的使用(2198)
- 腾讯通服务器删除离线消息,如何撤回RTX离线消息离线文件.docx
- 你有一条微信未发送_微信支持发送大文件;男子薅90年爱奇艺VIP;京东方再次未通过苹果质量审查...
- vue scroll 监听,点击按钮自动滚动到相应的信息展示
热门文章
- matlab绘制系统的根轨迹
- 读书笔记, Python - python-tricks-buffet-awesome-features
- python之函数用法isupper()
- 矩阵宏观调度:Zigzag扫描打印矩阵matrix,图像工程的一种编码
- 切片(Slice)在python中的运用(:)
- ccc-sklearn-13-朴素贝叶斯(1)
- hibernate一对多向数据库保存数据失败问题解决
- 电脑远程桌面连接不上应该如何解决
- Dubbo-02 20190315
- EasyUI(2):PHP+EasyUI的增、删、改操作的完整示例