Overview
Vuetify is a Vue.js UI library with Material Design components for building responsive web applications.
A cross-site scripting (XSS) vulnerability (CVE-2025-1461) has been identified within the Vuetify VCalendar component, specifically in the eventMoreText prop, which allows unsanitized HTML to be used.
Per OWASP: Cross-Site Scripting attacks are a type of injection, in which malicious scripts are injected into otherwise benign and trusted websites. XSS attacks occur when an attacker uses a web application to send malicious code, generally in the form of a browser side script, to a different end user. An attacker can use XSS to send a malicious script to an unsuspecting user.
This issue affects Vuetify versions greater than or equal to 2.0.0 and less than 3.0.0.
Details
Module Info
- Product: Vuetify
- Affected packages: vuetify
- Affected versions: >=2.0.0 <3.0.0
- GitHub repository: https://github.com/vuetifyjs/vuetify
- Published packages: https://npmjs.com/package/vuetify
- Package manager: npm
- Fixed in: Vuetify NES v2.7.3
Vulnerability Info
This Medium-severity vulnerability (CVSS score 4.6) is found in the VCalendar component of Vuetify >=2.0.0 <3.0.0.
The issue arises from improper handling of text passed in the eventMoreText prop. The vulnerability occurs because the default Vuetify translator will return the translation key as the translation if it can't find an actual translation. The vulnerability flow is:
- The text from the eventMoreText prop is passed into the Vuetify translation function
- The translation function returns the inputted text if no match is found (treating HTML as a "translation key")
- The returned text is directly assigned to the innerHTML of the Event More element, leading to potential XSS attacks
Steps To Reproduce
- Create a Vue.js application using Vuetify 2.x
- Add a VCalendar component with the event-more prop enabled
- Set the eventMoreText prop to include malicious HTML/JavaScript code, for example:
<v-calendar
:now="today"
:value="today"
:events="events"
color="primary"
type="month"
event-more
event-more-text="<span onclick=alert('XSS')>🚨 Click Here</span>"/>
- When there are more events than can be displayed, the calendar will show the "more events" link
- Clicking on this link will execute the injected JavaScript code
Proof Of Concept
A proof-of-concept demonstrating the code examples above as well as mitigation options below is available on GitHub.
Mitigation
Version 2.x of Vuetify is End-of-Life and will not receive any updates to address this issue. For more information see here.
Users of the affected components should apply one of the following mitigations:
- Migrate affected applications to a supported version of Vuetify.
- Leverage a commercial support partner like HeroDevs for post-EOL security support.
- If you already are a Never-Ending Support customer, see below for available migration options.
Mitigation for NES customers
In Vuetify NES, the vulnerability is mitigated by escaping any HTML passed into the eventMoreText prop before passing it to the Vuetify translation function.
Breaking Change
This fix is marked as a breaking change for VCalendar users who intentionally passed HTML into the eventMoreText prop for styling, third-party integrations, or event handling. Previously, HTML content in the eventMoreText prop was rendered directly to the DOM, allowing for potential XSS attacks. The fix now properly escapes HTML in the eventMoreText prop before rendering.
Temporary Opt-out Strategy
For users who need time to migrate, an opt-out strategy is provided using the nes-unsafe-event-more-text prop:
- Opt-out Flag: nes-unsafe-event-more-text
- Prop Type: Boolean
- Default Value: false (By default, pages will no longer be vulnerable)
- Purpose: Render HTML in eventMoreText prop (Legacy behavior)
<v-calendar
:events="events"
event-more
event-more-text="<span style='background: lightblue;'>Custom Text</span>"
nes-unsafe-event-more-text
/>
Migration Options
1. Styling Options
Use unscoped styles with specific class selectors:
<template>
<v-calendar
class="my-calendar"
:events="events"
event-more
event-more-text="Custom Text"
/>
</template>
<style>
/* Unscoped style */
.my-calendar .v-event-more {
background-color: lightblue;
}
</style>
2. Event Handling Options
Use the @click:more handler instead of any onclick events. See the Vuetify Calendar API for usage:
<v-calendar
:events="events"
event-more
event-more-text="Custom Text"
@click:more="handleMoreClick"
/>
3. Global i18n Fix (Advanced)
The Vuetify internationalization system can also be used to customize the eventMoreText message, including rendering HTML. The default translation key is $vuetify.calendar.moreEvents.
// Translation provided by Vuetify
import en from 'vuetify/lib/locale/en'
// Custom translation
export default {
...en,
calendar: {
moreEvents: '<span style="background: lightblue;">{0} more events</span>'
},
}
export default new Vuetify({
lang: {
locales: { en },
current: 'en',
},
})
Note: You may also find guidance from vue-i18n on the risk of using HTML in translations.
Recommended Actions
Users of the affected VCalendar component should:
- Upgrade to Vuetify NES v2.7.3 or later.
- Review all uses of the eventMoreText prop to ensure no malicious content can be injected.
- Choose an appropriate migration strategy from the options above.
For comprehensive migration guidance, see the advanced migration guide.