TL;DR

On a client engagement Reversec found the LAPSWebUI application by Truesec for handling Windows users’ local administrator passwords. Several vulnerabilities were found and reported to the vendor, which has addressed all of them in version 2.4 released in January 2026.

Introduction

Windows LAPS

Microsoft describes it best themselves:

Windows Local Administrator Password Solution (Windows LAPS) is a Windows feature that automatically manages and backs up the password of a local administrator account on your Microsoft Entra-joined or Windows Server Active Directory-joined devices.

Some of the security benefits of using Windows LAPS:

  • there is no single hard-coded local admin password shared by all client computers in an enterprise
  • passwords are automatically rotated when used

(There is also a “legacy” LAPS called Microsoft LAPS.)

LAPSWebUI

The cybersecurity company Truesec developed a web-based user interface supporting both self-service for users who are approved to gain local admin privileges when required and also for helpdesk or service technicians to look up passwords for multiple devices. They primarily offer the tool to their existing customers. See Truesec’s release announcements (1, 2) and their service description (PDF) for more background.

Confirmed Vulnerabilities

A vulnerability report sent to Truesec 2025-Dec-23. It included four vulnerabilities, but one of them could not be confirmed to have any security impact in Reversec’s client’s setup. It was nevertheless included in the report because of the major impact it would have if it was exploitable in certain configurations.

After the Christmas holidays, Truesec confirmed three (non-critical) vulnerabilities 2026-Jan-05 and told us that fixes will be included in the next version and that it was planned to be released already in January. The potentially high severity vulnerability (more information below) was judged to not be exploitable in any customer configuration, but a redesign was planned nevertheless to be on the safe side.

The three confirmed vulnerabilities were rated as Medium severity, using CVSSv4 vectors for the judgement. We have categorised one of they as Low instead (justification in advisory). Truesec did not provide any CVSS scoring of the vulnerabilities.

The confirmed vulnerabilities were the following. See the individual security advisories for details:

Quick summary of the issues if you don’t want to read the advisories:

  • The session cookie issued to a LAPSWebUI user lasted more than 13 days, which is a very long time for such a sensitive tool. There already existed an administration setting to require an Entra ID sign-in for every password retrieval, but that was not enabled in the environment where Reversec found LAPSWebUI.

  • The Logout button in LAPSWebUI did not log out the user from LAPSWebUI. Instead, the user was redirected to the logout functionality in Entra ID. If the user visited the URL of LAPSWebUI again, they were still authenticated.

  • LAPSWebUI recommended administrators to configure the web server to set certain security-related HTTP response headers, and also provided an option for the web application itself to set them. Neither option included any header restricting the caching of pages, so the retrieved local admin passwords were stored on disk by the user’s browser.

All three confirmed vulnerabilities are fixed in version 2.4 of LAPSWebUI according to its vendor Truesec.

Other Problems

We discovered some other issues with LAPSWebUI as well. For instance the potentially high severity one mentioned above.

Mutable Claim Used for Authorization Decisions

We were sooo close to report a very serious vulnerability in LAPSWebUI. Since in the end it was just bad practice and we couldn’t prove any security impact, we ended up describing the problem to our client in a finding rated Informational. But we still reported it to Truesec as a potentially high severity finding since we could not rule out that there existed other configurations of LAPSWebUI that were exploitable.

If it were exploitable, it would have been categorised as CWE-639 Authorization Bypass Through User-Controlled Key.

LAPSWebUI can use (and did in our client’s environment) Entra ID for authentication. The application then uses a Microsoft-signed JWT for logging in the user in the web application and setting a session cookie. The request looked like this:

POST /signin-oidc HTTP/1.1
Host: [REDACTED]
Cookie: .AspNetCore.Correlation.[...]=N; .AspNetCore.OpenIdConnect.Nonce.[...]=N; AzureAppProxyAnalyticCookie_[REDACTED]_https_1.3=[...]
[...]
Referer: https://login.microsoftonline.com/
Content-Type: application/x-www-form-urlencoded
Content-Length: 2198
Origin: https://login.microsoftonline.com
[...]

