XSS 101
XSS matters because it facilitates phishing — it makes the victim want to click on a legitimate-looking link. The attack is a reflection of HTML code (stored or not) that allows executing arbitrary code. This "code" is generally a fragment of HTML that enables JavaScript execution. It sometimes happens that the injection point is directly in a <script> tag, but this is rare.
A typical example:
https://beguier.eu/?q=1'><script>alert("XSS")</script><'XSS with CSS
Here is a type of injection that is often underestimated but can cause the same damage as a classic XSS. The magic <style> snippet below makes an element span the entire page and become transparent:
position: fixed; z-index: 100000; opacity: 0; top: 0; left: 0; width: 10000px; height: 10000px;The victim can only click on this invisible overlay. Here is a variant with a slightly transparent red background to visualise the attack surface:
position: fixed; z-index: 100000; opacity: 0.5; top: 0; left: 0; width: 10000px; height: 10000px; background-color: red;It all depends on the tag type. At best, it's an <a> tag (very common), so you can set an href to redirect the victim to an arbitrary website — for example, a copy of the current site with a fake login page to steal credentials. Full PoC with the <a> tag:
How to defend
The CSS properties to watch for and block in user-generated HTML:
position: fixed — Removes the element from the normal document flow and positions it relative to the viewport. Combined with large dimensions, it can cover the entire page.
z-index — Controls stacking order. A very high value ensures the overlay sits on top of all page content.
More generally:
- Never reflect raw HTML from user input.
- If you must allow HTML (e.g. a comment feature), use a whitelist of allowed tags — e.g. <b>, <i> — and strip everything else.
- Maintain a whitelist of allowed attributes — e.g. href on <a>, src on <img>.
- If a style attribute must be allowed, restrict it to a predefined list of safe CSS properties.
- Also be careful with class attributes: document.getElementsByClassName('className') can be exploited if class names trigger JavaScript functions.
Live Demo
Click either button below to trigger the attack locally on this page. The first shows a red overlay so you understand what's happening; the second is the real transparent version.