Eugene Rojavski, Author at Checkmarx https://checkmarx.com/author/eugenerojavski/ The world runs on code. We secure it. Tue, 19 Nov 2024 18:09:39 +0000 en-US hourly 1 https://wordpress.org/?v=6.6.1 https://checkmarx.com/wp-content/uploads/2024/06/cropped-cx_favicon-32x32.webp Eugene Rojavski, Author at Checkmarx https://checkmarx.com/author/eugenerojavski/ 32 32 Falling Stars https://checkmarx.com/blog/falling-stars/ Mon, 18 Nov 2024 14:39:23 +0000 https://checkmarx.com/?p=98880 Intro

The number of the open-source packages is constantly rising, complicating how developers choose a package that fits their needs and is secure. Package repositories offer various metrics to help developers choose the right package, like the number of downloads, GitHub statistics, and user ratings. Package repositories offer various metrics to help developers choose the right package, like the number of downloads, GitHub statistics, and user ratings. Nevertheless, popularity continues to be one of the most influential factors in package selection. When we see a popular package, we assume it’s well-maintained and reliable. This common assumption led to the emergence of starjacking two years ago.

Starjacking is a technique that artificially inflates a package’s apparent popularity by exploiting how package repositories display information about associated GitHub repositories. After the technique became public, several major repositories, including npm and Yarn, were found to allow package publications with links to GitHub repositories not owned by the package publisher. We recently conducted comprehensive research across more than 20 package repositories to evaluate the current state of starjacking, and the findings show promising developments in security measures.

Researched package repositories

Our research encompassed 21 separate package repositories, Ranging from the big ones like npm, maven, and PyPI to smaller ones like CPAN, LuaRocks, and Hackage. The table below lists each repository and its primary programming language, included in the research.

Repo Name Language
npm JS
Maven Central java
Pypi python
NuGet csharp
pkg.go.dev go
Packagist PHP
Rubygems Ruby
crates.io Rust
CocoaPods ObjC/Swift
Pub.dev dart
CPAN perl
CRAN R
Clojars JS
Yarn JS
anaconda python, r
LuaRocks lua
Hackage haskell
Opam ocaml
Hex erlang
Meteor JS
Swift package index Swift

These repositories fall into two primary categories based on their artifact management approaches:
  • Some store the artifacts created during building, compiling, or packaging the code.
  • Others simply provide references to GitHub repositories containing the necessary files for package installation.

Package managers that exclusively reference GitHub repositories, such as pkg.go.dev and RubyGems, are inherently protected against starjacking since they display data directly from GitHub repositories. This direct integration eliminates the possibility of linking to one repository while serving code from another.

GitHub repositories pkg.go.dev web image

While such package repositories are not susceptible to Starjacking, the displayed GitHub statistics can still be misleading. They can be manipulated using more sophisticated techniques. For example, Swift Package Index and Packagist display comprehensive GitHub repository details, which can trick the users, if the stats are spoofed.

Packagist index web screen shot
Swift index web screen shot

Results

Most repositories do not display the GitHub repository statistics referred to by the package. While PyPI and Yarn previously showed these stats, they’ve since modified their approaches: Yarn has completely removed the statistics while PyPI implemented a more sophisticated metadata display system.   Yet some package repos still display GitHub statistics; for example, npm continues to show the number of issues and pull requests from the GitHub repository specified in the package metadata.

npn index web screenshot

Moreover, the CPAN Perl package repository displays the GitHub stats.

CPAN Perl package repository screenshot

Pypi’s Transformation of GitHub Statistics Display

PyPI slowly but steadily added verification of the package metadata.

Initially, PyPI displayed GitHub repository statistics without any verification mechanism. This approach made the platform vulnerable to starjacking attempts, as any package could claim association with any GitHub repository. PyPI’s first security improvement divided package information into two distinct sections: unverified and verified details.