id_token=eyJ0eXAiOiJKV1QiLCJhbGciOiJSUzI1NiIsImtpZCI6InJ0c0ZULWItN0x1WTdEVlll
   U05LY0lKN1ZuYyJ9.[REDACTED].[...]&session_state=00abff59-8220-3605-d3a8-e61f2b5d3861

We used the author’s Reversec Entra ID account which was invited as a guest user in our client’s Entra ID tenant. Yes, the default setting for the Enterprise Application created by a LAPSWebUI installation prior to version 2.4 was to not require assignment and thereby allowing guest users in the tenant to authenticate to the application:

Microsoft Entra ID portal with settings page of the Enterprise Application created by LAPSWebUI. The Properties page shows "Assignment required?" set to "No".

The JWT provided to LAPSWebUI when logging in was decoded as follows:

{
  "typ": "JWT",
  "alg": "RS256",
  "kid": "rtsFT-b-7LuY7DVYeSNKcIJ7Vnc"
}.{
  "aud": "[REDACTED]",
  "iss": "https://login.microsoftonline.com/[REDACTED]/v2.0",
  "iat": [REDACTED],
  "nbf": [REDACTED],
  "exp": [REDACTED],
  "aio": "AYQAe/8aAAAAQDWITshVr[...]",
  "idp": "https://sts.windows.net/ea33927c-14dc-4a64-9482-d3df5ef087b9/",
  "name": "Laban Sköllermark",
  "nonce": "638998405736913083.[...]",
  "oid": "b7ab5fdb-3de5-4540-bfd3-9b233130d184",
  "preferred_username": "laban.[plz-no-spam]@reversec.com",
  "rh": "1.AXoA_icEFapGik2LJxn7bwp2cDgUJ216rqxNnlpEw1ICPZ7mAFR6AA.",
  "sid": "00abff59-8220-3605-d3a8-e61f2b5d3861",
  "sub": "_aAOkGmW_ADUzQ77HOdbP6_qv-FKOoOtv95sgRkAvF8",
  "tid": "150427fe-46aa-4d8a-8b27-19fb6f0a7670",
  "uti": "lV3-ws-ckUmzkISvftyBAA",
  "ver": "2.0"
}.[Signature]

The guest account in the client’s tenant used above yielded the following error message, which led to the conclusion that under the current LAPSWebUI configuration, authorization decisions were taken based on the claim preferred_username. That claim is mutable and under some circumstances controlled by the user.

Error message with the following text: LAPSWebUI has encountered the following error: One or more errors occurred. (Resource 'laban.please-no-spam@reversec.com' does not exist or one of its queried reference-property objects are not present.)

Microsoft identity platform’s ID token claims reference says the following about the preferred_username claim:

The primary username that represents the user. It could be an email address, phone number, or a generic username without a specified format. Its value is mutable and might change over time. Since it's mutable, this value can't be used to make authorization decisions. It can be used for username hints and in human-readable UI as a username. The profile scope is required to receive this claim. Present only in v2.0 tokens.

That sounded serious. If we set up our own Entra ID test tenant, we can control the preferred_username. We can let the users sign in with non-UPN email addresses by enabling the Connect Sync setting Email as an alternate login ID and setting proxy addresses for the users (see Sign-in to Microsoft Entra ID with email as an alternate login ID). We hoped to be able to trick Microsoft into signing a JWT when logging in as a guest user and being able to control the preferred_username claim and set it to match some arbitrary user’s email address (and UPN) in the client’s tenant, but it was unsuccessful. We spent several hours with this and the conclusions were:

  • The ID token claim preferred_username was included by default for guest accounts (we had to add it as an optional claim in the test application in our test tenant in order to see it)
  • Within our own test tenant, when Email as alternate login ID was used (one logs in with a non-UPN), there was no claim preferred_username in the ID token
  • Across tenants, when Email as alternate login ID was used (one logs in with a non-UPN), the claim preferred_username was there but always set to the UPN
  • The two latter behaviours might be a recent Microsoft response to nOAuth (June 2023) and some nOAuth follow-up by Semperis (June 2025)

We tried some TOCTOU attacks as well (Time-of-check to time-of-use), flipping the Email as alternate login ID switch at different points in time. For instance after logging in to the application in our account but before logging in with the corresponding guest account to the target application in the target tenant. We also tried flipping the switch while the second authentication waited for confirmation by the Authenticator app. We never succeeded getting an ID token for the target application with a preferred_username claim that contained anything else than our test tenant’s domain.

