1.Reflected_XSS_All_Clients
反射跨站,来自用户的数据直接输出到客户端。
解决方案
使用下列跨站修复函数处理输出到客户端的数据字符串。
public static String filter(String value) {
if (value == null) {
return null;
} else {
char[] content = new char[value.length()];
value.getChars(0, value.length(), content, 0);
StringBuffer result = new StringBuffer(content.length + 50);
for(int i = 0; i < content.length; ++i) {
switch(content[i]) {
case '"':
result.append(""");
break;
case '&':
result.append("&");
break;
case '\'':
result.append("'");
break;
case '<':
result.append("<");
break;
case '>':
result.append(">");
break;
default:
result.append(content[i]);
}
}
return result.toString();
}
}
2.Log_Forging
日志伪造
例如:如果数值未被解析为整数,输入就会被记录到日志中,附带一条提示相关情况的错误消息。
String val = request.getParameter("val");
try {
int value = Integer.parseInt(val);
}catch (NumberFormatException nfe) {
log.info("Failed to parse val = " + val);
}
如果用户为“val”提交字符串“twenty-one”,则日志中会记录以下条目:
INFO: Failed to parse val=twenty-one
然而,如果攻击者提交字符串twenty-one%0a%0aINFO:+User+logged+out%3dbadguy,则日志中会记录以下条目:
INFO: User logged out=badguy
解决方案
修复方案,过滤引起Log Forging漏洞的敏感字符的公共方法
/**
* Log Forging漏洞校验
* @param logs
* @return
*/
public static String vaildLog(String logs) {
List<String> list=new ArrayList<String>();
list.add("%0d");
list.add("%0a");
list.add("%0A");
list.add("%0D");
list.add("\r");
list.add("\n");
String normalize = Normalizer.normalize(logs, Normalizer.Form.NFKC);
for (String str : list) {
normalize=normalize.replace(str, "");
}
return normalize;
}
3.SQL_Injection
sql注入,采用预编译的方式即可
4.Improper_Resource_Shutdown_or_Release
错误的资源关闭
资源没有关闭,正确关闭即可
5.Information_Exposure_Through_an_Error_Message
通过报错泄露敏感信息
例如:
try {
out = httpResponse.getOutputStream()
} catch (Exception e) {
e.printStackTrace(out);
}
6.CGI_Stored_XSS
存储式XSS攻击
- 把恶意脚本存储到被攻击者的网站的数据库。
- 其他人访问数据库中的恶意脚本代码后,浏览器执行恶意脚本,被攻击。
- 存储式攻击不止一次攻击,并且被攻击的人不止一个,影响范围大。
解决方案
详情:https://www.cnblogs.com/fe-huahai/p/6482672.html
- 过滤字符,跟Reflected_XSS_All_Clients解决方案一样
- 安装三方的应用防火墙,可以拦截css攻击 例如Naxsi
7.Use_of_Hard_coded_Cryptographic_Key
使用硬编码的加密密钥
解决方案
加密密钥不应该留在源码里面,在企业里面源码会被广泛的分享,有些部分甚至会被开源出来,为了更安全的管理,密码和密钥应该被单独的存储在配置文件中
8.Privacy_Violation
隐私泄露
设备密钥没有加密(table:gym_qrcode_secret_key)
9.Serializable_Class_Containing_Sensitive_Data
包含敏感数据的可序列化类
package com.wangda.sports.saas.massgym.vo;
import java.io.Serializable;
/**
* @Description: 百姓健身房商家账户对象Vo
* @Author: MinSa
* @Date: 2020/8/15
* @Version: 1.0
*/
public class MassGymAccountConfigVo implements Serializable {
private Long id;
private String appId;
private String privateKey;
private String publicKey;
private String notifyUrl;
private String returnUrl;
private String accountNumber;
private String gymId;
}
该类实现了序列化,并带有隐私数据,可做加密传输
10.Use_of_Cryptographically_Weak_PRNG 或 Use_of_Insufficiently_Random_Values
标准的伪随机数值生成器不能抵挡各种加密攻击。(随机数不够随机)
详情:https://blog.csdn.net/qq_35976271/article/details/103709844
电脑是一种具有确定性的机器,因此不可能产生真正的随机性。 所以随机数属于伪随机,在安全要求较高的场景中不适用。
解决方案
使用java提供的 java.Security.SecureRandom类,生成的随机数
如果仅指定算法名称,如下所示:
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
如果既指定了算法名称又指定了包提供程序,如下所示:
SecureRandom random = SecureRandom.getInstance("SHA1PRNG", "SUN");
SecureRandom random = SecureRandom.getInstance("SHA1PRNG");
int accountID = random.nextInt();
在我们系统中使用的是Math中的随机静态方法
verifyCode = String.valueOf((int)(Math.random()*900000 + 100000));
11.Unchecked_Input_for_Loop_Condition
可输入的循环条件未作检查,用户可控的数据被作为循环次数的判断依据。 产品没有正确检查用于循环条件的输入,可能由于过度循环而导致拒绝服务或其他后果。
例如:
// clazz为用户输入值
for (Class<Object> superClass = clazz; superClass != Object.class; superClass = (Class)superClass.getSuperclass()) {
try {
return superClass.getDeclaredField(fieldName);
} catch (NoSuchFieldException noSuchFieldException) {}
}
解决方案
不要将用户控制的数据用于循环条件。
12.Incorrect_Permission_Assignment_For_Critical_Resources
关键资源的错误权限分配 (资源暴露)
如果为资源提供了权限设置,该权限设置提供对超出所需范围的参与者的访问权限,则可能导致敏感信息暴露或意外各方对该资源进行修改。当资源与程序配置,执行或敏感的用户数据有关时,这尤其危险。
13.SSRF
服务器端请求伪造
由攻击者构造形成由服务端发起请求的一个安全漏洞。一般情况下,SSRF攻击的目标是从外网无法访问的内部系统。
SSRF 形成的原因大都是由于服务端提供了从其他服务器应用获取数据的功能且没有对目标地址做过滤与限制。
详情:https://xz.aliyun.com/t/2115
解决方案
- 过滤返回信息,验证远程服务器对请求的响应是比较容易的方法。如果web应用是去获取某一种类型的文件。那么在把返回结果展示给用户之前先验证返回的信息是否符合标准。
- 统一错误信息,避免用户可以根据错误信息来判断远端服务器的端口状态。
- 限制请求的端口为http常用的端口,比如,80,443,8080,8090。
- 黑名单内网ip。避免应用被用来获取获取内网数据,攻击内网。
- 禁用不需要的协议。仅仅允许http和https请求。可以防止类似于file:///,gopher://,ftp:// 等引起的问题。
14.Portability_Flaw_Locale_Dependent_Comparison
java.lang.String.toUpperCase() 比较问题
不同地区使用 java.lang.String.toUpperCase() 的结果可能不一样, 比如使用土耳其区域设置"title".toUpperCase() 时将返回 "T\u0130TLE",其中 "\u0130" 是 "LATIN CAPITAL LETTER I WITH DOT ABOVE" 字符。
解决方案
// 指定默认区域设置 if (tag.toUpperCase(Locale.ENGLISH).equals("需要比较的字符串")){ return null; }
// 使用函数java.lang.String.equalsIgnoreCase() API 以防止出现此问题 if (tag.equalsIgnoreCase("需要比较的字符串")){ return null; }