# Patch Analysis for CVE-2026-48558 Variant Stage

## Scope and threat model

The relevant trust boundary is remote technician authentication. An unauthenticated network client can initiate an OIDC technician login and cause SimpleHelp to process an OIDC response at `/oidc`. The vendor's May 2026 advisory explicitly treats this as in-scope when all of the following are true:

- SimpleHelp 5.5.15 or earlier, or affected 6.0 prerelease builds, are in use.
- An OIDC Authentication Service is configured and enabled. The vendor states the OIDC-based categories are labelled **Active Directory**, **Azure**, and **OpenID Connect**.
- One or more Technician Groups have the OIDC Authentication Service enabled and **Allow group authenticated logins** enabled.
- Technician login IP restrictions and any group authentication filters permit the login source/claims.

The vendor also states that servers without OIDC, or without OIDC group-authenticated logins, cannot be exploited this way, and that SimpleHelp 5.5.16 / fixed 6.0 releases are not affected. The variant analysis stayed inside that threat model: the malicious input is a remote OIDC login response crossing the technician-authentication boundary, not a local configuration or self-loaded file.

## What the fix changes

No public source commit or diff is available because SimpleHelp is a commercial binary distribution. The patch was therefore analyzed by comparing official Linux server release artifacts:

- Vulnerable: SimpleHelp 5.5.15, build `20260326-092709`, SHA256 `26cd904ebf78ac4b2c5b99f6a9659a562390777dc8fe730469e2ecfc8ad139ab`.
- Fixed: SimpleHelp 5.5.16, build `20260526-203544`, SHA256 `9360af980277e1ef4330eb1ed08d981c9dfdcc4e25d87ed0552a47f5ebd5161a`.

Binary/class comparison shows these relevant changes:

- `utils/oauth/oidc/IDTokenVerifier.class` is **absent** in 5.5.15 and **present** in 5.5.16, with supporting `IDTokenVerifier$CachedJwks.class` and `IDTokenVerifier$1.class`.
- `utils/oauth/oidc/IDToken.class` changes from 7,852 bytes to 8,796 bytes.
- `com/aem/shelp/proxy/wds/OIDCCallbackManager.class` changes from 6,340 bytes to 10,556 bytes, and patched 5.5.16 adds `OIDCCallbackManager$ActiveOIDCCallback.class` and `OIDCCallbackManager$OIDCTestResult.class`.
- `com/aem/shelp/proxy/authentication/oidc/OIDCAuthenticator.class` changes from 6,188 bytes to 7,244 bytes.
- `com/aem/shelp/proxy/config/authentication/AzureAuthenticationProvider.class` changes from 3,860 bytes to 8,580 bytes.

Runtime behavior confirms the functional effect:

- In 5.5.15, forged ID-token claims are accepted and passed into group-authenticated technician login.
- In 5.5.16, the same forged token is rejected and the session remains `UNAUTHENTICATED`.

## Fix assumptions / security invariant

The apparent security invariant in 5.5.16 is: **no ID-token claims may be trusted until the token has been cryptographically verified against the configured issuer/provider metadata/JWKS and validated for the intended client and callback context.**

A complete fix for this vulnerability must cover all ways an `IDToken` can enter SimpleHelp's OIDC login machinery, including:

1. Generic OIDC authorization-code flow, where `/oidc` receives `code` and `state`, then SimpleHelp obtains `id_token` from the provider's token endpoint.
2. Azure/Entra direct ID-token flow, where `/auth/v1/account/oidc_get` generates an authorization URL with `response_type=id_token`, `response_mode=form_post`, `state`, and `nonce`, and `/oidc` receives the `id_token` directly in the callback body.
3. Any OIDC test/configuration flows that parse ID tokens or user info for administrator validation.
4. Any future direct machine / remote-work OIDC login paths that reuse these provider classes.

The tested 5.5.16 binary appears to apply the invariant to both the parent generic OIDC code flow and the alternate Azure/Entra direct ID-token flow.

## What code paths/inputs the fix covers

The following paths were runtime-tested and covered by the fix:

### Parent path: generic OpenID Connect authorization-code flow

- `GET /auth/v1/account/oidc_get` generates an authorization URL and pending `state`.
- Attacker-controlled IdP receives the authorization request and redirects back to `/oidc?code=...&state=...`.
- SimpleHelp calls the token endpoint and receives a forged `id_token`.
- Vulnerable 5.5.15 authenticates; patched 5.5.16 rejects.

### Variant path: Azure/Entra direct ID-token form-post flow

- `GET /auth/v1/account/oidc_get` generates an Azure/Entra authorization URL containing:
  - `response_type=id_token`
  - `response_mode=form_post`
  - `state=<server-issued UUID>`
  - `nonce=<server-issued UUID>`
- The attacker posts a forged `id_token` directly to `POST /oidc` with the server-issued `state`.
- Vulnerable 5.5.15 authenticates as `Forged Azure Attacker`.
- Patched 5.5.16 returns a Login Failed page and status remains `UNAUTHENTICATED`.

## What paths/inputs were not exhaustively covered

The following were not exhaustively tested because they would require additional licensed/interactive product setup or external identity providers, but they should be covered by the same central verification invariant:

- Real Microsoft Entra tenant metadata and JWKS retrieval with a legitimate tenant ID instead of the local test `common` tenant string.
- OIDC configuration-test UI flows used by administrators.
- Direct machine / Remote Work OIDC logins introduced or expanded in later 6.0 builds.
- Tokens with unsupported but signed algorithms, mismatched `kid`, stale JWKS cache entries, malformed `x5c`, or issuer aliases.
- Tokens with a valid signature but invalid `aud`, `iss`, `exp`, `nbf`, `iat`, `nonce`, or `state` binding.

No evidence was found that these untested paths bypass 5.5.16. They are listed as recommended regression-test coverage because they share the same root cause class: accepting OIDC claims without complete token validation.

## Behavior before and after the fix

### Before fix: 5.5.15

- Generic OIDC code-flow forged token: accepted.
- Azure/Entra direct form-post forged token: accepted.
- Observed impact: `/auth/v1/account/status` reports `FULLY_AUTHENTICATED` and includes attacker-controlled technician identity.
- Relevant logs show group-authenticated technician creation and session-token registration.
- `IDTokenVerifier.class` is absent.

### After fix: 5.5.16

- Generic OIDC code-flow forged token: rejected.
- Azure/Entra direct form-post forged token: rejected.
- Observed impact: callback shows `Login Failed`; `/auth/v1/account/status` reports `UNAUTHENTICATED`.
- `IDTokenVerifier.class` and JWKS cache support classes are present.

## Variant conclusion

A materially distinct alternate trigger was confirmed on the vulnerable version: Azure/Entra OIDC direct ID-token form-post login reaches the same vulnerable sink and creates a technician session on 5.5.15. However, the same alternate trigger does **not** reproduce on patched 5.5.16. Therefore, this stage did **not** find a bypass of the vendor fix. The fix appears complete for the two most important OIDC ID-token ingestion paths tested side by side.

## Evidence references

- `bundle/logs/vuln_variant/azure_class_comparison.log`
- `bundle/logs/vuln_variant/azure_flow_summary.json`
- `bundle/logs/vuln_variant/azure_vuln_flow.json`
- `bundle/logs/vuln_variant/azure_patched_flow.json`
- `bundle/logs/vuln_variant/reproduction_steps.log`
- `bundle/logs/vuln_variant/fixed_version.txt`
