arfct / itty-bitty

Itty.bitty is a tool to create links that contain small sites
http://itty.bitty.site
MIT License
3.4k stars 250 forks source link

XSS possibility #2

Open JeroenMoonen opened 6 years ago

JeroenMoonen commented 6 years ago

Example: https://itty.bitty.site/#/?XQAAAAIeAAAAAAAAAAAeHMhnVbtj2LI970NQdDTPEHzdDUCOt/ZTWFnmN///+MCAAA==

alcor commented 6 years ago

I'm going to keep this issue open indefinitely, as I'm curious about best practices here. I've created an itty site as a reference http://xss.bitty.site/ Inlining the content below - note that my thoughts on the matter may change, so please discuss.

--

Scripting is a feature of itty.bitty.site. It can encode an entire webpage, including JavaScript, (and yes, even alerts). These pages are loaded in an iframe, and thus have more limited access to things like cookies and local storage, but can still be abused.

As there are no databases, user accounts or persistent data, scripting does not allow any meaningful attacks here. This is subject to the same precautions you might have with any website with script content – what is shown on itty.bitty comes from the content people make and it is not inherently more trustworthy than a random site on the internet.

Longer term, this may degrade perception of the domain, but for now, the experimental nature of the site makes it worthwhile.

vikramjb commented 6 years ago

Can some sort of hashing or salt of that hash work in confirming the created content is same as the one being accessed ??

topaz commented 6 years ago

If the content were loaded into an iframe with a sandbox attribute that does not include the allow-same-origin permission, "the embedded content is treated as being from a unique origin." That might alleviate some risks.

https://developer.mozilla.org/en-US/docs/Web/HTML/Element/iframe

alcor commented 6 years ago

@topaz Great idea. I've added them. I was a bit worried about same-origin, particularly in IE, and this makes me feel much better. Thank you!

w9w commented 6 years ago

Another XSS PoC "><img src=x onerror=prompt(1)></style></div></article></script>"><script src= https://bitty.site/#%22%3E%3Cimg_src%3Dx_onerror%3Dprompt(1)%3E%3C%2Fstyle%3E%3C%2Fdiv%3E%3C%2Farticle%3E%3C%2Fscript%3E%22%3E%3Cscript_src%3D/data:text/html;charset=utf-8;bxze64,XQAAAAJOAAAAAAAAAAARD4PwR34GfhQzunPuvy5F3llcGzZth676F1jfVRRCFovpS7e3ZbwoDWRYPvBRe7EwYgr7VpBjulPa20N8dwV8Uwwasf/juOAA

itszn commented 6 years ago

@w9w First you only need the <img src=x onerror=prompt(1)> since it is just rendering html and you are not breaking out of another tag.

Second, this is not XSS, because it isn't cross-origin due to the sandboxed iframe. The data is being rendered with the sandboxed iframe src as a data url so there is nothing you can do from that the unique origin that you couldn't do from some other domain. You cannot affect the other "pages" on this site, and none of them can make any persistent data either anyway. This is the same way that something like https://github.com/cure53/DOMPurify "evaluates" the xss in a sandboxed iframe, without harming the page using it.

w9w commented 6 years ago

@itsZN , agree with you. I checked this immediately, before writing my message with payload, using prompt(document.domain) https://bitty.site/#%22%3E%3Cimg_src%3Dx_onerror%3Dprompt(document.domain)%3E%3C%2Fstyle%3E%3C%2Fdiv%3E%3C%2Farticle%3E%3C%2Fscript%3E%22%3E%3Cscript_src%3D/data:text/html;charset=utf-8;bxze64,XQAAAAJcAAAAAAAAAAARD4PwR34GfhQzunPuvy5F3llcGzZth676F1jfVSTesNDeHzIqrH+AT7sqpbNFN8Cg8RzTQJiGTQ5FL+BQMl+B68Q1wYq8Fj+ARpQPF9bkpfz/AEnAAA== . The page gave an empty reply.

nukeop commented 6 years ago

This isn't XSS, this is a js with an alert. Literally any website on the internet can do this. Anyone can host a html file with any kind of javascript inside.

JeroenMoonen commented 6 years ago

@nukeop it was just a basic example. And please, read the explanation of @alcor.

bc0la commented 6 years ago

Just a thought, It's possible this can be used for serverless scareware Example: https://itty.bitty.site/#/data:text/html;charset=utf-8;bxze64,XQAAAAKnAAAAAAAAAAAeHMhnVbtj2GhWv1nklm5AdsaqbvFEwWtJAUqPt1aCaY/ULVX6PrIbFETXytB6clGTPPcIfcYJzNFrH2hvK+qW8dCQAO+WVmo5TIHS394VCL+h2Dpe+mImIyyf8PNgcy9VO/BvIoLtBLZKrLw8UFIucV0E5OWLlu4eFyjjAiOV3H7JClAlgej/Y6EH//xm/eA=

iamwick commented 6 years ago

malicious content won't cause much harm!!! But there is always a way , to harm electronic devices ... lmao

FossPrime commented 6 years ago

How about using a wildcard subdomain with a sha256/bcrypt of the content and verifying that the local storage of the app is it's own before running. I realise browsers don't do good job at subdomain level security. But it could be better than nothing for PWA's that store data on the browser

