{"id":47062,"date":"2026-05-25T10:28:45","date_gmt":"2026-05-25T04:58:45","guid":{"rendered":"https:\/\/www.getastra.com\/blog\/?p=47062"},"modified":"2026-05-25T10:28:46","modified_gmt":"2026-05-25T04:58:46","slug":"stored-xss-in-ntfy","status":"publish","type":"post","link":"https:\/\/www.getastra.com\/blog\/vulnerability\/stored-xss-in-ntfy\/","title":{"rendered":"Stored XSS Vulnerability in ntfy"},"content":{"rendered":"<div class=\"gb-container gb-container-83f53fef\">\n\n<p class=\"wp-block-paragraph\"><strong>Product Name:<\/strong> ntfy<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Vulnerability:<\/strong> Stored Cross-Site Scripting(XSS)<\/p>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Vulnerable Version:<\/strong> 2.22.0<\/p>\n\n<\/div>\n\n\n<p class=\"wp-block-paragraph\">In May 2026, security researchers at Astra identified a Stored Cross-Site Scripting (XSS) Vulnerability in the SVG attachment preview function of <strong>nfty<\/strong>, affecting versions up to 2.22.0.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Stored Cross-Site Scripting (XSS) is a vulnerability that allows attackers to inject and permanently execute malicious scripts within a web application. If exploited, the threat actor could perform actions on behalf of the victim.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Technical_Breakdown\"><\/span>Technical Breakdown <span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The vulnerability was discovered during a manual security review of the attachment-handling and preview functionality in nfty. This flaw allows threat actors to execute arbitrary code within the application context when another user previews or opens the uploaded attachment.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How was it discovered?<\/h3>\n\n\n\n<p class=\"wp-block-paragraph\">Our researcher discovered Stored XSS during manual security review of nfty\u2019s attachment handling and preview functionality.\u00a0 When testing how uploaded files are rendered, it was observed that SVG files were served and previewed directly without any sanitization or content restrictions.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">\u200bA specially crafted malicious SVG payload with embedded JavaScript was created via standard attachment features. Upon opening or previewing the file, the embedded JavaScript executed successfully within the application&#8217;s origin context, confirming a stored XSS vulnerability.\u200b<\/p>\n\n\n\n<h3 class=\"wp-block-heading\">How to replicate the vulnerability<\/h3>\n\n\n\n<ol class=\"wp-block-list\">\n<li>Create <strong>an XML file<\/strong> with the embedded JavaScript and name it malicious.svg<\/li>\n\n\n\n<li>Go to the attachment upload feature and upload the <strong>malicious.SVG <\/strong>through normal workflow<\/li>\n\n\n\n<li>Trigger the XSS by navigating to the uploaded attachment and opening it using the preview or view feature.<\/li>\n\n\n\n<li>Now the embedded JavaScript will be executed automatically.<\/li>\n<\/ol>\n\n\n\n<p class=\"wp-block-paragraph\"><strong>Note:<\/strong> The issue was consistently reproducible until the patch was introduced in commit<strong> 2911340.<\/strong><\/p>\n\n\n\n<style>\n.ctaSaasCheckWrap{\n  padding:35px;\n  border: 6px;\n  background-image: url('https:\/\/cdn-blog.getastra.com\/2025\/08\/0737b9ac-deepblue-bg.png');\n  background-size: cover;\n  background-repeat: no-repeat;\n  position: relative;\n  background-position: right;\n  height: 275px;\n  border-radius: 10px;\n  margin: 20px 0px;\n}\n.pentestHeadingDB{\n  color: #fff;\n  font-size: 24px;\n  font-weight: 600;\n  max-width: 450px;\n}\n.ctaSaasCheckWrapHead {\n    display: flex;\n    align-items: center;\n    grid-gap: 1rem;\n}\n.ctaOneDB {\n    display: flex;\n  align-items: center;\n  padding: 1rem 1.5rem;\n  border-radius: 12px;\n  background-color: #FCBB2F;\n  text-decoration: none;\n  grid-gap: .5rem;\n  color: #000!important;\n  font-size: 18px;\n  font-weight: 500;\n  min-height: 3.75rem;\n  max-height: 3.75rem;\n  box-shadow: 0 4px 4px #00000014, 0 0 0 1px #c08e24, inset 0 -4px #0000003d;\n}\n.ctaTwo {\n    text-decoration: none;\n    background-color: #24BC94;\n    color: #ffffff !important;\n    padding: 10px 25px;\n    border-radius: 6px;\n    font-weight: 600;\n}\n.spanBoldBlue {\n    color: #3078FE;\n    font-weight: 700;\n}\n.ctaSaasCheckWrapImg{\n  position: absolute;\n  bottom: 0px;\n  right: 10px;\n  height: 250px;\n  width: 240px;\n}\n@media(max-width: 768px){\n}\n@media(max-width: 576px){\n   .pentestHeading{\n      font-size: 28px;\n    }\n   .ctaSaasCheckWrapImg{\n     display: none;\n   }\n}\n<\/style>\n\n<div class=\"ctaSaasCheckWrap\">\n<p class=\"pentestHeadingDB\">Every fortnight our security engineers update DAST vulnerability scanner&#8217;s test cases. So we&#8217;re always one step ahead.<\/p>\n<div class=\"ctaSaasCheckWrapHead\">\n  <a class=\"ctaOneDB\" href=\"\/contact-us\">Get started at $7!<\/a>\n<\/div>\n<img decoding=\"async\" class=\"ctaSaasCheckWrapImg\" src=\"\/cdn-cgi\/image\/quality=80,format=auto,onerror=redirect,metadata=none\/https:\/\/cdn-blog.getastra.com\/2024\/08\/96ad3cf0-girlcta.png\" alt=\"character\" \/>\n\n<\/div>\n\n\n<div class=\"gb-container gb-container-35f61913\">\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Impact_of_Stored_XSS\"><\/span>Impact of Stored XSS<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The Stored XSS vulnerability in nfty (<strong>versions &lt; 2.2.0)<\/strong> is particularly severe because it allows attackers to embed malicious JavaScript into SVG attachments that are persistently stored on the server.\u00a0\u00a0<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">Once a victim opens or previews the attachment, the payload executes automatically within the victim&#8217;s authenticated session and accesses internal APIs on the victim&#8217;s behalf.<\/p>\n\n\n\n<p class=\"wp-block-paragraph\">The vulnerability could lead to<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li><strong>Session hijacking <\/strong>and theft of authenticated session tokens.<\/li>\n\n\n\n<li>Sensitive data exfiltration.<\/li>\n\n\n\n<li>Potential compromise of administrator accounts if privileged users preview the malicious attachment.<\/li>\n\n\n\n<li>Execution of actions on behalf of the victim (<strong>account takeover<\/strong>).<\/li>\n<\/ul>\n\n<\/div>\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"Current_Status\"><\/span>Current Status<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">The issue was responsibly disclosed to the project maintainer. The maintainer acknowledged the report and fixed the vulnerability in commit <strong>2911340<\/strong>. The issue can be tracked under GitHub Advisory <strong>GHSA-j8hr-p342-xrmh<\/strong>.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\"><span class=\"ez-toc-section\" id=\"What_Can_You_Do\"><\/span>What Can You Do?<span class=\"ez-toc-section-end\"><\/span><\/h2>\n\n\n\n<p class=\"wp-block-paragraph\">Users are strongly advised to update nfty to version <strong>2.23.0<\/strong> to mitigate this vulnerability. If it\u2019s not possible due to compatibility issues, implement the following workarounds:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Disable attachment previews<\/li>\n\n\n\n<li>Block SVG file uploads.<\/li>\n\n\n\n<li>Implement a strict CSP header that blocks script execution.<\/li>\n\n\n\n<li>Disable direct preview\/open functionality for attachments.<\/li>\n<\/ul>\n\n\n\n<p class=\"wp-block-paragraph\">Moreover, Astra Security helps you test for this vulnerability during a<a href=\"https:\/\/www.getastra.com\/pentesting\/web-app\" target=\"_blank\" data-type=\"link\" data-id=\"https:\/\/www.getastra.com\/pentesting\/web-app\" rel=\"noreferrer noopener\"> manual pentest.<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Product Name: ntfy Vulnerability: Stored Cross-Site Scripting(XSS) Vulnerable Version: 2.22.0 In May 2026, security researchers at Astra identified a Stored Cross-Site Scripting (XSS) Vulnerability in the SVG attachment preview function of nfty, affecting versions up to 2.22.0. Stored Cross-Site Scripting (XSS) is a vulnerability that allows attackers to inject and permanently execute malicious scripts within &#8230; <a title=\"Stored XSS Vulnerability in ntfy\" class=\"read-more\" href=\"https:\/\/www.getastra.com\/blog\/vulnerability\/stored-xss-in-ntfy\/\" aria-label=\"Read more about Stored XSS Vulnerability in ntfy\">Read more<\/a><\/p>\n","protected":false},"author":138,"featured_media":47065,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[723],"tags":[],"class_list":["post-47062","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-vulnerability"],"_links":{"self":[{"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/posts\/47062","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/users\/138"}],"replies":[{"embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/comments?post=47062"}],"version-history":[{"count":1,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/posts\/47062\/revisions"}],"predecessor-version":[{"id":47069,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/posts\/47062\/revisions\/47069"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/media\/47065"}],"wp:attachment":[{"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/media?parent=47062"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/categories?post=47062"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.getastra.com\/blog\/wp-json\/wp\/v2\/tags?post=47062"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}