第一种:SQL盲注
SQL盲注是一种威胁程度很高的安全漏洞,通过这种方式,可以入侵服务提供商的服务器数据库,从而窃取、篡改、甚至是删除用户数据。在现实生产环境中我们要完全避免SQL注入的话,需要做很多的工作。在这里仅记录绕过AppScan检测的方法
解决方式:在cas中添加过滤器,过滤请求中的非法字符
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain fc) throws IOException, ServletException {
//判断是否有注入攻击字符
HttpServletRequest req = (HttpServletRequest) request;
/* 已解密的登陆请求*/
String inj = injectInput(req);
if (!"".equals(inj)) {
String failPage = "/error.jsp";
request.getRequestDispatcher(failPage).forward(request, response);
return;
} else {
// 传递控制到下一个过滤器
fc.doFilter(request, response);
}
}
/**
* 判断request中是否含有注入攻击字符
*/
public String injectInput(ServletRequest request) {
Enumeration e = request.getParameterNames();
String attributeName;
String attributeValues[];
String inj = "";
String nameHasXss="";
while (e.hasMoreElements()) {
attributeName = (String)e.nextElement();
// //不对密码信息进行过滤,一般密码中可以包含特殊字符
// if(attributeName.equals("userPassword")||attributeName.equals("confirmPassword")||attributeName.equals("PASSWORD")
// ||attributeName.equals("password")||attributeName.equals("PASSWORD2")||attributeName.equals("valiPassword")){
// continue;
// }
nameHasXss = cleanXSS(attributeName);
if(!"".equals(nameHasXss)){
return nameHasXss;
}else{
attributeValues = request.getParameterValues(attributeName);
for (String attributeValue : attributeValues) {
if (attributeValue == null || "".equals(attributeValue)) {
continue;
}
inj = cleanXSS(attributeValue);
if (!"".equals(inj)) {
return inj;
}
}
}
}
return inj;
}
/**
* 清除恶意的脚本
*/
private String cleanXSS(String value) {
Set keySet = filterMap.keySet();
for(String key : keySet){
if(value.contains(key)){
return value;
} }
return "";
}
@Override
public void init(FilterConfig fConfig) throws ServletException {
//含有脚本script
filterMap.put("[s|S][c|C][r|R][i|C][p|P][t|T]", "");
//含有脚本javascript
filterMap.put("[\\\"\\\'][\\s]*[j|J][a|A][v|V][a|A][s|S][c|C][r|R][i|I][p|P][t|T]:(.*)[\\\"\\\']", "\"\"");
//含有eval函数
filterMap.put("[e|E][v|V][a|A][l|L]\\((.*)\\)", "");
//含有特殊符号
filterMap.put("<", "<");
filterMap.put(">", ">");
filterMap.put("\\(", "(");
filterMap.put("\\)", ")");
filterMap.put("(", "(");
filterMap.put(")", ")");
filterMap.put("'", "'");
filterMap.put("\"", "\"");
filterMap.put(";", ";");
filterMap.put("+", "+");
filterMap.put("|", "¦");
filterMap.put("$", ";");
filterMap.put("@", ";");
filterMap.put("%", ";");
}
第二种:跨站点请求伪造
通常缩写为 CSRF 或者 XSRF,是一种挟制用户在当前已登录的Web应用程序上执行非本意的操作的攻击方法
解决方式:解决CSRF的方法非常多,我选择的是去判断请求的referer是否被篡改
final HttpServletRequest request = (HttpServletRequest) req;
final HttpServletResponse res = (HttpServletResponse) resp;
String referer=request.getHeader("Referer");
String uri = request.getRequestURI();
if((referer!=null) &&(referer.trim().startsWith("http://localhost:8083/"))){
chain.doFilter(request, res);
}else{
request.getRequestDispatcher("/404.html").forward(request,res);
}
还有一种情况是会去篡改你登陆过程中请求的时间戳:例如
GET /index/home.html?_=115840922910701 HTTP/1.1
然后它把115840922910701篡改成了其他数字
我就简单的判断了一下请求的时间戳和当前时间戳是否相差过大,我感觉这种方式不太好,就不贴出来了
第三种:跨站点脚本编制
XSS攻击通常指的是通过利用网页开发时留下的漏洞,通过注入恶意指令代码到网页,使用户加载并执行攻击者恶意制造的网页程序,和上面说的的CSRF的区别在于:XSS利用的是用户对指定网站的信任,CSRF 利用的是网站对用户网页浏览器的信任。
这个漏洞在原生的cas里面几乎不会存在,我检测出这个漏洞是因为我修改过cas的登陆页面,然后留下了漏洞,原因在于这行代码:
">
并没有对参数和结果进行过滤,这行代码对程序影响不大,我直接就删掉了,你也可以对参数进行过滤,执行AppScan扫描出的带有漏洞url,然后查看源代码就基本可以确定哪里是注入点了
第四种:使用 HTTP 动词篡改的认证旁路
这个漏洞出现的原因大部分是因为配置不安全,导致在没有登陆的情况下,访问系统的某个页面的时候,没有被登陆页面拦截。我这里出现的原因是因为我之前写接口把index配置了进去,导致cas忽略index
解决办法:1.更换接口路径,2.过滤指定路径使之被cas拦截
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
HttpServletRequest httpRequest = (HttpServletRequest) servletRequest;
HttpServletResponse httpResponse = (HttpServletResponse) servletResponse;
SessionContent sc = (SessionContent) httpRequest.getSession().getAttribute(SessionContent.skey);
Principal t=httpRequest.getUserPrincipal();
System.out.println(t+"=========================================================");
String redirectUrl = "/";
String servletPath = httpRequest.getServletPath();
System.out.println("拦截请求: " + servletPath);
String uncheckedUrls="/login,/yzuser,/register,/logout/success,/index";
//静态资源直接放行
if (servletPath.startsWith("/static/")){
// System.out.println("----------静态资源----------");
filterChain.doFilter(servletRequest, servletResponse);
return;}
//检测1中获取的servletPath是否为不需要检测的URl中的一个.若是,放行
List urls = Arrays.asList(uncheckedUrls.split(","));
if (urls.contains(servletPath)) {
// System.out.println("---------------------当前url直接放行---------------------\n\n\n\n\n");
filterChain.doFilter(servletRequest, servletResponse);
return;
}
//获取session是否有用户
if (null==t){
System.out.println("---------------------用户未登陆---------------------\n\n\n\n\n");
httpResponse.sendRedirect(httpRequest.getContextPath() + redirectUrl);
return;
}
filterChain.doFilter(servletRequest, servletResponse);
}
第五种:已解密的登录请求
这个漏洞原生的cas上面我扫了一下也是存在的,我账号密码全加密也不行。这个问题耗费了最长的时间,最后发现也是最简单的
解决方式:1.使用ssl,通过https加密去修补漏洞,建议使用nginx比较方便
2.AppScan只会识别type='password'的为密码框,所以我们重写cas的casLoginView.jsp 修改type='text'就能绕过AppScan的检测
casLoginView.jsp关于password的描写如下:
我们重写完如下:
完结!