While this division helped users identify trusted information, statistics of arbitrary GitHub repositories were still shown in the unverified details section. This was a good step towards informing the user which data they can trust. However, this was not enough since most people don’t carefully distinguish between verified and unverified information.

PyPI made a crucial advancement by implementing a comprehensive verification system through the Trusted Publisher Management feature. Starting from August 2024, the platform now ensures GitHub statistics appear exclusively in the verified details section and are only displayed for packages uploaded through the Trusted Publisher Management feature. This system utilizes OpenID Connect to enable secure publishing through trusted services like GitHub Actions.

The new publishing process works as follows: A PyPI project maintainer specifies a workflow in their GitHub repository for automatic package publishing. When triggered, the workflow authenticates with PyPI, proving that the code comes from the intended source. Only after verification can the package be published. Under this new system, PyPI displays GitHub repository statistics only when the links point to verified code repositories that have been authenticated through the trusted publishing workflow.

The evolution of PyPI’s security measures against Starjacking can be seen in three distinct phases (left to right):

  1. Initial phase: GitHub statistics were displayed without any verification or indication of their authenticity.

2. Second phase: Separation of verified and unverified details, with GitHub statistics specifically placed
in the unverified details section.

3. Current phase: GitHub statistics are now only displayed in the verified details section and appear
exclusively for packages uploaded through the Trusted Publisher Management feature.

This progression demonstrates PyPI’s commitment to maintaining security while providing valuable repository information to users.

GitHub project description page screenshot

Conclusion

While npm and CPAN continue to display unverified GitHub statistics, the risk of Starjacking has significantly decreased over the past two years. This improvement stems from most repositories either removing GitHub statistics entirely or implementing more robust verification systems, as exemplified by PyPI. It’s worth noting that most repositories (with PyPI being the exception) still display package metadata links without verification. While this vulnerability could potentially be exploited by malicious actors, it poses a substantially lower risk of misleading users compared to the original Starjacking technique.

]]>
GO package repo packigist package repo swift package repo npm package repo meta cpan package repo Pypi verified details
Analysis of OpenSSL CVE-2022-3786 and CVE-2022-3602 https://checkmarx.com/blog/analysis-of-openssl-cve-2022-3786-and-cve-2022-3602/ Tue, 01 Nov 2022 22:55:50 +0000 https://checkmarx.com/?p=80220 On the 1st of November, OpenSSL released information about two buffer overflow vulnerabilities: CVE-2022-3786 and CVE-2022-3602. In the pre-disclosure announcement on the 25th of October, the issue severity was declared as Critical, but then it was changed to High. The issues affect versions 3.0 and above.

Both CVEs have similar severity; however, their potential impact varies: CVE-2022-3602 may lead to remote code execution, and CVE-2022-3786 results in denial of service. The severity has been downgraded because the OpenSSL team got more feedback from the parties participating in the early testing concluding that remote code execution is only possible for a limited set of platforms/compilers.

There is no PoC (proof of concept) available now. The exploitation requires either a malicious certificate signed by a trusted Certificate Authority, which is not trivial, or code that ignores the certificate chain validation error, which is possible but is not ubiquitous.

The OpenSSL team recommends updating to version 3.0.7, regardless of the issue severity change.

Checkmarx SCA can help find the usage of OpenSSL, flagging the currently affected versions. Technical information regarding the vulnerabilities are available in our new Developer’s Hub:

The KICS team has added a new query that detects downloads of the vulnerable OpenSSL versions in the Dockerfiles.

References

More Details

OpenSSL is an open-source implementation of the SSL and TLS protocols, and its ubiquitous software. The modern Internet relies on SSL and TLS, so OpenSSL or its forks like LibreSSL and BoringSSL are pre-installed and used by all modern operating systems. This software is used on both ends: servers and clients.

On November 1st, the OpenSSL team announced two new CVEs: CVE-2022-3786 and CVE-2022-3602. These two issues are buffer overflows, and their severity is High. Initially, on the 25th of October, the issue severity was announced by the OpenSSL project as Critical, but then it was changed to High. The issues reside in punycode decoding functions.

