Introduction
This website is one of several online retail stores specialising in children’s toys. Their website has all the standard features you would expect from an online store including the ability to create an account. Unfortunately the “update details” page contains a minor cross-site-scripting bug.

An unassuming account details form, ripe for exploitation!
Cross-Site-Scripting (XSS)
In general, XSS refers to a vulnerability in a website that allows a user to submit HTML to the website and to have that HTML render in the browser. XSS may be quite serious since it can involve getting JavaScript to execute on another user’s browser. XSS comes in a couple of different flavours, you can read more about XSS here but I’ll run through the basics.
Reflected XSS
This occurs when a user is able to submit data to a website (for example, in a form) and the data is “reflected” back to the user’s browser in the HTTP response. This is usually not too much of an issue since browsers have gotten much better at detecting this and preventing scripts from running.
Stored XSS
This one can be more serious since instead of the malicious data coming straight back to the user’s browser it is stored on the server first. This can mean that if any other user views this data on the website that the unescaped HTML might be rendered on their browser too. And because the victim’s web browser has no way of telling apart the website HTML from the malicious HTML, the browser will happily render all the data, including any scripts that might have been included by the bad actor.
Injecting the Update Details Page
In the case of this website, we have a stored XSS vulnerability via the first name of the user. For example, if I change my first name to:
|
|
Then the background of the whole page turns pink. That’s kinda neat 😸

A nice pink-coloured background for my update details page.
We can also include picture is we want to:

If you like looking at cats when you're expecting your name, well, you're in luck!
And even an old-school marquee
tag:
We can also do some '90s-style animations using the marquee
tag.
Limitations
However, due to how the “first name” is returned to the browser, there are a couple of limitations on what kind of data can be used for XSS:
- The page will only render the first 150 characters of the user’s first name.
- If the backend detects any scripts in the request it will reject them (there may be a WAF sitting in the middle here).
- This means that we cannot do anything too clever, unfortunately.
- As far as I can tell, the HTML is only ever run on the “update details” page of the site and is only visible by the user whose account it is.
So, really this issue isn’t all that bad. Even though the HTML is stored in the database it behaves more like a glorified reflected XSS vulnerability. The most exciting thing we can do here is add some custom styles to the page or add other HTML elements (such as video, etc).
Protecting Your Websites from XSS
There’s really only one good way to prevent XSS from happening to your sites, and that’s to HTML escape any user-provided data.
If you’re not using a templating library this essentially just involves replacing all the <
and >
symbols with <
and >
symbols respectively.
Depending on how the data is injected into the page you may also want to escape any quotes from user-provided data.
However, most backend web frameworks have a templating engine built in to them that will do all this for you so there’s likely not much that you need to do yourself.
The litmus test I usually use to quickly determine if a field of a website is vulnerable is to put in <h1>test</h1>
and see if it actually renders a heading or if it escapes (or even removes!) those angled brackets properly.
More Widespread than I Thought
I suspect that the XSS problem is less of an issue with this particular site and more of an issue of the CMS that is being used by this site. Unfortunately, I have no idea what CMS is being used and have tried my best to figure it out! The reason I think this is that there is another popular NZ website that looks very similar (in HTML structure, administration panel, etc) and it has the exact same XSS vulnerability.

A second website with the same issue.
The administration panel for this website uses the logo “Cody” and a URL “meetcody.io” which doesn’t currently exist. I have not been able to find any mention of “meetcody.io” it on Google, or on the Wayback Machine (there appears to be a “meetcody.ai” project that is unrelated and poisons my search results for “meetcody”). I think that this CMS/website builder is proprietary software that isn’t offered to the public.
Disclosure
I reached out to the website administrator on the 31st of March 2024 via email and received no response. I reached out to the owners of this website again on the 9th of April via their Facebook page. They informed me that they had passed my email on to their external web development team. I suspect that this team is responsible for the aforementioned CMS.
I have decided to publish this post while the issue still exists since the potential for abuse is low.
Cover photo by Jerry Wang on Unsplash