Working with e-commerce stores, we deal with a large amount of PII (Personally Identifiable Information) and payment details on a daily basis. Customers are putting their trust in us when they enter their details into our site. Hopefully, we can all agree that security is important. A security breach can be terminal to a business, whether it be due to lack of customer confidence in the site or more quantifiable consequences such as large fines or revocation of merchant banking capabilities. The latest Magento patch (SUPEE-10415) came out last month, fixing a variety of issues. A review of the release notes show’s that the majority of the issues patched require administrative access to exploit. This poses the question:
Are exploits which require you to be logged in to the admin panel serious?
Your admin panel has a 16 character alpha-numeric ‘secret’ front name. The admin section is only available from a dedicated admin domain on a dedicated admin server. You’ve installed the latest greatest 2FA login system. You’ve implemented IP restrictions, ensuring the admin panel can only be accessed by connecting to a VPN. The only admin user is Dave. He’s been with you for years and you trust him explicitly. You’ve ensured his admin account has 32 character password. You know there’s a theoretically Remote Code Execution (RCE) attack, but you have to be logged in to perform it and you’ve got admin access sealed up tighter than a camels’ backside in a sandstorm. So why worry? Exploit chaining, that’s why you should worry.
What is exploit chaining?
Well, it’s exactly what it says on the tin, forming a “chain of exploits” by using one to trigger another, linking them together. By using this approach, it may be possible to use an otherwise low impact issue, to trigger one with more severe or even critical impact. This may be due to triggering a different type of exploit, such as RCE or by triggering a similar type of issue as you started with, but in an area of the site with more sensitive information.
How does this apply to the Magento Backend?
If you’re Daves developer/hosting partner, you’ve made a great job of protecting his admin panel. Bravo, give yourself a pat on the back. There are however still a couple of different scenarios in which it may be possible for a malicious actor to trigger one of the “theoretical” RCE vulnerabilities. Lets assume you’ve managed to make it impossible for anybody except Dave to make requests to the backend. The question then becomes “How do we trick Dave into doing it for us?”
Persistent XSS to RCE
Hopefully, readers are familiar with the concept of XSS. For those that aren’t, XSS or Cross Site Scripting is when user-provided data is output to the page, without being escaped, allowing for JS code to be executed. Persistent XSS is where the XSS payload is stored in some form of persistent storage rather than coming from the request. This means that the payload can be triggered at a later date, generally multiple times and normally by a different user than the one who persisted the payload in the first place.
As an e-commerce platform, Magento obviously stores a bunch of information provided by its visitors, whether it be their name, address data or items in their cart. Much of this data is displayed to administrators when viewing the backend. If any core file or 3rd party extension outputs such data without correctly escaping it, this allows for a persistent XSS attack. The ability to trigger arbitrary XSS on a page in the backend means that we can read the contents of that page. This may allow us to steal information relating to either other customers or the store, but more importantly, it means we can force the browser to make additional requests. With the ability to trigger arbitrary requests, we can use attack chains to convert this persistent XSS into an RCE.
CSRF to Reflective XSS to RCE
Unlike persistent XSS, a reflective XSS involves “reflecting” data from the actual request rather than from a persistent storage. Since persistent XSS is triggered by an admin as they go about their daily tasks and reflective XSS requires the admin to make a very specific malicious request, they are generally more difficult to trigger. Whilst not all users are technical, many are savvy enough to realise that a URL containing “<script>// <![CDATA[
” (for example) is not normal and thus a red flag is raised, making it even more difficult.
One method to trigger this XSS is by chaining it with cross-site request forgery. Cross-site request forgery or CSRF for short is the process of tricking a browser into making a request to a different site. Since that browser has any associated session id for the site, such a request is for all intents and purposes a valid request by the logged in user. If an admin visits `https://evil.com/` whilst also logged into `https://example.com/admin`, it may be possible for pages on `https://evil.com/` to “trick” the browser into making requests to `https://example.com/`.
The Magento backend employs a couple of different mitigation techniques to help protect against this. The ability to specify a custom front name makes it more difficult for a malicious site to target you and the use of the form_key and URL key tokens add a random element that the attacker, in theory, cannot know. It is however possible to disable these protections globally and extensions may disable / bypass them on a per action basis. If any combination is discovered it may be possible to chain CSRF into XSS into further CSRF and finally RCE.
Conclusion
Whilst a vulnerability may appear impossible to exploit, bugs don’t exist in isolation. New vulnerablities are discovered and exploited on a daily basis. By not patching against known vulnerabilities you are leaving potentially critical tools in an attackers toolbox. You are not only abusing the trust your customers have placed in you, but potentially breaching your contractual obligations with your payment processors.
Whilst it’s OK to assign admin only exploits a lower priority than those that can be triggered from the frontend of the site, hopefully, this post has helped to re-enforce that it’s still of vital importance that *all* known vulnerabilities get patched.