XSS in user supplied title in nuxt/nuxt

Valid

Reported on

Feb 7th 2023


Issue

The useHead function does not sanitize tags inserted in each property, including the title property.

Context

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).

Therefore 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 nuxt or vueuse or 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 title within 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

<template>
<div>Hello world!</div>
</template>

<script setup lang="ts">
  const r = useRoute()

  useHead({
     title: r.query.title as string
  })
</script>

Create a production build, start the build, navigate to the url http://site/?title=</title><script>alert(1)</script> This vulnerability only occurs during SSR.

Recommendation

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.

Impact

XSS can give an attacker access to sensitive information or actions.

We are processing your report and will contact the nuxt team within 24 hours. 2 months ago
OhB00 modified the report
2 months ago
We have contacted a member of the nuxt team and are waiting to hear back 2 months ago
OhB00 submitted a
2 months ago
OhB00 modified the report
2 months ago
nuxt/nuxt maintainer has acknowledged this report 2 months ago
OhB00
2 months ago

Researcher


Vulnerability has been fixed in downstream component https://github.com/unjs/unhead/issues/97

OhB00
2 months ago

Researcher


Fixed upstream! https://github.com/nuxt/nuxt/commit/88b895a23a855135c5c8ee53183677e17aad1a12

Daniel Roe validated this vulnerability a month ago

Thank you for this - great work. <title> XSS is resolved. As far as potential XSS in innerHTML I think we can document the risks of setting html directly, and we plan to provide a sanitisation option to make it easy for devs.

OhB00 has been awarded the disclosure bounty
The fix bounty is now up for grabs
The researcher's credibility has increased: +7
Daniel Roe marked this as fixed in 3.2.1 with commit 88b895 a month ago
The fix bounty has been dropped
This vulnerability will not receive a CVE
This vulnerability is scheduled to go public on Feb 17th 2023
Daniel Roe published this vulnerability a month ago
to join this conversation