我今年近期的工作中作为系统架构师身份,对一个现有系统的框架从架构设计的伸缩性和安全性等方面进行了评估,发现了以下安全性问题。
它的现系统的ticket的生成是用以下代码生成的:
package com.xxx.sna.server.utils;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang.BooleanUtils;
public class TicketBuilder {
private static final String ENCRYPT_KEY = "!@$%6*He(8HJ79dsFGKD";
/**
* 取得随机密钥
*
* @return
*/
private static final String getEncryptKey() {
return ENCRYPT_KEY;
}
/**
* 生成Ticket
*
* @param account
* @return
*/
public static final String generateTicket(String account) {
return DigestUtils.md5Hex(account + getEncryptKey());
}
/**
* 匹配Ticket
*
* @return
*/
public static final boolean match(String account, String ticket) {
return generateTicket(account).equals(ticket);
}
public static void main(String[] args) {
// System.out.println(TicketBuilder.generateTicket("roymax"));
// System.out.println(TicketBuilder.match("roymax",
// generateTicket("roymax")));
System.out.println(BooleanUtils.toInteger(true));
System.out.println(BooleanUtils.toInteger(false));
}
}
大家有没发现什么问题呢?
下面是我发现问题后对此的相关对话记录:
Wooce 2009-03-09 18:31:12
我觉得SNA的cookie里没有跟具体会话有关的信息, 就是说,只要登录一次,这次登录的cookie完全可以用来伪造为下次登录使用?
XXX 2009-03-09 18:33:39
嗯,用到cookie是有一点安全隐患
Wooce 2009-03-09 18:35:26
只要cookie里是能保存每次登录都不同的session id, 那么,既能解决我下午所说的问题, 又能保证比较好的安全性, 对不对?
XXX 2009-03-09 18:37:23
我查一下代码,现在保存的sna_ticket值应该是每次登录都不同才对
Wooce 2009-03-09 18:38:25
不是啊。
public static final String generateTicket(String account) {
return DigestUtils.md5Hex(account + getEncryptKey());
}
Wooce 2009-03-09 18:38:56
getEnryptKey()又返回每次都一样的:
private static final String ENCRYPT_KEY = "!@$%6*He(8HJ79dsFGKD"
Wooce 2009-03-09 18:39:17
所以, sna_ticket值每次登录都会是一样的,:)
XXX 2009-03-09 18:39:17
嗯,知道了~~~~~~呵呵,这代码改过
XXX 2009-03-09 18:40:06
是的,只要每次登录的值不同就可以
Wooce 2009-03-09 18:43:43
+系统当前时间+user id+随机串,然后再加密, 就保证每次和每个用户都不同了, 就可以完全把sna_ticket当session id用了