There is no PoC (proof of concept) available now.

CVE-2022-3786 – X.509 Email Address Variable Length Buffer Overflow

In short, CVE-2022-3786 affects TLS clients and servers and could result in a crash (Denial of Service). Exploitation seems complicated because it requires certain conditions.

A buffer overrun can be triggered in X.509 certificate verification. To be specific, it happens in the name constraint check. An attacker can craft a malicious email address to overflow an arbitrary number of bytes containing the . (decimal 46) character on the stack.

TLS clients may be affected by CVE-2022-3786 as well as TLS servers. On a TLS client, this can be triggered by connecting to a malicious server. On a TLS server, this can be triggered if the server requests client authentication and a malicious client connects. It is worth saying that vulnerable code is triggered only after the certificate chain signature verification. It means that an attacker must obtain a signed malicious certificate, whereas issuing a trusted malicious certificate signed by a valid certificate authority is not trivial.

CVE-2022-3602 – X.509 Email Address 4-byte Buffer Overflow

CVE-2022-3602 is an arbitrary 4-byte stack buffer overflow. Such vulnerabilities may lead to remote code execution. Originally, this issue was assessed by the OpenSSL project as Critical. After investigation, the OpenSSL team realized that remote code execution is only possible for a limited set of platforms/compilers and decreased the severity to High.

Because these two issues reside in punycode decoding functions, it is highly likely that CVE-2022-3602 has the same attack vector and conditions for exploitation as the CVE-2022-3786.

What to do

If you use OpenSSL 3.0.0-3.0.6, upgrade to 3.0.7 as soon as possible.

You may find an original blog post by the OpenSSL team with the FAQ: https://www.openssl.org/blog/blog/2022/11/01/email-address-overflows/

References

]]>
Apache Unomi CVE-2020-13942: RCE Vulnerabilities Discovered https://checkmarx.com/blog/apache-unomi-cve-2020-13942-rce-vulnerabilities-discovered/ Tue, 17 Nov 2020 09:00:14 +0000 https://www.checkmarx.com/?p=42583 “Apache Unomi is a Java Open Source customer data platform, a Java server designed to manage customers, leads and visitors’ data and help personalize customers experiences,” according to its website. Unomi can be used to integrate personalization and profile management within very different systems such as CMSs, CRMs, Issue Trackers, native mobile applications, etc. Unomi was announced to be a Top-Level Apache product in 2019 and is made with high scalability and ease of integration in mind.
Given that Unomi contains an abundance of data and features tight integrations with other systems, making it a highly desired target for attackers, the Checkmarx Security Research Team analyzed the platform to uncover potential security issues. The findings are detailed below.

Executive Summary: CVE-2020-13942

What We Found

Apache Unomi allowed remote attackers to send malicious requests with MVEL and OGNL expressions that could contain arbitrary classes, resulting in Remote Code Execution (RCE) with the privileges of the Unomi application. MVEL and OGNL expressions are evaluated by different classes inside different internal packages of the Unomi package, making them two separate vulnerabilities. The severity of these vulnerabilities is heightened since they can be exploited through a public endpoint, which should be kept public by design for the application to function correctly, with no authentication, and no prior knowledge on the attacker’s part.
Both vulnerabilities, designated as CVE-2020-13942, have a CVS Score of 10.0 (Critical) as they lead to complete compromise of the Unomi service’s confidentiality, integrity, and accessibility, in addition to allowing access to the underlying OS.

Details

Previous RCE Found in Unomi

Unomi offers a restricted API that allows retrieving and manipulating data, in addition to a public endpoint where applications can upload and retrieve user data. Unomi allows complex conditions in the requests to its endpoints.
Unomi conditions rely on expression languages (EL), such as OGNL or MVEL, to allow users to craft complex and granular queries. The EL-based conditions are evaluated before accessing data in the storage.
In the versions prior to 1.5.1, these expression languages were not restricted at all—leaving Unomi vulnerable to RCE via Expression Language Injection. An attacker was able to execute arbitrary code, and OS commands on the Unomi server by sending a single request. This vulnerability was classified as CVE-2020-11975 and was fixed. However, due to further investigation by the Checkmarx Security Research Team, we discovered that the fix is not sufficient and can be trivially bypassed.

