Tag Archives: Exploit

Prototype Pollution, an overlooked application security hole

Some well-known NPM packages, including ember.js, xmldom, loader-utlis and deep-object-diff, have recently been found to have a few prototype pollution vulnerabilities. I made the decision to investigate these vulnerabilities in order to see if there were any trends that we could identify and steer clear.

All of the NPM packages are open source, which allows us to evaluate where vulnerabilities were introduced and how they are remediated by reviewing the fixes. 

A brief Overview of Prototype Pollution Vulnerability

We may need to examine some fundamental concepts about JavaScript Prototype and how Prototype pollution vulnerabilities are introduced and how they could be exploited before we dig in to see if there are any common patterns in these vulnerable libraries.

What is Prototype in JavaScript

Every object in JavaScript has a built-in property, which is called its prototype. The prototype is itself an object, so the prototype will have its own prototype, making what’s called a prototype chain. The chain ends when we reach a prototype that has null for its own prototype.

The following code snippet defined an Object called Student, the prototype of the Student is Object and it has many predefined properties

One power of the Prototype is that it allows an object to inherit properties/attributes from its prototype. Under this case,  Student object could inherit and use all the predefined properties of its prototype Object.

Key takeaway 1:  an object could access the properties/attribute of its prototype due to the inheritance of Prototype. Under this example, the toString() function is defined by Student prototype Object and it could be accessed by any Student object.

Key takeaway 2:  An object could have many instance, they could shared the same Prototype properties 

Key takeaway 3: Meanwhile, JavaScript allows some Object attributes to be changed during runtime, that includes the prototype property; though overwriting the prototype of a default object is considered as a bad practice. 

How does prototype pollution occur and how to exploit them

As the term “prototype pollution” suggests, it happens when a hostile attacker has the ability to manipulate and alter an object’s prototype. Once an attacker could modify the object’s prototype,  all the instances that share the object prototype properties would be affected

Let us tweak the aforementioned code by modifying the toString() properties of the Object prototype to a customized function in order to clarify the explanation. 

When running the above code under the browser console, the studObj.toString() statement will be executed using the new toString() function once we update the toString() function of its Object prototype, and the same will be true for the newly generated object  {} since they both share the same Object Prototype.

If you look at the payload we used in the example above, you’ll see that it has three parts

Part 1: studObj.__proto__.__proto__.

This is intended to obtain the target Object.Prototype, you may see many more .__proto__. in the actual payloads if the prototype chain is very long.

Part 2: .toString 

Using this section, we may tell which function we wish to change or add to the Object.Prototype. In this example, we want to override the toString() function defined in the Object.Prototype

Part 3: = function() {return “I am changed”}

This part is used to set up the new value for the prototype property. 

In a nutshell, access to the Object.Prototype and the ability to modify or add its properties are required for a successful exploit. You may start to think how any app would allow these conditions to be met. In the next section, We will examine the four most current Prototype vulnerabilities to 1) see how the property pollution vulnerabilities are introduced into the codes and 2) see what sort of mitigation methods are employed to fix the prototype pollution.

Case studies for Prototype Pollution Vulnerability & Remediation

Case 1: Prototype Pollution Vulnerability in Ember.js < 4.4.3 (PR

Root Cause

Ember.js provides two functions EmberObject.setProperties or EmberObject.set to set properties of an object.

As there is no validation on the untrustPath variable, if an attacker defines the path to __proto__.__proto__.srcdoc, it would modify the property of the fundamental Object, which will affect all the objects inherited from it.

Mitigation

By referring to the remediation PR,  the mitigation method is to forbid specific keyword __proto__ and constructor to block a prototype chain access. 

Case 2: Potential Prototype Pollution vulnerability in xmldom < 0.7.7

Root Cause

The potential prototype pollution vulnerability (CVE-2022-37616) is caused when this library provides the following function to copy one DOM element to another. (I marked it as potential because a valid POC has not been provided and this copy is NOT performing a deep clone). 

Mitigation

The hasOwnProperty() method is used in this mitigation procedure (PR) to determine whether the src object has the requested property as its own property (as opposed to inheriting the Prototype property). The copy function will fail if the src attribute is inherited from its prototype to prevent a malicious user to access the Prototype Property

Case 3: Prototype Pollution in webpack loader-utils < 2.0.3

Root Cause

This potential vulnerability (CVE-2022-37601) was caused by the queryParse() function when parsing the query parameter and composing a new Object called result with the query parameter name and value.

Mitigation

The mitigation method is very straightforward by using Object.create(null) on objects created as Object.create(null) does NOT inherit from Object.prototype. It means the created Object is not able to access the Prototype Property

Case 4: Prototype Pollution in deep-object-diff

Root Cause

This weakness was introduced when two items were compared deeply and the difference between the two objects was returned as a new object. Due to the possibility that the difference contains prototype property and is under the attacker’s control. It enables the prototyping of pollution.

Mitigation

Similar to Case 3, the mitigation method is using Object.create(null) to create an object where Prototype property could not be inherited. 

When going through all the reported vulnerabilities, cit seems these vulnerabilities are likely to be introduced when following operation occurs

  1. Path assignment to set the property of an Object.  (Case 1, Case 3)
  2. Clone/Copy an object   (Case 2, Case 4)

The common mitigation method includes

  1. Create objects without prototypes inheritance Object.create(null) (case 3,case 4)
  2. Use hasOwnProperty()  function to check  whether a property is on your actual object or inherited via the prototype   (Case 2)
  3. Validate the user input with specific keyword filtering (Case 1)

Prototype Vulnerabilities, a much wider security issue

After reviewing several real-world examples of how prototype vulnerabilities could be developed and how to exploit them, I continued by examining some NPM open source libraries to determine whether prototype pollution is a widely ignored issue in the NPM open source libraries.

Without spending too much effort,  I discovered and verified that two open source libraries used for merging objects are vulnerable to Prototype vulnerability by scraping the source code under Github using specific patterns listed below. 

These two libraries appear to be rather dated though there are still hundreds of downloads every week, however I have contacted the maintainer but have not yet received a response.

All of these instances, in my opinion, are really the tip of the iceberg in terms of how JavaScript libraries are vulnerable to prototype pollution.

I see two possible explanations for why this vulnerability is so prevalent: 1) Given that this vulnerability is very recent, few developers appear to be completely aware of it. 2) At the moment, automation methods to find this kind of vulnerability are not very mature. 

