前言:
Jspxcms9.0版本留言处存在存储型XSS漏洞,现复现审计一下源码以及原因。
漏洞复现:
用户评论处
浅测一下
复现成功
代码审计:
F12查看请求包是/comment_submit接口,参数是text
找到/comment_submit接口,发现
text = sensitiveWordService.replace(text);//过滤输入
comment.setText(text);//过滤后的文本
@RequestMapping(Constants.SITE_PREFIX_PATH + "/comment_submit")
public String submit(@PathVariable String siteNumber, String fname,
String ftype, Integer fid, Integer parentId, String text,
String captcha, HttpServletRequest request,
HttpServletResponse response, org.springframework.ui.Model modelMap)
throws InstantiationException, IllegalAccessException,
ClassNotFoundException {
siteResolver.resolveSite(siteNumber);
User user = Context.getCurrentUser();
Response resp = new Response(request, response, modelMap);
………………………………………………省略
if (StringUtils.isBlank(ftype)) {
ftype = Info.COMMENT_TYPE;
}
// 这里传入
text = sensitiveWordService.replace(text);
Comment comment = (Comment) Class.forName(fname).newInstance();
comment.setFid(fid);
comment.setText(text);
comment.setIp(Servlets.getRemoteAddr(request));
}
追踪sensitiveWordService.replace方法逻辑是判断text为空或空格,直接返回text。否则进行遍历。
word.getName():获取当前敏感词对象的敏感词字符串。
word.getReplacement():获取当前敏感词对象指定的替换字符串。如果没有指定替换字符串 (null),则使用空字符串 "" 进行替换。
StringUtils.replace(s, word.getName(), replacement):使用 Apache Commons Lang 库中的 StringUtils.replace 方法,将字符串 s 中的敏感词 word.getName() 替换为 replacement。
敏感词在哪里呢,追踪getReplacement()与getName(),这里用了JPA,最后追踪到cms_sentive_word表的f_name与f_replacement。
到sql数据库查询,所有值都为空,所以会造成存储型XSS,如果维护做好过滤,则可修复此漏洞。