-
Notifications
You must be signed in to change notification settings - Fork 821
Closed
Description
Summary
The admin panel allows users to customize uploaded file types through the endpoint "/admin/sysConfigData/save", including dangerous types such as jsp, jspx, php, html, etc. Yes, server-side scripts typically won't be executed, but browsers will parse and execute client-side code. Therefore, if attackers upload htm, html, or pdf files containing malicious JavaScript code, they will be executed, leading to XSS attacks.
The endpoint /admin/cmsWebFile/doUpload
allow user uploads html, htm and PDF file without sanitizer which leads to Stored XSS.
Details

- publiccms-parent/publiccms-core/src/main/java/com/publiccms/controller/admin/cms/CmsWebFileAdminController.java
@RequestMapping("doUpload")
@Csrf
public String upload(@RequestAttribute SysSite site, @SessionAttribute SysUser admin, MultipartFile[] files, String path,
boolean privatefile, boolean overwrite, boolean unzip, String encoding, boolean here, boolean zipOverwrite,
HttpServletRequest request, ModelMap model) {
if (null != files) {
try {
for (MultipartFile file : files) {
String originalName = file.getOriginalFilename();
String suffix = CmsFileUtils.getSuffix(originalName);
String filepath = CommonUtils.joinString(path, Constants.SEPARATOR, originalName);
String fuleFilePath = siteComponent.getWebFilePath(site.getId(), filepath);
if (ArrayUtils.contains(safeConfigComponent.getSafeSuffix(site), suffix)) {
if (CommonUtils.notEmpty(suffix) && suffix.equalsIgnoreCase(".zip") && unzip) {
try {
File dest = File.createTempFile("temp_", suffix);
file.transferTo(dest);
String targetPath;
if (here) {
targetPath = siteComponent.getWebFilePath(site.getId(), path);
} else {
targetPath = siteComponent.getWebFilePath(site.getId(),
CommonUtils.joinString(path, Constants.SEPARATOR,
originalName.substring(0, originalName.lastIndexOf(Constants.DOT))));
}
ZipUtils.unzip(dest.getAbsolutePath(), targetPath, encoding, zipOverwrite, (f, e) -> {
String historyFilePath = siteComponent.getTemplateHistoryFilePath(site.getId(), e.getName(),
true);
try {
CmsFileUtils.copyInputStreamToFile(f.getInputStream(e), historyFilePath);
} catch (IOException e1) {
}
return true;
});
Files.delete(dest.toPath());
} catch (IOException e) {
model.addAttribute(CommonConstants.ERROR, e.getMessage());
log.error(e.getMessage(), e);
}
} else if (overwrite || !CmsFileUtils.exists(fuleFilePath)) {
if (CmsFileUtils.exists(fuleFilePath)) {
String historyFilePath = siteComponent.getWebHistoryFilePath(site.getId(), filepath, true);
try {
CmsFileUtils.copyFileToFile(historyFilePath, historyFilePath);
} catch (IOException e1) {
}
}
CmsFileUtils.upload(file, fuleFilePath);
if (CmsFileUtils.isSafe(fuleFilePath, suffix)) {
FileUploadResult uploadResult = CmsFileUtils.getFileSize(fuleFilePath, originalName, suffix);
logUploadService.save(new LogUpload(site.getId(), admin.getId(),
LogLoginService.CHANNEL_WEB_MANAGER, originalName, privatefile,
CmsFileUtils.getFileType(CmsFileUtils.getSuffix(originalName)), file.getSize(),
uploadResult.getWidth(), uploadResult.getHeight(), RequestUtils.getIpAddress(request),
CommonUtils.getDate(), filepath));
} else {
CmsFileUtils.delete(fuleFilePath);
model.addAttribute(CommonConstants.ERROR, "verify.custom.file.unsafe");
return CommonConstants.TEMPLATE_ERROR;
}
}
} else {
model.addAttribute(CommonConstants.ERROR, "verify.custom.fileType");
return CommonConstants.TEMPLATE_ERROR;
}
}
} catch (IOException e) {
model.addAttribute(CommonConstants.ERROR, e.getMessage());
log.error(e.getMessage(), e);
return CommonConstants.TEMPLATE_ERROR;
}
}
return CommonConstants.TEMPLATE_DONE;
}
POC


Impact
The Stored XSS vulnerability allows attackers launch attacks via arbitrary javascript execution, such as phishing, stealing user's credentials, etc
Metadata
Metadata
Assignees
Labels
No labels