Patch Not Sufficient – New Vulnerabilities Discovered

The patch for CVE-2020-11975 introduced SecureFilteringClassLoader, which checks the classes used in the expressions against an allowlist and a blocklist. The SecureFilteringClassLoader relies on the assumption that every class in both MVEL and OGNL expressions is loaded using the loadClass() method of the ClassLoader class. The SecureFilteringClassLoader overrides the ClassLoader loadClass method and introduces the allowlist and blocklist checks. This assumption happened to be incorrect. There are multiple ways of loading a class other than calling the loadClass() method, which leads to the security control bypass and leaves Unomi open to RCE.
First, the MVEL expressions in some cases use already instantiated classes, like Runtime or System, without calling loadClass(). This results in the latest version of Unomi (1.5.1) allowing the evaluation of MVEL expressions inside the condition, which contains arbitrary classes.
The following HTTP request has a condition with a parameter containing a MVEL expression (script::Runtime r = Runtime.getRuntime(); r.exec(“touch /tmp/POC”);). Unomi parses the value and executes the code after script:: as an MVEL expression. The expression in the example below creates a Runtime object and runs a “touch” OS command, which creates an empty file in /tmp directory.

Vulnerability #1


Second, there is a way to load classes inside OGNL expressions without triggering the loadClass() call. The following HTTP request gets Runtime and executes an OS command using Java reflections API.

Vulnerability #2


The payload may look scary but it’s simply Runtime r = Runtime.getRuntime(); r.exec(“touch /tmp/POC”); written using reflection API and wrapped into OGNL syntax.
Both presented approaches successfully bypass the security control introduced in version 1.5.1, making it vulnerable to RCE in two different locations.

Possible Attack Scenarios

Unomi can be integrated with various data storage and data analytics systems that usually reside in the internal network. The vulnerability is triggered through a public endpoint and allows an attacker to run OS commands on the vulnerable server. The vulnerable public endpoint makes Unomi an ideal entry point to corporate networks. Its tight integration with other services also makes it a steppingstone for further lateral movement within an internal network.

Summary of Disclosure and Events

After discovering and validating the vulnerabilities, we notified Apache of our findings and worked with them throughout the remediation process until they informed us everything was appropriately patched.
To learn more about these types of vulnerabilities, OWASP and CWE have descriptions, examples, consequences, and related controls, as shown in the following links:

Additionally, read the code, analyze the fix, and learn how to mitigate similar issues via our interactive CxCodebashing lesson here.

Timeline of Disclosure

June 24, 2020 – Vulnerability disclosed to Apache Unomi developers
August 20, 2020 – Code with the mix merged to master branch
November 13, 2020 – version 1.5.2 containing the fixed code is released
November 17, 2020 – public disclosure

Recommendations

The evaluation of user-defined expression language statements is dangerous and hard to constrain. Struts 2 is an excellent example of how hard it is to restrict dynamic OGNL expressions and avoid RCE. These attempts to impose usage restrictions from within/on the EL, rather than restricting tainted EL usage for general purposes, is an iterative approach, rather than a definitive one. Instead, a more reliable means to prevent RCE is to remove the support of arbitrary EL expressions entirely, creating a set of static expressions that rely on dynamic parameters instead.
Static Application Security Testing solutions, like CxSAST, can detect OGNL injections in source code and prevent this sort of vulnerability from making its way into production. Meanwhile, software composition analysis (SCA) solutions, such as CxSCA, will have the necessary data about the vulnerable package and will update CxSCA users as soon as the vulnerability is publicly disclosed. To learn how to mitigate similar issues, visit our CxCodebashing lesson here.

