CVE-2026-48558: Verified Repro With Script Download
CVE-2026-48558: SimpleHelp OIDC authentication accepts unsigned/forged ID tokens, enabling remote authentication bypass and possible MFA bypass in versions 5.5.15 and earlier and 6.0 prereleases prior to the fixed release.
CVE-2026-48558 is verified against SimpleHelp · other (commercial, Java-based server application). Affected versions: SimpleHelp 5.5.15 and earlier; 6.0 prerelease versions before 6.0 RC2. Fixed in 5.5.16; 6.0 RC2 / 6.0 prerelease (20260327-150806). Vulnerability class: Auth Bypass. This critical reproduction includes runnable sandbox proof, artifacts, and a plain-text agent view under REPRO-2026-00222.
What Is CVE-2026-48558?
CVE-2026-48558 is a critical authentication bypass (CWE-347, CVSS 9.5) in SimpleHelp's OpenID Connect (OIDC) login flow, which fails to verify the cryptographic signature on submitted ID tokens, letting an unauthenticated remote attacker forge a fully authenticated technician session. Pruva reproduced it (reproduction REPRO-2026-00222).
CVE-2026-48558 Severity & CVSS Score
CVE-2026-48558 is rated critical severity, with a CVSS base score of 9.5 out of 10.
Critical — the most severe class — typically remotely exploitable with severe impact. Treat as an emergency.
Affected SimpleHelp Versions
SimpleHelp · other (commercial, Java-based server application) versions SimpleHelp 5.5.15 and earlier; 6.0 prerelease versions before 6.0 RC2 are affected.
How to Reproduce CVE-2026-48558
pruva-verify REPRO-2026-00222 curl -O https://pruva.dev/api/v1/reproductions/REPRO-2026-00222/artifacts/bundle/repro/reproduction_steps.sh && chmod +x reproduction_steps.sh && ./reproduction_steps.sh Proof of Reproduction for CVE-2026-48558
- reached the target end-to-end
- full exploit chain demonstrated
- on the real production code path
- high confidence
- the upstream fix blocks the same trigger
forged OIDC ID token with alg:none, bogus signature, and attacker technician claims
- HTTPS /auth/v1/account/oidc_get to real /oidc callback with server-issued state
reproduction_steps.sh Azure/Entra OIDC direct form_post id_token callback is an alternate vulnerable-version trigger for the same SimpleHelp ID-token signature-verification bug, but patched 5.5.16 rejects it; no fixed-version bypass was confirmed.
How the agent worked
Root Cause and Exploit Chain for CVE-2026-48558
- Affected versions: SimpleHelp 5.5.15 and earlier, and 6.0 prerelease builds before the fixed release.
- Patched versions tested: SimpleHelp 5.5.16 (
SimpleHelp-linux-amd64.tar.gz, SHA2569360af980277e1ef4330eb1ed08d981c9dfdcc4e25d87ed0552a47f5ebd5161a). - Risk level and consequences: Critical. A remote unauthenticated attacker can authenticate as a group-authenticated technician using forged identity claims. A technician account can access the SimpleHelp technician console and, depending on group permissions and deployment, remote support / remote access capabilities.
Impact Parity
- Disclosed/claimed maximum impact: Remote authentication/authorization bypass via forged OIDC token, yielding an authenticated technician session and potential MFA bypass.
- Reproduced impact from this run: Full remote API/OIDC authentication bypass on the real SimpleHelp 5.5.15 server. The script obtains a legitimate pending OIDC state from the product API, submits a forged ID token through the genuine
/oidccallback, and observesFULLY_AUTHENTICATEDstatus for the attacker-controlled technician identity. - Parity:
full - Not demonstrated: Post-auth remote-control actions against managed endpoints were not performed; the reproduced impact stops at a concrete authenticated technician session and technician-console page access.
Root Cause
The vulnerable SimpleHelp OIDC implementation parses JWT claims from the ID token but does not cryptographically verify the token signature before using those claims for technician authentication. Runtime/class evidence shows that SimpleHelp 5.5.15 includes utils/oauth/oidc/IDToken.class and OIDC callback classes, but no IDTokenVerifier class. The patched 5.5.16 build adds utils/oauth/oidc/IDTokenVerifier.class and related JWKS caching classes, and its callback rejects the same forged token.
The key behavioral difference is:
- 5.5.15 vulnerable: The forged token reaches
OIDCAuthenticator, is parsed into anIDToken, passes group-authentication logic, registers a new anonymous/group-authenticated technician, and registers a session token. - 5.5.16 patched: The same forged token causes the callback to fail closed; the status endpoint remains
UNAUTHENTICATED.
No public fix commit hash was provided in the ticket because SimpleHelp is a commercial binary distribution; the script anchors the negative control to the vendor fixed 5.5.16 release identified in the advisory.
Reproduction Steps
- Run
bundle/repro/reproduction_steps.sh. - The script:
- Verifies/downloads the official SimpleHelp 5.5.15 and 5.5.16 Linux server tarballs.
- Extracts clean vulnerable and patched server instances.
- Initializes each real SimpleHelp server through the first-launch path.
- Configures a real OIDC authentication provider and a non-admin
Technicianstechnician group that allows group-authenticated/OIDC-created logins. - Starts a local fake OIDC IdP that returns a JWT with
alg: noneand a bogus signature segment. - Requests a real OIDC authorization URL from
https://127.0.0.1/auth/v1/account/oidc_get, preserving the server-issuedstate. - Delivers the forged token through the genuine
https://127.0.0.1/oidc?code=...&state=...callback. - Checks
https://127.0.0.1/auth/v1/account/statusas the post-login authorization proof. - Repeats the same flow against patched 5.5.16 as the negative control.
- Expected evidence:
- Vulnerable flow:
status_after_bodycontains"state":"FULLY_AUTHENTICATED"and the forged identity (Forged Attacker,attacker,attacker@example.com). - Patched flow: callback contains
Login Failedand status remains"state":"UNAUTHENTICATED".
- Vulnerable flow:
Evidence
Primary evidence files:
bundle/logs/reproduction_steps.log— full script stdout/stderr for the successful run.bundle/logs/vuln_flow.json— vulnerable HTTP/API/OIDC flow result.bundle/logs/patched_flow.json— patched negative-control flow result.bundle/logs/vuln_idp.log— fake IdP requests and the forged ID token returned to the product.bundle/logs/patched_idp.log— same forged-token IdP interaction for patched version.bundle/logs/vuln_runtime_tail.log— vulnerable server runtime log excerpts.bundle/logs/patched_runtime_tail.log— patched server runtime log excerpts.bundle/logs/class_comparison.log— class-level fix comparison showingIDTokenVerifierabsent in 5.5.15 and present in 5.5.16.bundle/repro/runtime_manifest.json— runtime evidence manifest written by the reproduction script.
Key excerpts from the successful run:
// bundle/logs/vuln_flow.json
"status_after_body": "{\"state\":\"FULLY_AUTHENTICATED\",\"user\":{\"uniqueID\":480346,\"displayName\":\"Forged Attacker\",\"username\":\"attacker\",\"emailAddress\":\"attacker@example.com\",\"isOnline\":true},\"code\":1}"
// bundle/logs/patched_flow.json
"callback_contains_login_failed": true,
"status_after_body": "{\"state\":\"UNAUTHENTICATED\",\"code\":0}"
// bundle/logs/vuln_runtime_tail.log
[OIDCAuthenticator] Received OIDC response (...)
[ProxyServerAuthentication] Group authenticated technician via group 'Technicians'
[ServerConfig] Registering technician login for attacker / (Technicians)
[Server Config] Configuration save requested (Forged Attacker - attacker [(Technicians)] [New Anon])
[ProxyServerAuthentication] Registering session token for Forged Attacker - attacker [(Technicians)] (...)
// bundle/logs/class_comparison.log
[*] Vulnerable OIDC classes
7852 ... utils/oauth/oidc/IDToken.class
6340 ... com/aem/shelp/proxy/wds/OIDCCallbackManager.class
[*] Patched OIDC classes
8796 ... utils/oauth/oidc/IDToken.class
252 ... utils/oauth/oidc/IDTokenVerifier$1.class
1660 ... utils/oauth/oidc/IDTokenVerifier$CachedJwks.class
17996 ... utils/oauth/oidc/IDTokenVerifier.class
Environment details captured in logs include SimpleHelp server version/build (5.5.15 build 20260326-092709, patched 5.5.16 build 20260526-203544), bundled JRE versions, HTTPS listener startup, and the exact API/callback URLs exercised.
Recommendations / Next Steps
- Upgrade SimpleHelp servers to 5.5.16 or later, or to the fixed 6.0 release/RC identified by the vendor.
- Ensure OIDC ID tokens are validated using issuer metadata/JWKS before any claims are trusted:
- Verify the JWT signature.
- Reject
alg: noneor unsupported algorithms. - Validate
iss,aud,exp,iat, and nonce/state binding.
- Add regression tests that submit unsigned and incorrectly signed ID tokens through the real
/oidccallback and assert rejection. - Audit existing SimpleHelp deployments for unexpected group-authenticated/anonymous technician accounts, especially identities created via OIDC.
Additional Notes
- The script was run successfully twice consecutively after the escaping/configuration fix.
- The reproduction uses the real SimpleHelp server binaries and real HTTPS API/callback paths; the only test double is the OIDC identity provider, which is attacker-controlled by design for this class of vulnerability.
- The script rewrites the IdP redirect host to
127.0.0.1after preserving the SimpleHelp-issued callback path,code, andstate, because the product derives a public hostname from its local environment. This keeps the callback on the genuine SimpleHelp/oidcendpoint while avoiding external DNS/network dependence.
Variant Analysis & Alternative Triggers for CVE-2026-48558
Fix Coverage / Assumptions
The vendor fix appears to rely on a new invariant: every ID token consumed by the OIDC callback/authentication path must be cryptographically verified before claims are trusted for group-authenticated technician login. Because SimpleHelp is distributed as commercial binaries, no public source commit was available. Runtime and class comparison evidence shows the following binary-level changes between 5.5.15 and 5.5.16:
utils/oauth/oidc/IDTokenVerifier.classand supporting JWKS cache classes are absent in 5.5.15 and present in 5.5.16.com/aem/shelp/proxy/wds/OIDCCallbackManager.classgrows from 6,340 bytes to 10,556 bytes and gainsOIDCCallbackManager$ActiveOIDCCallback.classandOIDCCallbackManager$OIDCTestResult.class.com/aem/shelp/proxy/authentication/oidc/OIDCAuthenticator.classgrows from 6,188 bytes to 7,244 bytes.com/aem/shelp/proxy/config/authentication/AzureAuthenticationProvider.classgrows from 3,860 bytes to 8,580 bytes.
The code paths explicitly covered by the tested fix include both:
- The generic OIDC authorization-code callback used in the parent reproduction.
- The Azure/Entra implicit/direct ID-token form-post callback tested in this variant stage.
The tested fix did not leave an observable gap for the alternate Azure/Entra path. Both the generic and Azure paths use the same /oidc callback and downstream OIDCAuthenticator / group-authentication sink, and 5.5.16 fails closed before creating a technician session.
The target's stated security scope matches this testing: the vendor advisory states that vulnerable configurations are SimpleHelp servers with an enabled OIDC Authentication Service, including OIDC-based categories labelled Active Directory, Azure, and OpenID Connect, plus a Technician Group with the OIDC service enabled and "Allow group authenticated logins" enabled. It also states that 5.5.16 and the public/fixed 6.0 release are not affected. The variant test stayed within that threat model: the input is remote unauthenticated login traffic crossing the SimpleHelp technician-authentication trust boundary, not a local/self-attacking configuration file issue.
Variant / Alternate Trigger
Tested alternate trigger: Azure/Entra-style OIDC implicit/direct ID-token callback.
- Entry point 1:
GET https://127.0.0.1/auth/v1/account/login_options - Entry point 2:
GET https://127.0.0.1/auth/v1/account/oidc_get?payload=... - Entry point 3:
POST https://127.0.0.1/oidcwith form fields:state=<server-issued state>id_token=<attacker-forged JWT with alg:none and bogus signature>
- Status proof endpoint:
GET https://127.0.0.1/auth/v1/account/status
This differs materially from the parent reproduction because no fake token endpoint is contacted and no authorization code is exchanged. SimpleHelp itself generates an Azure/Entra authorization URL with response_type=id_token, response_mode=form_post, and a nonce; the variant then forges the direct callback payload that an identity provider would post back. The vulnerable server accepts the forged claims as the identity of azure-attacker@example.com / Forged Azure Attacker.
Relevant code/class anchors from the binary inspection:
com/aem/shelp/proxy/config/authentication/AzureAuthenticationProvider.class— Azure/Entra provider; vulnerable javap evidence showsgetResponseType()returnsid_tokenandcreateAuthenticationMetadata()addsresponse_mode=form_post.com/aem/shelp/proxy/wds/OIDCCallbackManager.class—/oidccallback manager.com/aem/shelp/proxy/authentication/oidc/OIDCAuthenticator.class— OIDC callback/token-to-login authenticator.utils/oauth/oidc/IDToken.class— parses ID-token claims.utils/oauth/oidc/IDTokenVerifier.class— absent in 5.5.15 and present in 5.5.16.com/aem/shelp/proxy/ProxyServerAuthentication.class— downstream group-authenticated technician login sink.Affected version tested: SimpleHelp 5.5.15, build
20260326-092709, official Linux tarball SHA25626cd904ebf78ac4b2c5b99f6a9659a562390777dc8fe730469e2ecfc8ad139ab.Fixed version tested: SimpleHelp 5.5.16, build
20260526-203544, official Linux tarball SHA2569360af980277e1ef4330eb1ed08d981c9dfdcc4e25d87ed0552a47f5ebd5161a.Risk level and consequences on vulnerable builds: Critical authentication bypass. In the tested vulnerable configuration, a remote unauthenticated attacker can become a fully authenticated technician through the Azure/Entra OIDC option if OIDC group-authenticated logins are enabled and login IP restrictions permit the source address.
Impact Parity
- Disclosed/claimed maximum impact for the parent: remote authentication bypass and possible MFA bypass via forged OIDC identity token, yielding a technician session.
- Reproduced impact from this variant run: on SimpleHelp 5.5.15, the Azure/Entra direct ID-token callback produces
FULLY_AUTHENTICATEDstatus forForged Azure Attacker/azure-attacker@example.comwithout a valid identity-provider signature. - Parity:
fullfor the vulnerable-version alternate trigger;noneas a fixed-version bypass because patched 5.5.16 rejects the same forged direct-ID-token callback. - Not demonstrated: post-auth remote-control actions against managed endpoints were not performed. The proof stops at authenticated technician-session creation and status-page authorization evidence.
Root Cause
The same underlying vulnerable sink can be reached in SimpleHelp 5.5.15 from the Azure/Entra OIDC path because the vulnerable implementation parses and trusts an ID token before verifying its signature. For Azure/Entra providers, AzureAuthenticationProvider.getResponseType() returns id_token and the provider adds response_mode=form_post; this causes /auth/v1/account/oidc_get to create an authorization URL where the identity token is returned directly to /oidc, instead of being obtained from a token endpoint after a code exchange. In 5.5.15, posting a forged JWT with alg:none, a bogus signature segment, matching aud, and the server-issued nonce/state reaches the same OIDCAuthenticator and ProxyServerAuthentication group-authentication path as the parent reproduction.
The fix commit is not public. The tested vendor fixed binary, 5.5.16, adds utils/oauth/oidc/IDTokenVerifier.class and rejects the forged Azure/Entra direct callback. This indicates the fix enforces signature/JWKS validation before the parsed IDToken is accepted by group authentication.
Reproduction Steps
- Run
bundle/vuln_variant/reproduction_steps.sh. - The script:
- Verifies the official SimpleHelp 5.5.15 and 5.5.16 Linux tarball SHA256 values, reusing the downloaded repro artifacts if present.
- Extracts clean vulnerable and patched server instances under
bundle/vuln_variant/runtime-azure-implicit/. - Initializes each SimpleHelp server through first launch.
- Configures an Azure/Entra-style OIDC authentication provider (
type="oidc_azure") and a non-admin Technician Group with group-authenticated logins enabled. - Requests a real SimpleHelp OIDC authorization URL through
/auth/v1/account/oidc_get. - Confirms the server-generated Azure authorization URL uses
response_type=id_token,response_mode=form_post,state, andnonce. - Posts a forged unsigned/bogus-signature ID token directly to
/oidcwith the server-issuedstate. - Checks
/auth/v1/account/statusto determine whether a technician session was created. - Repeats the same test against patched 5.5.16.
- Expected evidence:
- Vulnerable 5.5.15:
bundle/logs/vuln_variant/azure_vuln_flow.jsoncontains"state":"FULLY_AUTHENTICATED"and the forged Azure identity. - Patched 5.5.16:
bundle/logs/vuln_variant/azure_patched_flow.jsoncontains aLogin Failedcallback and"state":"UNAUTHENTICATED". - Script exit:
1, because the alternate trigger is vulnerable-only and did not bypass fixed 5.5.16.
- Vulnerable 5.5.15:
Evidence
Primary evidence files:
bundle/logs/vuln_variant/reproduction_steps.log— full output from the second idempotency run of the variant script.bundle/logs/vuln_variant/azure_vuln_flow.json— vulnerable Azure/Entra direct-ID-token flow result.bundle/logs/vuln_variant/azure_patched_flow.json— patched negative-control result.bundle/logs/vuln_variant/azure_flow_summary.json— structured variant summary.bundle/logs/vuln_variant/azure_vuln_runtime_tail.log— vulnerable server runtime tail showing group-authenticated login/session registration.bundle/logs/vuln_variant/azure_patched_runtime_tail.log— patched server runtime tail.bundle/logs/vuln_variant/azure_class_comparison.log— class-level comparison showing verifier addition and Azure/OIDC class changes.bundle/logs/vuln_variant/fixed_version.txt— exact fixed binary identity tested.bundle/vuln_variant/runtime_manifest.json— runtime evidence manifest.
Key evidence excerpt from azure_flow_summary.json:
{
"vulnerable_auth_url_direct_id_token_flow": true,
"vulnerable_status_fully_authenticated": true,
"patched_has_IDTokenVerifier_class": true,
"patched_status_fully_authenticated": false,
"patched_failed_closed": true,
"vulnerable_status_after": "{\"state\":\"FULLY_AUTHENTICATED\",\"user\":{\"displayName\":\"Forged Azure Attacker\",\"username\":\"azure-attacker\",\"emailAddress\":\"azure-attacker@example.com\"...}}",
"patched_status_after": "{\"state\":\"UNAUTHENTICATED\",\"code\":0}"
}
Key class-comparison excerpt from azure_class_comparison.log:
[*] Vulnerable Azure/OIDC-relevant classes
com/aem/shelp/proxy/config/authentication/AzureAuthenticationProvider.class
utils/oauth/oidc/IDToken.class
com/aem/shelp/proxy/wds/OIDCCallbackManager.class
com/aem/shelp/proxy/authentication/oidc/OIDCAuthenticator.class
[*] Patched Azure/OIDC-relevant classes
com/aem/shelp/proxy/config/authentication/AzureAuthenticationProvider.class
utils/oauth/oidc/IDTokenVerifier.class
com/aem/shelp/proxy/wds/OIDCCallbackManager.class
com/aem/shelp/proxy/authentication/oidc/OIDCAuthenticator.class
The script was executed twice. Both runs completed deterministically with exit code 1, which is the expected stage result for "alternate trigger works on vulnerable build but no fixed-version bypass was found."
Recommendations / Next Steps
- Keep the fix centralized at the ID-token acceptance boundary. Every route that constructs or receives an
IDTokenmust call the verifier before exposing claims toOIDCAuthenticator, group filters, account lookup/linking, or technician-session creation. - Add regression tests for both materially different OIDC modes:
- Generic authorization-code callback where
/oidcreceivescodeand the server obtainsid_tokenfrom/token. - Azure/Entra direct callback where
/oidcreceives a form-postedid_tokendirectly.
- Generic authorization-code callback where
- Regression tests should reject
alg:none, bogus signatures, missing/empty JWKS, mismatchedkid, wrongiss, wrongaud, expiredexp, and nonce/state mismatches. - Ensure Azure/Entra-specific validation uses the correct issuer/JWKS metadata for the configured tenant and does not silently fall back to claim-only parsing if metadata retrieval fails.
- Continue documenting operational mitigations from the vendor advisory: disable OIDC group-authenticated logins if patching is delayed, enforce technician login IP restrictions, and audit newly created OIDC/anonymous technician accounts.
Additional Notes
- Idempotency confirmed:
bundle/vuln_variant/reproduction_steps.shwas run twice consecutively and completed both times with the expected exit code1. - The variant uses the real SimpleHelp server binaries and real HTTPS
/auth/v1/account/oidc_get,/oidc, and/auth/v1/account/statusendpoints. No source checkout was modified. - The only synthetic input is the forged ID token, which models the attacker-controlled OIDC response at the trust boundary described by the vendor advisory.
- No fixed-version bypass was found in the tested 5.5.16 Linux server build.
CVE-2026-48558 Reproduction Transcript
The agent's step-by-step process — every tool call, every handoff, the moment the exploit fired.
Full session Replay every step — scrub the timeline or play it back.
Artifacts and Evidence for CVE-2026-48558
Scripts, logs, diffs, and output captured during the reproduction.
How to Fix CVE-2026-48558
Upgrade SimpleHelp · other (commercial, Java-based server application) to 5.5.16; 6.0 RC2 / 6.0 prerelease (20260327-150806) or later.
FAQ: CVE-2026-48558
How does the CVE-2026-48558 OIDC bypass attack work?
alg: none JWT at the /oidc callback and creates a fully authenticated technician session for whatever identity the attacker put in the token claims — demonstrated in the reproduction with a forged identity of "attacker" / "Forged Attacker" — without ever validating the token's signature.Which SimpleHelp versions are affected by CVE-2026-48558, and where is it fixed?
How severe is CVE-2026-48558?
How can I reproduce CVE-2026-48558?
References for CVE-2026-48558
Authoritative sources for CVE-2026-48558 — official vulnerability databases and the upstream advisory. Pruva's reproduction verifies the issue firsthand; these are the primary records to corroborate it.