Instead of: https://itty.bitty.site/Vue-Hello-World#/XQAAAAT//////////wAeCEUG0O+oKBdZ2an16qclPsVsLFo9UXQ0dBK8N+oibOoSWe6xphwrXczGTmEURv+Y+elIed4/mzh2pi6ME0q9x+TqYcl7278HwSuCaNEcpa8OrFcFJOsKUM2rXCb0nxVrds+n1qkcaNteTSWyWdyjhEZFGn+HuE/MdRq4AkIdRCgAnEAnvOx08lP9I/wH0Y96QAirrn0pAJmaIJOasB/IWlQINk3FckfYmvwxK8vjoGbT2UUNjMRMFbUE+xgELTWNZ/5UIxb6fkMd2udYNmZvIeTetmgHVEYwiCcVceHvKsK1YSPnpCwX9Q66lG2oJpvZ9mfhs+19tk1XsZbOisdfouEG3XlQ3z2L9VIZKyMVQiLq6eRkwUMTbsQctH39WM613NQPHuCk4Sez2vi6Tps59CQxe/a3wnedpU/fkjJ4ec7fdTEUX1jAvyyvbnjFIt+PTt1bUPCOccIgEVGNwwjXkL9+kH7XA+p4Vzm2v5s5iA37C1Z536Eh1eJBDvluvxZ9Sl6Ezb0t2c8IBMZfIzSPFFpz+9SCMOEDQYhpzBYHPi7pkDjESb31BhY0a0MoL0R0zywnIMnIf0kzQIElsojgUUzKv500fAsu3uf/5gzs9A==

This:

https://30dca837f3b381201761830fdf322475034f675c.itty.bitty.site/Vue-Hello-World#/XQAAAAT//////////wAeCEUG0O+oKBdZ2an16qclPsVsLFo9UXQ0dBK8N+oibOoSWe6xphwrXczGTmEURv+Y+elIed4/mzh2pi6ME0q9x+TqYcl7278HwSuCaNEcpa8OrFcFJOsKUM2rXCb0nxVrds+n1qkcaNteTSWyWdyjhEZFGn+HuE/MdRq4AkIdRCgAnEAnvOx08lP9I/wH0Y96QAirrn0pAJmaIJOasB/IWlQINk3FckfYmvwxK8vjoGbT2UUNjMRMFbUE+xgELTWNZ/5UIxb6fkMd2udYNmZvIeTetmgHVEYwiCcVceHvKsK1YSPnpCwX9Q66lG2oJpvZ9mfhs+19tk1XsZbOisdfouEG3XlQ3z2L9VIZKyMVQiLq6eRkwUMTbsQctH39WM613NQPHuCk4Sez2vi6Tps59CQxe/a3wnedpU/fkjJ4ec7fdTEUX1jAvyyvbnjFIt+PTt1bUPCOccIgEVGNwwjXkL9+kH7XA+p4Vzm2v5s5iA37C1Z536Eh1eJBDvluvxZ9Sl6Ezb0t2c8IBMZfIzSPFFpz+9SCMOEDQYhpzBYHPi7pkDjESb31BhY0a0MoL0R0zywnIMnIf0kzQIElsojgUUzKv500fAsu3uf/5gzs9A==
alcor commented 6 years ago

Hmm. Interesting. And the sub domain isolation means it could be rendered as a true page instead of as a sandboxed iframe. As of right now, local storage and cookies are not accessible.

tra38 commented 5 years ago

Thought this might be useful knowledge to note (but not useful enough to deserve its own Issue). I discovered this while trying to figure out whether itty.bitty.site could serve as a URL Shortner service.

https://itty.bitty.site/#/XQAAgABEAAAAAAAAAAAeHMhnVbtj2LJdi/PNbyKqL1FBBgJxnQlvGAv6SME8OMeFNOFLnPHwxObwXPvtiftSSAAvsfqVD6idJGMjU/IAAA==

This itty.bitty.site redirects the user to my personal site, but still displays the security modal. It seems that all external links are blocked, as well as a couple of internal links that uses "http://", but the internal links that use "https://" are indeed clickable (so a malicious programmer will need to craft a specific site that only have all the malicious materials on their own domain -- and also remember to use https).

I was able to generate this URL using the following Ruby script:

require 'base64'
require 'lzma'

def url_shortner(url)
      generated_text = %{<script>window.location.replace("#{url}");</script>}
      compressed = LZMA.compress(generated_text)
      base64page = Base64.encode64(compressed).gsub("\n","")
      "https://itty.bitty.site/#/#{base64page}" 
end

url_shortner("https://tra38.github.io")
hanskokx commented 5 years ago

I whipped up this bad boy as a proof of concept. It will eat up all your RAM, and lock your browser.

https://itty.bitty.site/#/XQAAAAT//////////wAeGgqG70rWiByF4jFzRHVDMf0eN9du6LCQxeZC5cnI9UGeN9RUzet49loipZhd9qNBjPXESLhS/ulGVmswFF3lbifCpMG+P2bMFgIi8YJZeZZiz+WkRB9b/83lAZRzzPPpslGHT0rXnADKA0wl4c0Hs+8MeRDf71907n/DArUFzQRZd2k0AiCHK9Gyeu68r7BbmRygBcJ/1XiA0ju2xBuez3d6SxULIwIGIR3iU6QWuZ+hYUh2Mh+arb5stXHQRvr+WO1y

<html>

<body>
    <script>setInterval(function () { var w = document.getElementById('x'); w.append(document.documentElement.outerHTML || document.documentElement.innerHTML); }, 10);</script>
    <div id='x' style='display:none;'></div>
</body>

</html>