Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The XSS vulnerability exists in the latest version of SENS #17

Open
altEr1125 opened this issue Nov 19, 2022 · 0 comments
Open

The XSS vulnerability exists in the latest version of SENS #17

altEr1125 opened this issue Nov 19, 2022 · 0 comments

Comments

@altEr1125
Copy link

This project allows new users to register. New users are only allowed to post articles and need to be reviewed by an administrator.
This function is implemented in the project code: com.liuyanzhao.sens.web.controller.admin#pushPost
The specific code is as follows:

@PostMapping(value = "/save")
    @ResponseBody
    @SystemLog(description = "保存文章", type = LogTypeEnum.OPERATION)
    public JsonResult pushPost(@ModelAttribute Post post,
                               @RequestParam("cateList") List<Long> cateIds,
                               @RequestParam("tagList") String tagList) {

        checkCategoryAndTag(cateIds, tagList);
        User user = getLoginUser();
        Boolean isAdmin = loginUserIsAdmin();
        //1、如果开启了文章审核,非管理员文章默认状态为审核
        Boolean isOpenCheck = StringUtils.equals(SensConst.OPTIONS.get(BlogPropertiesEnum.OPEN_POST_CHECK.getProp()), TrueFalseEnum.TRUE.getValue());
        if (isOpenCheck && !isAdmin) {
            post.setPostStatus(PostStatusEnum.CHECKING.getCode());
        }
        post.setUserId(getLoginUserId());

        //2、非管理员只能修改自己的文章,管理员都可以修改
        Post originPost = null;
        if (post.getId() != null) {
            originPost = postService.get(post.getId());
            if (!Objects.equals(originPost.getUserId(), user.getId()) && !isAdmin) {
                return new JsonResult(ResultCodeEnum.FAIL.getCode(), localeMessageUtil.getMessage("code.admin.common.permission-denied"));
            }
            //以下属性不能修改
            post.setUserId(originPost.getUserId());
            post.setPostViews(originPost.getPostViews());
            post.setCommentSize(originPost.getCommentSize());
            post.setPostLikes(originPost.getPostLikes());
            post.setCommentSize(originPost.getCommentSize());
            post.setDelFlag(originPost.getDelFlag());
        }
        //3、提取摘要
        int postSummary = 100;
        if (StringUtils.isNotEmpty(SensConst.OPTIONS.get(BlogPropertiesEnum.POST_SUMMARY.getProp()))) {
            postSummary = Integer.parseInt(SensConst.OPTIONS.get(BlogPropertiesEnum.POST_SUMMARY.getProp()));
        }
        //文章摘要
        String summaryText = HtmlUtil.cleanHtmlTag(post.getPostContent());
        if (summaryText.length() > postSummary) {
            String summary = summaryText.substring(0, postSummary);
            post.setPostSummary(summary);
        } else {
            post.setPostSummary(summaryText);
        }

        //4、分类标签
        List<Category> categories = categoryService.cateIdsToCateList(cateIds, user.getId());
        post.setCategories(categories);
        if (StringUtils.isNotEmpty(tagList)) {
            List<Tag> tags = tagService.strListToTagList(user.getId(), StringUtils.deleteWhitespace(tagList));
            post.setTags(tags);
        }
        //当没有选择文章缩略图的时候,自动分配一张内置的缩略图
        if (StringUtils.equals(post.getPostThumbnail(), BlogPropertiesEnum.DEFAULT_THUMBNAIL.getProp())) {
            String staticUrl = SensConst.OPTIONS.get(BlogPropertiesEnum.BLOG_STATIC_URL.getProp());
            if (!Strings.isNullOrEmpty(staticUrl)) {
                post.setPostThumbnail(staticUrl + "/static/images/thumbnail/img_" + RandomUtil.randomInt(0, 14) + ".jpg");
            } else {
                post.setPostThumbnail("/static/images/thumbnail/img_" + RandomUtil.randomInt(0, 14) + ".jpg");
            }
        }
        post.setPostType(PostTypeEnum.POST_TYPE_POST.getValue());
        postService.insertOrUpdate(post);
        if (isOpenCheck && !isAdmin) {
            return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), "文章已提交审核");
        }
        return new JsonResult(ResultCodeEnum.SUCCESS.getCode(), localeMessageUtil.getMessage("code.admin.common.operation-success"));
    }

After auditing the code, you can see that there is an xss attack without any wrapping or filtering.
It is found that the content of the article will be encoded using escapeHTML(), and the article data will be included in the p tag.
XSS injection can be performed by grabbing traffic packets and directly modifying postTitle or postContent.
Use the website provided by the project author to demonstrate the vulnerability.
At this point, the revised content has been submitted for review.
image
The administrator will be attacked by XSS when logging in to the audit page.
image
Another problem is that when other undetected xss attacks are used, the administrator will approve them. In this case, storage xss will be formed and all users will be attacked by xss, which is extremely harmful

Solution: Add a filtering mechanism

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant