专栏链接

一、数据的校验

  1. SQL注入
  2. 命令注入
  3. 跨站脚本
  4. 任意文件上传
  5. 任意文件下载
  6. 任意文件删除
  7. 任意文件读取与写入
  8. Iframe 框架钓鱼
  9. 负值支付漏洞

二、认证与授权

  1. 密码修改(无需原密码)
  2. 密码策略不足
  3. 用户名密码(敏感信息)明文传输
  4. 验证码可重复利用
  5. 缺少验证码功能
  6. 用户名枚举(用户名和密码单独验证)
  7. 登录尝试次数限制功能失效
  8. 登录后门
  9. 横向越权
  10. 纵向越权

三、Cookie与会话管理

  1. 直接关闭浏览器“退出“系统
  2. 会话标识未更新
  3. Cookie 中明文存储用户名、密码

四、错误处理

  1. 数据库交互中的异常处理

五、日志安全

  1. 日志记录敏感信息

六、未验证的重定向

  1. URL 重定向

认证与授权:用户名枚举(用户名和密码单独验证)

漏洞描述:

为了给客户更好的体验,在用户登录的时候,通常会先去后台查询一下该用户名是否存在,然后将消息及时反馈给操作者。虽然在客户的体验上加了分,但攻击者利用此问题可先爆破用户名,然后再爆破密码。

检测方法:

检查在不登录的情况下也能通过某个功能验证用户名是否存在。

检查登录过程中是否存在异步验证用户名的操作。

不合规的代码示例:

public String checkAccess(String userId, String password, String ip) {
	//取 用 户 资 料
	UserInfo user = null;
	try {
		user = this.getUserById(userId);
	} catch (DataAccessException ex) {
		logger.warn("获取用户失败", ex);
	}
	if (user == null) {
	 return "无法获取用户或用户不存在,连接用户 ID:" + userId; }
	// 校验密码
	if (!user.getPassword().equals(password)) {
	  return "密码错误,连接用户 ID:" + userId;
	 }
	// 校验
	IP String allowIp = user.getAllowIp();
		if (allowIp.equals("*")) {
		// *号表示匹配任意 IP
		return "";
	}
	else { String[] patterns = allowIp.split(";");
	for (int i = 0; i < patterns.length; i++) {
		if (checkIp(ip, patterns[i])) { return ""; }}
	}
	return "非法的 IP 地址,IP:" + ip; 
}

不合规说明:

在登录验证用户时,首先单独去验证用户名存不存在,然后验证密码是否正确。攻击者利用此问题可先爆破用户名,然后再爆破密码。

合规的代码示例:

public String checkAccess(String userId, String
password, String ip) {
	// 验证用户资料
	UserInfo user = null;
	try {
		user = this.getUserById(userId, password);
	} catch (DataAccessException ex) {
		logger.warn("获取用户失败", ex);
	}
	if (user == null) {
		return "用户名或密码不正确,请重新输入";
	}
	// 校验 IP
	String allowIp = user.getAllowIp();
	if (allowIp.equals("*")) {
		// *号表示匹配任意 IP
		return "";
	} else {
		String[] patterns = allowIp.split(";");
		for (int i = 0; i < patterns.length; i++) {
			if (checkIp(ip, patterns[i])) {
				return "";
			}
		}
	}
	return "非法的 IP 地址,IP:" + ip;
}

合规说明:

程序对用户名和密码进行同步校验,可增大攻击者的爆破困难度。

Logo

汇聚全球AI编程工具,助力开发者即刻编程。

更多推荐