Final Words/Summary

This type of research is part of the Checkmarx Security Research Team’s ongoing efforts to drive the necessary changes in software security practices among all organizations. Checkmarx is committed to analyzing open source software to help development teams build and deploy more-secure applications. Our database of open source libraries and vulnerabilities is cultivated by the Checkmarx Security Research Team, empowering CxSCA customers with risk details, remediation guidance, and exclusive vulnerabilities that go beyond the NVD.
To learn more about this type of RCE vulnerabilities, read our blog about Struts 2. For more information or to speak to a Checkmarx expert about how to detect, prioritize, and remediate open source risks in your code, contact us.

]]>
The Hacker vs. Struts 2 Game – It Appears it has No Ending https://checkmarx.com/blog/hacker-vs-struts2-game-has-no-ending/ Wed, 30 Oct 2019 13:40:15 +0000 https://www.checkmarx.com/?p=29650 If you’re active in the cybersecurity industry, you have likely heard the buzz about Struts 2 Java framework in 2017. In short, hackers were able to exploit a vulnerable application based on Struts 2 and stole hundreds of millions of PII records.
The vulnerability (CVE-2017-5638) made a lot of noise, but like almost any critical vulnerability, it was patched and everyone moved on. However, this ultimately ended up being the tip of the iceberg since there are other, lesser-known vulnerabilities with equally-serious consequences. The root cause of these vulnerabilities are still there as a result, and even the latest patch does not guarantee the complete safety of a Struts 2-based application.

In this post, I will show you why Struts 2 is a dangerous toy to play with and where to poke to break it.
In the graphic below, the fourth column from the left shows the number of code execution vulnerabilities in Struts, accounting for nearly 33% of the issues discovered. No other Java framework has this many. What’s more, all of them share the same root cause—the framework’s architecture itself. Let’s take a closer look.

Source: CVE Details

Struts Architecture

There are two major architectural solutions stitching together model, views, and controllers:  Value Stack and OGNL. Value Stack is the stack of all the objects used by an application to respond to a user request (e.g. application configuration, security settings, data, etc.). Objects in the Value Stack are manipulated using Object Graph Navigation Language (OGNL), which is an expression language handy for getting and setting Java object properties.

OGNL

What is the OGNL library capable of? With the following example, OGNL calls a method of a given class, as well as doing something worse.

As you can see, an OGNL expression can contain an operating system command (e.g., cmd.exe, calc.exe, etc.). Therefore, if you allow the execution of malicious input as OGNL expressions, then you are in trouble.
Luckily, Struts 2 doesn’t expose OGNL directly. It has several layers above it a shown below.

At the top of the pyramid resides an entrance point to the OGNL expression. The example below shows a view that retrieves the username from the session object using “#session.user.name” OGNL expression.  It is an intentional and legitimate way of using OGNL in Struts 2. However, malicious data may be evaluated as an OGNL expression unintentionally because of a vulnerability in the application or framework itself.

The next layer of the pyramid is the framework’s implementation of OGNL library. The most interesting part for us is the security mechanism because it defines which OGNL expressions are allowed to be evaluated.
Finally, after passing security checks, the expression is evaluated by Java OGNL library.

Recipe of a Successful Attack

Therefore, you need two key components to evaluate arbitrary OGNL expressions in a Struts 2-based application:

  1. Find an injection point leading to the evaluation
  2. Bypass the security mechanism

Injection Points

How can a malicious OGNL expression be evaluated? There are two options:
The direct evaluation method happens when the user input ends in an argument of a method that evaluates the input as an OGNL expression. The following framework code took part in the notorious CVE-5638-2017 by evaluating an error message tainted with the malicious OGNL expression.

The double evaluation method consists of two evaluation calls, making it harder to find. As demonstrated in the following example, the first call populates a variable with a malicious expression but does not evaluate it yet. Meanwhile, the second call gets the tainted variable value and evaluates it. The double evaluation is usually unintentional. For example, it may combine the evaluation introduced by a developer and the evaluation inside the framework code.

