XSS in user supplied title in nuxt/nuxt
Feb 7th 2023
useHead function does not sanitize tags inserted in each property, including the
useHead repository is a wrapper around
vueuse/head which wraps
unjs/unhead which wraps
harlan-zw/zhead. The possibility of XSS is not described as being a vulnerability in the root repositories (see here and here).
nuxt, and some nuxt packages (content, bridge) are misusing/misdocumenting this feature.
The fact that the
useHead function is vulnerable to XSS appears to be known by the community:
But the these dangers are not documented directly on
unjs/head docs. You have to look at the lowest level utility
zhead to understand that this may be dangerous. Even at that point it's not completely obvious that possibility of XSS when using
useHead, as this seems like a safe feature, compared to scripts which are obviously inherently dangerous.
This lack of documentation means that It may not be obvious to developers that
useHead title is an unsafe feature, and you can find instances of developers making this mistake if you search. I would definitely say most developers would assume setting the page title will be safe, setting title in nuxt2 does not have this issue.
User supplied data within the title is a common practice.
Proof of Concept
<script setup lang="ts">
const r = useRoute()
title: r.query.title as string
Create a production build, start the build, navigate to the url
This vulnerability only occurs during SSR.
It seems like there is a plan to implement a safe version of this function in
vueuse. I think this weakness should be documented for the moment, or creating a wrapper
useHead that HTML encodes title.
XSS can give an attacker access to sensitive information or actions.