## Jeesns Weibo Comments store XSS
### Introduction to Vulnerability
JEESNS is a social management system based on JAVA enterprise-level platform. Based on the advantages of enterprise-level JAVA, such as high efficiency, security and stability, it creates a pioneering domestic Java version of open source SNS. JEESNS can be used to build portals, forums, communities, Weibo, Q&A, knowledge payment platform, etc. In Jeesns <= 1.4.2, the Weibo commentary did not completely filter the user's input, resulting in a stored XSS vulnerability.
### Vulnerability Impact
* Jeesns <= 1.4.2
### Vulnerability Analysis
The data submitted by the user foreground will pass XSSFilter, and the doFilter will call XssWrapper.
```java
Package com.lxinet.jeesns.core.utils;
Import java.util.regex.Matcher;
Import java.util.regex.Pattern;
Import javax.servlet.http.HttpServletRequest;
Import javax.servlet.http.HttpServletRequestWrapper;
Import org.springframework.web.util.HtmlUtils;
Public class XssWrapper extends HttpServletRequestWrapper {
    Private static final String REGEX_SCRIPT = "<script[\\s\\S]*?<\\/script>";
    Private static final String REGEX_STYLE = "<style[^>]*?>[\\s\\S]*?<\\/style>";
......
    Public String getParameter(String parameter) {
        String value = super.getParameter(parameter);
        Return value == null ? null : this.cleanXSS(value);
    }
    Public String getHeader(String name) {
        String value = super.getHeader(name);
        Return value == null ? null : this.cleanXSS(value);
    }
    Private String cleanXSS(String value) {
        Value = dealScript(value);
        Value = dealStyle(value);
        String[] eventKeywords = new String[]{"onmouseover", "onmouseout", "onmousedown", "onmouseup", "onmousemove", "onclick", "ondblclick", "onkeypress", "onkeydown", "onkeyup", "ondragstart", "onerrorupdate", "onhelp", "onreadystatechange", "onrowenter", "onrowexit", "onselectstart", "onload", "onunload", "onbeforeunload", "onblur", "onerror", "onfocus ", "onresize", "onscroll", "oncontextmenu", "alert"};
        For(int i = 0; i < eventKeywords.length; ++i) {
            Value = value.replaceAll("(?i)" + eventKeywords[i], "_" + eventKeywords[i]);
        }
        Return value;
    }
    Private static String dealScript(String val) {
        Pattern p = Pattern.compile("<script[\\s\\S]*?<\\/script>");
        Return htmlEscape(p, val);
    }
    Private static String dealStyle(String val) {
        Pattern p = Pattern.compile("<style[^>]*?>[\\s\\S]*?<\\/style>");
        Return htmlEscape(p, val);
    }
    Private static String htmlEscape(Pattern p, String val) {
        String s;
        String newVal;
        For(Matcher m = p.matcher(val); m.find(); val = val.replace(s, newVal)) {
            s = m.group();
            newVal = HtmlUtils.htmlEscape(s);
        }
        Return val;
    }
}
```
As you can see, the `<script>` and `<style>` tags are filtered, and some HTML events are escaped and filtered. However, when matching tags, there is no case processing, which can be bypassed by capitalization.
See the `save()` of the function `\jeesns-service\src\main\java\com\lxinet\jeesns\service\weibo\impl\WeiboCommentServiceImpl.java` that saves the Weibo comments.
```java
        @Override
    Public boolean save(Member loginMember, String content, Integer weiboId, Integer weiboCommentId) {
        Weibo weibo = weiboService.findById(weiboId, loginMember.getId());
        ValidUtill.checkIsNull(weibo, "Weibo does not exist");
        ValidUtill.checkIsBlank(content, "Content cannot be empty");
        If(content.length() > 500){
            Throw new ParamException("Comment content cannot exceed 500");
        }
        WeiboComment weiboComment = new WeiboComment();
        weiboComment.setMemberId(loginMember.getId());
        weiboComment.setWeiboId(weiboId);
        weiboComment.setContent(content);
        weiboComment.setCommentId(weiboCommentId);
        Int result = weiboCommentDao.saveObj(weiboComment);
        If(result == 1){
            @@会员处理 and send system messages
            messageService.atDeal(loginMember.getId(),content, AppTag.WEIBO, MessageType.WEIBO_COMMENT_REFER,weibo.getId());
            / / Reply to microblogging to send system information
            messageService.diggDeal(loginMember.getId(), weibo.getMemberId(), content, AppTag.WEIBO, MessageType.WEIBO_REPLY, weibo.getId());
            If (weiboCommentId != null){
                WeiboComment replyWeiboComment = this.findById(weiboCommentId);
                If (replyWeiboComment != null){
                    / / Reply to microblogging to send system information
                    messageService.diggDeal(loginMember.getId(), replyWeiboComment.getMemberId(), content, AppTag.WEIBO, MessageType.WEIBO_REPLY_REPLY, replyWeiboComment.getId());
                }
            }
            //Weibo comment reward
            scoreDetailService.scoreBonus(loginMember.getId(), ScoreRuleConsts.COMMENT_WEIBO, weiboComment.getId());
        }
        Return result == 1;
    }
```
The data of the user condition is not further filtered, and is directly saved to the database, and then the front end directly renders, resulting in a storage type XSS.
### Vulnerability recurrence
1. Register a user
2. Fill in the XSS payload `<Script>prompt(/xss/)</Script>` in the Weibo comment section.
   
3. Trigger XSS when viewing the details of the Weibo.
   
                       
                       
        
          
暂无评论