stored xss due to unsantized anchor url in alvarotrigo/fullpage.js
Description
stored xss due to unsantized anchor url in GitHub repository alvarotrigo/fullpage.js prior to 4.0.4. stored xss .
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
Stored XSS in fullPage.js <4.0.4 via unsanitized anchor URLs allows arbitrary script execution in victim browsers.
Vulnerability
In fullPage.js versions prior to 4.0.4, the anchor URL used for navigation bullets is not sanitized, leading to stored cross-site scripting (XSS) [3]. The vulnerability exists in the bullet link generation code where the getBulletLinkName output is directly inserted into an `` tag without encoding [4].
Exploitation
An attacker can craft a malicious anchor/URL containing JavaScript payloads. When a user visits a page using fullPage.js with such a crafted anchor, the payload is stored and executed in the context of the victim's browser. No special authentication is required; the attacker needs to control the anchor value, e.g., via a user-supplied input [2][4].
Impact
Successful exploitation leads to arbitrary JavaScript execution in the victim's browser, potentially allowing theft of cookies, session tokens, or other sensitive information, or performing actions on behalf of the victim [3].
Mitigation
The issue is fixed in fullPage.js version 4.0.4 released on April 12, 2022 [1][3]. Users should upgrade to 4.0.4 or later. The fix uses encodeURI for the link and bullet names [4]. No workarounds are documented.
AI Insight generated on May 21, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected packages
Versions sourced from the GitHub Security Advisory.
| Package | Affected versions | Patched versions |
|---|---|---|
fullpage.jsnpm | < 4.0.5 | 4.0.5 |
Affected products
3- Range: < 4.0.4
- alvarotrigo/alvarotrigo/fullpage.jsv5Range: unspecified
Patches
1e7a5db427117Merge pull request #4360 from ranjit-git/ranjit-git-patch-1
5 files changed · +8 −8
dist/fullpage.extensions.min.js+1 −1 modifieddist/fullpage.js+2 −2 modified@@ -1829,7 +1829,7 @@ for (var i = 0; i < numSlides; i++) { var slide = $(SLIDE_SEL, sectionElem)[i]; - appendTo(createElementFromHTML('<li><a href="#"><span class="fp-sr-only">' + getBulletLinkName(i, 'Slide', slide) + '</span><span></span></a></li>'), $('ul', nav)[0]); + appendTo(createElementFromHTML('<li><a href="#"><span class="fp-sr-only">' + encodeURI(getBulletLinkName(i, 'Slide', slide)) + '</span><span></span></a></li>'), $('ul', nav)[0]); } //centering it @@ -2354,7 +2354,7 @@ link = section.anchor; } - li += '<li><a href="#' + link + '"><span class="fp-sr-only">' + getBulletLinkName(section.index(), 'Section') + '</span><span></span></a>'; // Only add tooltip if needed (defined by user) + li += '<li><a href="#' + encodeURI(link) + '"><span class="fp-sr-only">' + encodeURI(getBulletLinkName(section.index(), 'Section')) + '</span><span></span></a>'; // Only add tooltip if needed (defined by user) var tooltip = getOptions().navigationTooltips[section.index()];
dist/fullpage.min.js+1 −1 modifiedsrc/js/nav/sections.js+2 −2 modified@@ -64,7 +64,7 @@ export function addVerticalNavigation(){ link = section.anchor; } - li += '<li><a href="#' + link + '"><span class="fp-sr-only">' + getBulletLinkName(section.index(), 'Section') + '</span><span></span></a>'; + li += '<li><a href="#' + encodeURI(link) + '"><span class="fp-sr-only">' + encodeURI(getBulletLinkName(section.index(), 'Section')) + '</span><span></span></a>'; // Only add tooltip if needed (defined by user) var tooltip = getOptions().navigationTooltips[section.index()]; @@ -98,4 +98,4 @@ export function sectionBulletHandler(e){ EventEmitter.emit('scrollPage', { destination: getState().sections[indexBullet] }); -} \ No newline at end of file +}
src/js/nav/slides.js+2 −2 modified@@ -57,12 +57,12 @@ export function addSlidesNavigation(section){ for(var i=0; i< numSlides; i++){ var slide = utils.$(SLIDE_SEL, sectionElem)[i]; - utils.appendTo(utils.createElementFromHTML('<li><a href="#"><span class="fp-sr-only">'+ getBulletLinkName(i, 'Slide', slide) +'</span><span></span></a></li>'), utils.$('ul', nav)[0] ); + utils.appendTo(utils.createElementFromHTML('<li><a href="#"><span class="fp-sr-only">'+ encodeURI(getBulletLinkName(i, 'Slide', slide)) +'</span><span></span></a></li>'), utils.$('ul', nav)[0] ); } //centering it utils.css(nav, {'margin-left': '-' + (nav.innerWidth/2) + 'px'}); var activeSlideIndex = section.activeSlide ? section.activeSlide.index() : 0; utils.addClass(utils.$('a', utils.$('li', nav)[activeSlideIndex] ), ACTIVE); -} \ No newline at end of file +}
Vulnerability mechanics
Generated on May 9, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
5- github.com/advisories/GHSA-h3cq-j957-vhxgghsaADVISORY
- nvd.nist.gov/vuln/detail/CVE-2022-1330ghsaADVISORY
- github.com/alvarotrigo/fullPage.js/pull/4360ghsaWEB
- github.com/alvarotrigo/fullpage.js/commit/e7a5db42711700c8a584e61b5e532a64039fe92bghsax_refsource_MISCWEB
- huntr.dev/bounties/08d2a6d0-772f-4b05-834e-86343f263c35ghsax_refsource_CONFIRMWEB
News mentions
0No linked articles in our index yet.