ReDOS, it could be the cause of your next security incident

Regardless of which positions you are fulfilling in the development lifecycle in your organization, regular expressions are useful tools to make your work more efficient. While writing a basic regex itself might not be very hard, defining a robust and secure one could be a real challenge. 

You may start to ponder that I remembered that some security incidents were caused by an insufficient regex pattern where a malicious user input was NOT blocked or detected by the regex. You are right in that perspective and this is a very common scenarios of poor regex leading to a security incident. But in this article, I would like to talk about the danger of poorly designed regexes from a different perspective, ReDOS, which is an overlooked security issue by many developers and  security engineers in my opinion.

ReDOS, an overlooked security risk

Before we start the exploration of ReDOS, we need to understand two basic things 1) Regular expression is a sequence of characters that specifies a search pattern in text, which are commonly used by string-searching algorithms 2) when the regex matching (string searching) is performed, the behind scene algorithm is using a so called backtracking algorithm, where it is a brute forcing method to find a solution/path in a context that will match with the regex, it means there could be an infinite loop when a regex matching is performed behind the scene.  That is the root cause of the DOS caused by regular expression, ReDOS, for short.

Though the severity of ReDOS could be critical as it could paralyze your web server just with a single malformed string, this vulnerability is always overlooked by many security engineers because 1)they are not able to identify a regex with potential ReDOS vulnerability 2) ignore or underestimate the risk of it 3)not able to craft a malicious string to demonstrate the exploitation of this vulnerabilities.  As a security engineer, I was trying to downplay the severity of the ReDOS vulnerability as well as I was not persuaded to believe one single string would be able to totally freeze a web server.  I started to change my mind after I was able to  exploit a ReDOS vulnerability imposed by an inefficient regex with an elaborate string. During the exploitation, the elaborate string consumed 100% CPU of the server when a regex match is performed between the string (payload) and regex

How did I start?

When I was performing a static code analysis against a piece of code with some help of a SAST tool, a vulnerability was flagged against the following regex and it states the following piece of regex could lead to ReDOS attack.  (Note: The regex was modified and changed to make the POC easier to follow)

var regex = /\A([\sa-z!#]|\w#\w|[\s\w]+\”)*\z/g

After reviewing the regex, I started to craft a string by using an online tool https://regex101.com/ to match the regex. It did not take me long to find out that the regex101 is reporting Catastrophic backtracking  error when evaluating the following string.

That error message clearly shows the regex has a flaw in it. I was then using the Debugger functions provided by Regex101 to validate how the backtrack steps are created. After running the debugger,  it indicated that there are some group repetitions in the regex, which makes the backtracking into an endless loop.

After figuring out a possible ReDOS vulnerability could be exploited, I created the following POC codes and ran it on a free tier AWS EC2  t2.micro instance (1G RAM).

The CPU usage of the EC2 instance hiked to 100% after the length of the test payload reached 99 characters after running the POC code, which really surprised me. 

The above POC definitely changed my understanding of the ReDOS vulnerability as the impact could be catastrophic. You might start to ask yourself about how to spot this kind of vulnerability in your code and eliminate it before it gets exploited.

Identify DeROS vulnerabilities in you codes 

It is relatively complicated to justify whether your regex is vulnerable to ReDOS. However, there are a couple of approaches that could make it a little bit easier for you.

Use some patterns to evaluate your Regex

Suggested by OWASP, there are so called pattern to identify evil regex 

  • Grouping with repetition
  • Inside the repeated group:
    • Repetition
    • Alternation with overlapping

When you find a regex with repetition patterns, for example, + character is used in your regex, you should start to pay some attention to the regex as it contains repetition patterns.

Use some automation tool

There are also some automation tools that you might be able to use, for example,  rxxr2 and  ReScue are some open source tools you could use neatly. If you have your source code hosted in Github and have Github Advance Security  enabled,  you could scan your code with CodeQL and the vulnerable regex could be flagged as well though you still need to verify it manually.

Conclusion

Composing an efficient and robust regex is hard and to spot a regex vulnerable to ReDOS is not easier either. This article just attempts to explore the basic problems of ReDOS and how to identify and exploit it with the help of some tools by providing a concrete example.

As stated in the before ahead, most developers, even the security engineers  are not  really aware of the potential risks of an efficient regex. The best way to avoid the ReDOS risk caused by an inefficient regex is to inform your developers and security engineers about the danger of the ReDOS and perform a thorough code review and testing when a regex has to be used in your code.