Skip to main content

VMWare Workspace ONE Access

Space & Airborne Systems
Feb 27, 2023 | 5+ Minute Read

By Steven Seeley

Note: This article is one in a technical series by Trenchant of L3Harris Technologies.


In 2022, I conducted research against VMWare Workspace ONE Access and was able to find a remote code execution vulnerability triggerable by an authenticated administrator. Although authentication is required, past authentication bypass vulnerabilities have been published. As an aside, if you’re interested in this sort of work, here at Trenchant we perform vulnerability research against a wide variety of interesting and challenging targets!

VMWare’s vendor advisory can be found here.


Full chain authorABRCE
Kai Zhao & Steven YuCVE-2022-22973?
Petrus VietCVE-2022-31659CVE-2022-31659

After I built the Hekate 0-click exploit, which chains an authentication bypass with other vulnerabilities, I saw that Kai Zhao of ToTU Security Team and Steven Yu reported CVE-2022-22973, another authentication bypass without chaining any remote code execution.

Later on, Petrus Viet bypassed the patch for CVE-2022-22973 (patched as CVE-2022-31659) and chained it with another remote code execution vulnerability he found (CVE-2022-31659).

A new RCE vulnerability could be combined with Kai Zhao and Steven Yu’s authentication bypass to achieve unauthenticated remote code execution. VMWare try very hard not to allow any post-authentication RCE vulnerabilities, especially because these flaws have been exploited in the wild.

Vulnerability Analysis

I was up late one night and reading about Java bean validation related vulnerabilities, and I realized this is an area I hadn’t investigated initially when auditing this target. Since an RCE would allow completing a full chain, I decided it was time to dive in one last time.

In Alvaro’s excellent post, he mentions that the vulnerable sink to be looking for is javax.validation.ConstraintValidatorContext.buildConstraintViolationWithTemplate with a partially controlled error message, so I went about my journey to find such a sink which lead me to the com.vmware.horizon.catalog.validation.TypeInfoValidator class:




At [1] the validator loops through the errorMessages property and gets the first string value from the HashSet and proceeds to call buildConstraintViolationWithTemplate. I continued to look for anything that calls addErrorMessage at [2] since this method populates the errorMessages property.

I failed at finding anything of use and was about to give up when I found this interesting method inside of the TypeInfoValidator class:



Naturally, I wanted to know how the errorMessages list is derived in order to influence the return value of getErrorMessageKey at [3]. I dived into the
com.vmware.horizon.catalog.utils.saml.transformation.ClaimTransformationHelper class to inspect the validateClaimTransformations method:


At [4] the code loops through the supplied claimTransformations and calls getRules. At [5] claimRules is cast to an ArrayList of ClaimRule instances and stored in rules. Then at [6] the code calls validateClaimRuleCondition with the attacker-supplied rules.

The getCondition method is called on the attacker-supplied ClaimRule instance that was passed directly to the scriptEngine.eval sink at [7]. Because Java bean validation occurs on user-supplied data, it was likely that we could reach this injection sink with influenceable data.

Reaching validateClaimRuleCondition

Looking for calls to validateClaimTransformations I found a few results:

Looking for calls to validateClaimTransformations I found a few results:

The second result is the com.vmware.horizon.catalog.validation.SamlTypeInfoValidator class that exposes the validate method.

validate method

This is called by the two child bean validation classes Saml11TypeInfoValidator and Saml20TypeInfoValidator in their isValid implementations.

isValid implementations

At this point I started to look for implementations with any of the annotations @ValidSaml11TypeInfo, @ValidSaml20TypeInfo or @ValidWSFed12TypeInfo.

The classes com.vmware.horizon.api.v2.catalog.Saml11AuthInfo, com.vmware.horizon.api.v2.catalog.Saml20AuthInfo and com.vmware.horizon.api.v2.catalog.wsfed.WSFed12ResourceInfo all implement the custom bean validator as an annotation.

custom bean validator as an annotation

Looking for validation

At this point, we have three classes that can reach the vulnerable sink and these classes need to be validated in order to reach that sink. After some searching, I found a @PostConstruct at [8] inside of the
com.vmware.horizon.catalog.impl.CatalogServiceImpl class that is called after the initialization of the catalogService bean service:

catalogService bean service

After more searching, I found the abstract class implements this service:

abstract class implements this service

At [9] we see that the class auto wires the CatalogService. Naturally, I then looked for child classes of AbstractCatalogResource and I found two interesting examples:


These are interesting because they use the following three types from the package:

  1. Saml11CatalogItem
  2. Saml20CatalogItem
  3. WSFed12CatalogItem

These types expose a JSON property that maps back to their associated AuthInfo types. For example, let’s inspect the Saml20CatalogItem class:

Saml20CatalogItem class


Looking at the class we can find several methods that expose the vulnerable sink:

expose the vulnerable sink

At [11] the user needs to be at the admin level to reach this endpoint, however, several authentication bypasses existed in this application in the past and these can be chained with this vulnerability.

Also, note that not all methods to reach the vulnerable code are listed here. I have provided two as proof of concept.

Proof of Concept

This PoC requires the target’s hostname and admin credentials. Chaining with CVE-2022-22973 is an exercise for the reader 🙂






Stack Trace

Stack Trace