## Jfinal cms article stored XSS
### Vulnerability Introduction
Jfinal cms, using the simple and powerful JFinal as the web framework, the template engine is beetl, the database uses mysql, front-end bootstrap, flat ui and other frameworks. Support multi-site, oauth2 authentication, account registration, password encryption, comments and replies, message prompts, website traffic statistics, article comments and pageview statistics, response management, rights management, etc.
### Vulnerability impact
- <= v4.7.1
### Vulnerability analysis
The vulnerability trigger point is in `com/jflyfox/modules/front/controller/PersonController.java`
```java
public void saveblog() {
JSONObject json = new JSONObject();
json.put("status", 2);// 失败
SysUser user = (SysUser) getSessionUser();
if (user == null) {
json.put("msg", "没有登录,不能提交博文!");
renderJson(json.toJSONString());
return;
}
Integer pid = getParaToInt();
TbArticle model = getModel(TbArticle.class);
// 验证题目,内容
String content = model.getContent();
String title = model.getTitle();
String tags = getPara("tags");
// 删除侵入脚本
content = JFlyFoxUtils.delScriptTag(content);
title = HtmlUtils.delHTMLTag(title);
tags = HtmlUtils.delHTMLTag(tags);
// 这里没有必要提示太精准~因为前台有验证~绕过的都不是好人哦
if (content == null || HtmlUtils.delHTMLTag(content).length() > 2000 //
|| title == null || title.length() > 200 //
|| tags == null || tags.length() > 200 //
) {
json.put("msg", "博客信息错误,请输入正确数据!");
renderJson(json.toJSONString());
return;
}
model.setUpdateTime(getNow());
if (pid != null && pid > 0) { // 更新
// 管理员或者自己才能修改
if (!isAdmin(user) //
&& model.getCreateId().intValue() != user.getUserid().intValue()) {
json.put("msg", "你没有权限修改博文!");
renderJson(json.toJSONString());
return;
}
model.update();
} else { // 新增
model.remove("id");
if (model.getFolderId() == null || model.getFolderId() <= 0) {
model.setFolderId(JFlyFoxUtils.MENU_BLOG); // 博文目录
}
model.setStatus("1"); // 显示
model.setType(11);
model.setIsComment(1); // 能评论
model.setIsRecommend(2);// 不推荐
model.setSort(20); // 排序
model.set("approve_status", ArticleConstant.APPROVE_STATUS_PASS); // 需要审核改为update
model.setPublishTime(DateUtils.getNow("yyyy-MM-dd")); // 发布时间
model.setPublishUser(user.getUserName()); // 发布人
model.setCreateId(getSessionUser().getUserid());
model.setCreateTime(getNow());
model.save();
}
```
The relevant data published in the front desk will be stored in the TbArticle model. The data sent by the user will be filtered by the delHTMLTag function to filter the html related tags, but the extracted data will not be assigned after filtering. At this time, the data in the model is still with the payload. Then, directly call model.save() to store the data, and finally render it in the foreground, which is equivalent to no filtering.
### Vulnerability recurrence
1. Register a regular user.
2. Post a blog post.
3. Fill in the xxs payload in the header.
![](https://images.seebug.org/1553771096194-w331s)
4. Click to publish
5. Accessing the home page or this article will trigger xss
![](https://images.seebug.org/1553771102331-w331s)
暂无评论