Security Mechanism Bypasses

Now that you know what injection points look like, let us imagine that the payload is evaluated, allowing us to play with the security mechanism.
You will see its evolution from an attacker perspective starting from Struts 2 version 2.3.14.1 (2013) up to the current state in versions 2.5.20 or 2.3.37. The security mechanism in versions before 2.3.14.1 is trivial; afterward, it was continuously upgraded.
Now comes the best part where we are going to review the payloads that bypass the security mechanism and upgrades made against them. The general approach of all the following payloads is to first remove the existing restrictions, and then run an OS command.

The first payload

The security mechanism in the initial state restricted access to static method calls. For some reason, the mechanism itself was accessible to OGNL expressions. The following payload first permits static method calls, and then calls a static method getRuntime().exec with the OS command.

The fix in 2.3.14.2 made allowStaticMethodAccess immutable. What if instead of a static method, we try to generate an object dynamically? The next payload does exactly this to bypass the security mechanism.

The second payload


The fix in 2.3.20 prohibits usage of constructors and introduces blacklists of classes and packages restricted for OGNL.

The third payload

The security mechanism disallows static methods, but allows static objects. The researchers found a static object in the OGNL library containing the security mechanism in its default state (= zero security settings). The following payload sets the current security mechanism to the default state and runs a command.

The fix in 2.3.30 and 2.5.2 finally deprived OGNL expressions of access to the security mechanism by blacklisting ognl.MemberAccess and ognl.DefaultMemberAccess classes.

The fourth payload

OGNL can call methods of any object in the given context. It occurred that the blacklists are in the context of an evaluated expression, which can be reached through a chain of several objects and flushed using clear() method. When blacklists are empty, we can use the trick from the previous payload to run a command.

The fix in 2.3.32 and 2.5.10.1 blocked the path to OgnlUtils by making com.opensymphony.xwork2.ActionContext unavailable for OGNL. In addition, blacklists were made immutable, making clear() method ineffective.

The fifth payload

ValueStack is a complex set of intertwined objects where you can reach the same object in several ways, starting from the Value Stack root. The next payload accesses OgnlUtils through a different set of objects. Blacklists were made immutable incorrectly by the previous fix and they can be updated using a setter. The payload consists of two consequent requests, the first of which request flushes blacklists, and the second of which runs a command. It’s possible to break the payload into two requests because OgnlUtils is a singleton and keeps its value until the application restart.

No More CVEs, but the Vulnerabilities May Still Be There

The fix in 2.3.35 and 2.5.17 fixed the flaws and put Struts 2 OGNL injections on pause. The blacklists are destined to be bypassed, so we can wait for the next episode of the cat and mouse game between the framework developers and attackers.
Currently, the framework does not have known injection points and code execution exploits. However, it does not make the Struts 2-based application safe because developers may introduce an injection point themselves. For example, this can occur by unintentionally chaining a benign evaluation inside framework code, with one more evaluation in their own code. The following code snippet is an example of how the application based on the latest version of Struts 2 is still exploitable when there is an injection point.

At first, the “createUser” action creates an object of class User and saves it to the session variable. The default value of the “isAdmin” property of the “User” class is false.
Later, the “inject” action loads the “User” object from the session, evaluates user input as OGNL expression, and saves the “User” object back to the session. The “getText()” method is an injection point inserted for demonstration purposes.
By calling these actions sequentially, the attackers can manipulate non-blacklisted objects. For example, set “User.isAdmin” to true, thus bypassing an authorization check.
Given these points, Struts 2 developers should keep yet another vulnerability type in mind. The recommendation is to use SAST or IAST tools like Checkmarx extensively, to find possible code execution via OGNL injection vulnerabilities. Without proper application security testing processes in place, the likelihood of overlooking an exploitable injection vulnerability caused by a developer is quite high.

]]>