【Java编码准则】の #02不要在client存储未加密的敏感信息
当构建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的很多其它细节,參见“#13使用散列函数来存储password”。关于怎样保证内存中敏感信息安全的很多其它细节,參见“#01限制内存中敏感数据的生命周期”。
[不符合安全要求的代码演示样例]
以下的代码中,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分钟来将降低攻击者实施会话劫持攻击的时间窗长度。
——欢迎转载,请注明出处 http://blog.csdn.net/asce1885 ,未经本人允许请勿用于商业用途,谢谢——
【Java编码准则】の #02不要在client存储未加密的敏感信息的更多相关文章
- 【Java编码准则】の #12不要使用不安全或者强度弱的加密算法
安全性要求高的应用程序必须避免使用不安全的或者强度弱的加密算法,现代计算机的计算能力使得攻击者通过暴力破解能够攻破强度弱的算法.比如,数据加密标准算法DES是极度不安全的,使用类似EFF(Electr ...
- 【Java编码准则】の #13使用散列函数保存password
明文保存password的程序在非常多方面easy造成password的泄漏.尽管用户输入的password一般时明文形式.可是应用程序必须保证password不是以明文形式存储的. 限制passwo ...
- 【Java编码准则】の #11不要使用Object.equals()来比較密钥值
java.lang.Object.equals()函数默认情况下是不能用来比較组合对象的,比如密钥值.非常多Key类没有覆写equals()函数,因此,组合对象的比較必须单独比較里面的各个类型以保证正 ...
- 【Java编码准则】の #01限制内存中敏感数据的生命周期
当竞争对手的应用程序与我们的应用程序执行在同一个系统上时,我们的应用程序在内存中的敏感数据是非常easy被竞争对手获取的.假设我们的应用程序符合以下几种情况之中的一个,那么竞争对手能够获取到我们应用的 ...
- idea安装 阿里巴巴Java编码准则插件
首先还是打开熟悉的idea 在marketplace 输入 alibaba 我这是已经安装过了 下载完成之后重启idea生效 如果需要那就手动的扫描 当然已经自动的扫描了 如果你的代码不符合阿里的标准 ...
- 【Android平台安全方案】の #00-请不要在外部存储(SD卡)加密存储的敏感信息
本文翻译自https://www.securecoding.cert.org/confluence/display/java/DRD00-J.+Do+not+store+sensitive+infor ...
- 015 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 09 Unicode编码
015 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 09 Unicode编码 本文知识点:Unicode编码以及字符如何表示? ASCII码是美国提出的标准信息 ...
- 013 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 07 基本数据类型变量的存储
013 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 07 基本数据类型变量的存储 变量和它的值如何在内存中进行存储的? 前面学习过:Java中的数据类型分为基本 ...
- 017 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 11 变量综合案例
017 01 Android 零基础入门 01 Java基础语法 02 Java常量与变量 11 变量综合案例 本文知识点:变量 相同类型的变量可以一次同时定义多个 例:可以一行代码同时定义2个变量x ...
随机推荐
- 2010多校第一题 hdu3440House Man 差分约束系统
给我们n座房子,房子的高度各不相同, 从最低的房子开始, 每次跳到更高的房子, 跳n-1次最能跳到最高的房子了,但是每次跳跃的距离不能超过d 将这些房子在一维的方向上重新摆放(但是保持输入时的相对位置 ...
- 从PCI上读取数据 线程和定时器效率
从PCI上读取数据 线程和定时器效率 线程: mythread=AfxBeginThread(StartContinuous,(LPVOID)1,THREAD_PRIORITY_NORMAL,0,CR ...
- Vb.net/VB 声明API功能父窗口功能
回想第一次敲房费,他说自己是api函数实现父窗口及其子窗口最小化的功能.现在再次遇到,自己就在思考,能不能继续使用API函数呢?答案当然是Of Course! 事实上细致看两者并没有多大的差别,先看看 ...
- ORA-00020的思考
今天,历史的图书馆例行检查DB,发现alert.log有一"ORA-00020: maximum number of processes (150) exceeded",这是一个常 ...
- 深度分析 Java 的 ClassLoader 机制(源码级别)(转)
写在前面:Java中的所有类,必须被装载到jvm中才能运行,这个装载工作是由jvm中的类装载器完成的,类装载器所做的工作实质是把类文件从硬盘读取到内存中,JVM在加载类的时候,都是通过ClassLoa ...
- Silverlight之 xaml布局
目标:在两周内完成一个界面的功能 第1阶段:完成xaml的布局 准备:视频4-14节 第2阶段: 完成环状图 柱状图 TreeView样式 准备: 矢量绘图 telerik 自定义控件 自定义控件 ...
- improper Advertising identifier [IDFA] Usage. Your app contains the Advertising Identifier [IDFA] AP
找到答案了.随便传个包上去.然后拒绝掉,又一次prepare to upload.就会出现选项. 相应选择就好了.
- lsb_release: command not found 解决方法(转)
问题:通过lsb_release -a 是查看linux系统版本时报错,具体的解决办法如下: [root@localhost ~]# lsb_release -a-bash: lsb_release: ...
- 联想A798T刷机包 基于百度云V6 集成RE3.1.7美化版 精简冗余文件
ROM介绍 1.apk进行odex合并及zipaliang优化-省电及降低内存暂用. 2.測试相机.通话.数据.wifi.蓝牙.等传感器均正常,. 3.提供时间居中防iphone状态栏补丁 4.增加I ...
- (转)mvn clean install 与 mvn install 的区别(为啥用clean)
之前写代码的过程中曾经遇到过问题,用mvn install后,新改的内容不生效,一定要后来使用mvn clean install 才生效,由于之前没有做记录,以及记不清是什么情况下才会出现的问题,于是 ...