博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【Java编码准则】の #02不要在client存储未加密的敏感信息
阅读量:4538 次
发布时间:2019-06-08

本文共 4101 字,大约阅读时间需要 13 分钟。

     当构建CS模式的应用程序时,在client側存储敏感信息(比如用户私要信息)可能导致非授权的信息泄漏。

     对于Web应用程序来说,最常见的泄漏问题是在client使用cookies存放server端获取的敏感信息。Cookies是由webserver创建的,它具有一个指定的有效时间,保存在client。当client连接上server端时,client使用cookies中存储的信息向server端进行认证,通过后server端返回敏感信息。

     在XSS攻击下,Cookies不能保证敏感信息的安全。不管是通过XSS攻击,还是直接对client的攻击,攻击者一旦获取到Cookies,他就能够使用这个Cookies从server端获取敏感信息。上面的风险存在时间窗,当Cookies存活超过指定的时间后(比如15分钟),server端会使会话无效,这时风险就不存在了。

     Cookies是一个短的字符串,假设它包括了敏感的信息,那么这段信息必须进行加密,敏感信息包括username,password,信用卡号码,社会安全码,以及其它不论什么个人标识信息。关于管理password的很多其它细节,參见“”。关于怎样保证内存中敏感信息安全的很多其它细节,參见“”。

[不符合安全要求的代码演示样例]

     以下的代码中,login servlet将username和password存储在Cookies中,用于兴许请求中标识用户。

protected void doPost(HttpServletRequest request, HttpServletResponse response) {				// validate input (omitted)				String username = request.getParameter("username");		char[] password = request.getParameter("password").toCharArray();		boolean rememberMe = Boolean.valueOf(request.getParameter("rememberme"));				LoginService loginService = new LoginServiceImpl();		if (rememberMe) {			if (request.getCookies()[0] != null &&					request.getCookies()[0].getValue() != null) {				String[] value = request.getCookies()[0].getValue().split(";");								if (!loginService.isUserValid(value[0], value[1].toCharArray())) {					// set error and return				} else {					// forward to welcome page				}			} else {				boolean validated = loginService.isUserValid(username, password);				if (validated) {					Cookie loginCookie = new Cookie("rememberme", username + ";" + new String(password));					response.addCookie(loginCookie);										// forword to welcome page				} else {					// set error and return				}			}		} else {			// no remember-me functionality selected			// process with regular authentication;			// if it fails set error and return		}		Array.fill(password, ' ');	}

     上面代码中实现“记住我”功能的方法不安全的,由于当攻击者能够訪问client电脑时,他能够直接获取这些敏感信息。上面代码同一时候违背了“#13使用散列函数来存储password”。

[符合安全要求的解决方式-会话]

     以下代码以一种安全的方式实现“记住我”功能,它将username和一个安全的随机字符串存储在Cookie中,同一时候使用HttpSession来保存会话状态。

protected void doPost(HttpServletRequest request, HttpServletResponse response) {				// validate input (omitted)				String username = request.getParameter("username");		char[] password = request.getParameter("password").toCharArray();		boolean rememberMe = Boolean.valueOf(request.getParameter("rememberme"));				LoginService loginService = new LoginServiceImpl();		boolean validated = false;		if (rememberMe) {			if (request.getCookies()[0] != null &&					request.getCookies()[0].getValue() != null) {				String[] value = request.getCookies()[0].getValue().split(";");								if (value.length != 2) {					// set error and return				}								if (!loginService.mappingExists(value[0], value[1])) {					// (username random) pair is checked					// set error and return				} else {					validated = loginService.isUserValid(username, password);					if (!validated) {						// set error and return					}				}								String newRandom = loginService.getRandomString();				// reset the random every time				loginService.mapUserForRememberMe(username, newRandom);				HttpSession session = reuqest.getSession();				session.invalidate();				session = request.getSession(true);								// set session timeout to 15 minutes				session.setMaxInactiveInterval(60*15);								// store user attribute and a random attribute in session scope				session.setAttribute("uset", loginService.getUsername());				Cookie loginCookie = new Cookie("rememberme", username + ";" + newRandom);				response.addCookie(loginCookie);								// forword to welcome page			}		} else {			// no remember-me functionality selected			// process with regular authentication;			// if it fails set error and return		}		Array.fill(password, ' ');	}

     server端保存username和安全随机字符串的映射关系,当用户选择“记住我”时,doPost()函数检查client提供的Cookies中是否包括有效的username和随机字符串映射对。假设映射对是正确的,server端通过该用户的认证,并使用户跳转到欢迎页。假设认证没有通过,server端返回错误给client。假设用户选择“记住我”,但客户度没有有效的Cookie导致认证失败,那么server端会要求用户使用认证信息又一次进行认证。假设认证成功,server端会提供一个包括新的“记住我”特性的Cookie给client。

     这个解决方式通过使当前会话无效并创建新的会话,能够避免固定会话攻击。同一时候通过将会话訪问有效时间设置为15分钟来将降低攻击者实施会话劫持攻击的时间窗长度。

——欢迎转载,请注明出处  ,未经本人允许请勿用于商业用途,谢谢——

转载于:https://www.cnblogs.com/zfyouxi/p/4484972.html

你可能感兴趣的文章
【Flex】读取本地XML,然后XML数据转成JSON数据
查看>>
字符串循环右移-c语言
查看>>
解决从pl/sql查看oracle的number(19)类型数据为科学计数法的有关问题
查看>>
古训《增广贤文》
查看>>
职场的真相——七句话
查看>>
xcode命令行编译时:codesign命令,抛出“User interaction is not allowed.”异常 的处理...
查看>>
[转载]开机出现A disk read error occurred错误
查看>>
STM32 C++编程 002 GPIO类
查看>>
ELK-Elasticsearch安装
查看>>
Django后台管理admin笔记
查看>>
JavaScript中的变量
查看>>
iptables基本原理和规则配置
查看>>
ArcGIS JS 学习笔记4 实现地图联动
查看>>
使用分层实现业务处理
查看>>
Microsoft Windows平台的NoSQL数据存储引擎
查看>>
Ubuntu系统Linux编译osg库
查看>>
Linux学习笔记 -- 系统目录结构
查看>>
[转载]ExtJs4 笔记(9) Ext.Panel 面板控件、 Ext.window.Window 窗口控件、 Ext.container.Viewport 布局控件...
查看>>
将数组排序组成最小的整数
查看>>
sqlserver学习--1(登陆,时间函数,查看表结构,查看建表语句,IDENTITY() 函数,查询表名称,查询表结构)...
查看>>