So probably we were a bit too late to discover this application which maybe was vulnerable 1-3 years ago. ¯_(ツ)_/¯

One-Character HTML Injection

This “problem” was not reported to Truesec in December since we could not exploit it, but we shared it with them anyway 2026-Jan-14:

By the way, there is an additional small problem that I spent too much time trying to exploit. I think you want to fix it in a future version anyway since the solution is so simple. When printing the password for an account, it’s done twice in the HTML code. First the whole password, and then it’s properly HTML encoded. But it’s also printed character-by-character. Here HTML encoding is missing. This theoretically leads to HTML injection, but only one character at a time. I failed to bypass restrictions so I could never get XSS, which was the plan. (By controlling what password was sent by one’s own computer to Intune/Entra, the idea was to XSS an admin that had access to LAPS for many computers. A prerequisite would be that your recommended CSP was not in place.)

We spent hours setting up Burp interception of the client computer’s communication with netsh winhttp set proxy 127.0.0.1:8080, using the PowerShell cmdlet Reset-LapsPassword (documentation) to trigger rotation of the computer’s local admin password to figure out the communication with the Entra endpoint https://enterpriseregistration.windows.net/manage/[REDACTED GUID]/lapsdevicepasswordupdate/[REDACTED GUID]?api-version=1.0&client-request-id={[REDACTED GUID]}&return-client-request-id={[REDACTED GUID]} to be able to fake the password sent to Entra and include various Cross-Site Scripting (XSS) payloads, but we could never use the one-character HTML injection to trigger XSS.

LAPSWebUI showing the password "<script>alert(1)</script>"

We had saved the above screenshot of an early XSS attempt via the LAPS password retrieved by LAPSWebUI, but we did not save the corresponding HTML code. It’s reconstructed below from how another password with special characters was represented. The complete password was correctly HTML encoded in the data-pass attribute of the <code> tag, but the individual password characters in the <span> tags were not:

<code id="code" data-pass="&#x3C;script&#x3E;alert&#x28;1&#x29;&#x3C;&#x2F;script&#x3E;">
  <span class='code-character'><</span>
  <span class='code-character'>s</span>
  <span class='code-character'>c</span>
  <span class='code-character'>r</span>
  <span class='code-character'>i</span>
  <span class='code-character'>p</span>
  <span class='code-character'>t</span>
  <span class='code-character'>></span>
  <span class='code-character'>a</span>
  <span class='code-character'>l</span>
  <span class='code-character'>e</span>
  <span class='code-character'>r</span>
  <span class='code-character'>t</span>
  <span class='code-character'>(</span>
  <span class='code-number'>1</span>
  <span class='code-character'>)</span>
  <span class='code-character'><</span>
  <span class='code-character'>/</span>
  <span class='code-character'>s</span>
  <span class='code-character'>c</span>
  <span class='code-character'>r</span>
  <span class='code-character'>i</span>
  <span class='code-character'>p</span>
  <span class='code-character'>t</span>
  <span class='code-character'>></span>
</code>

Maybe this one-character HTML injection vulnproblem will be fixed in an upcoming version of LAPSWebUI.

Responsible Disclosure Policy

Reversec follow our own vulnerability disclosure policy along with the vendors’ disclosure policies. It is important to adhere to these policies in order to protect our clients, the users of these products and the vendor.

Truesec have not disclosed any LAPSWebUI vulnerability information publicly or requested any CVE IDs for the vulnerabilities. We got this statement, approved for publication by them 2026-Mar-06:

Truesec maintains a direct working relationship with all organizations using LAPSWebUI as part of their consultancy engagements. Guidance and support regarding the version 2.4 update have been provided directly to all affected parties.

At Reversec we think that public security advisories are important for the cybersecurity industry. If a competitor makes a security assessment for one of the companies which uses LAPSWebUI and they forgot to install the updated version or didn’t prioritise it, it is important that there is public information available about the vulnerabilities and the fixed version. Therefore we registered CVEs for the vulnerabilities ourselves (see IDs below).

(Also, the author had only one CVE with his name on it before. 😉)

Advisory Links