Safely determine whether a Palo Alto Networks PAN-OS GlobalProtect portal is vulnerable to CVE-2026-0265 without authenticating any session or modifying any state.
CVE-2026-0265 is a remote authentication bypass affecting PAN-OS and Panorama that triggers when an authentication profile uses Cloud Authentication Service (CAS). The vulnerable pan_auth_verify function in libpanmp_mp.so dispatches JSON Web Token signature verification purely on the attacker-controlled alg header — a forged JWT with alg=HS256 and HMAC-SHA256(cas_public_key_pem, header.payload) as its signature is accepted as if it were a real RS256-signed CAS token, letting any attacker impersonate any user.
The bug is reachable through two attack surfaces — the GlobalProtect portal (/saml/acs.esp, yields a VPN session) and the management UI (/SAML20/SP/ACS, yields full PAN-OS administrator). This tool covers the GlobalProtect portal surface only.
A single anonymous GET /global-protect/prelogin.esp request reveals everything needed for an authoritative verdict:
- Precondition factor — The prelogin response carries an XML element
<cas-auth>yes|no</cas-auth>set directly by the portal's auth configuration. A value ofyesconfirms the CVE precondition is met for this listener. - Build factor — When CAS is attached, the same response embeds an outbound CAS request token in its
<saml-request>field. Decoding it yields the firewall's authoritative version string, which is then cross-referenced against the vendor advisory's per-base patched-hotfix matrix to produce the verdict. .saasshort-circuit — PA cloud-managed builds are not affected per Palo Alto's clarification (2026-05-21), regardless of the underlying base build number.
The script emits the verdict, the firewall's reported PanOS version (so a defender can sanity-check the assessment against their inventory), and basic triage context (prelogin_status, prelogin_msg, http_status, error notes). If your pipeline needs richer appliance metadata, cross-reference the target URL against your own inventory.
git clone https://github.com/BishopFox/CVE-2026-0265-check
cd CVE-2026-0265-check
pip install requestsRequires Python 3.9+ and the requests package.
Pass one or more targets as positional arguments, via --targets-file, or on stdin. Hostnames and host:port strings are auto-wrapped to https://.
python3 CVE-2026-0265-check.py [options] <target> [<target>...]| Flag | Meaning |
|---|---|
-f, --targets-file FILE |
Read one target per line from FILE |
-t, --timeout SECONDS |
Per-request timeout. Default: 20.0 |
-c, --concurrent N |
Max parallel targets. Default: 5 |
-b, --brief |
Emit <url>\t<verdict>\t<panos_version> per target instead of full JSON |
--user-agent UA |
Override probe User-Agent. The default is a browser-like Chrome string that bypasses gpsvc's GP-client version gate; use a custom UA if you need access-log audit visibility and don't need the version-gated path. |
Default output is one JSON object per target on stdout (jq-friendly).
The script emits one of three classes of verdict per target. Determined verdicts answer the vulnerability question authoritatively for that target. Undetermined verdicts indicate the probe could not reach a conclusion and operator follow-up is required.
| Verdict | When |
|---|---|
VULNERABLE |
CAS attached, PanOSversion strictly below the advisory's patched hotfix for this base, not .saas. |
| Verdict | When |
|---|---|
PATCHED |
CAS attached, PanOSversion at or above the advisory's patched hotfix for this base. |
NOT-AFFECTED-SAAS |
CAS attached but PanOSversion has the .saas suffix (PA cloud-managed; not affected per PA 2026-05-21). |
NOT-AFFECTED-NO-CAS |
Prelogin returned successfully but <cas-auth> indicates SAML / RADIUS / LDAP / local auth. CVE doesn't apply to this listener. |
NOT-AFFECTED-NOT-GLOBALPROTECT |
Response shape isn't a GP portal (e.g. "GlobalProtect portal does not exist"). Out of scope. |
| Verdict | When | Suggested follow-up |
|---|---|---|
UNDETERMINED-VERSION-GATED |
gpsvc returned "CAS is not supported by the client". CAS is attached but the probe was rejected for User-Agent reasons; PanOSversion cannot be read from this response. |
Retry with --user-agent set to a real GP-client string. |
UNDETERMINED-MTLS-GATED |
"Valid client certificate is required" in the prelogin response. Auth surface hidden behind an mTLS gate. | Confirm the build via a separate channel (customer's authoritative version, or a probe with a valid client cert). |
UNDETERMINED-ERROR |
Network failure, malformed response, unparsable PanOSversion, or Token decode failure despite cas-auth=yes. |
Re-run; if persistent, the target is probably not reachable from this position. |
$ python3 CVE-2026-0265-check.py -b -f targets.txt
https://gp1.customer.example VULNERABLE 11.1.6-h23
https://gp2.customer.example PATCHED 11.1.6-h32
https://vpn.cloud.customer.example NOT-AFFECTED-SAAS 11.2.7-h9.saas
https://mgmt.customer.example NOT-AFFECTED-NO-CAS -
https://www.customer.example NOT-AFFECTED-NOT-GLOBALPROTECT -
https://internal-vpn.customer.example UNDETERMINED-MTLS-GATED -
$ python3 CVE-2026-0265-check.py gp.customer.example | jq .
{
"target": "https://gp.customer.example",
"verdict": "VULNERABLE",
"panos_version": "11.1.6-h23",
"prelogin_status": "Success",
"http_status": 200,
"notes": [
"11.1.6-h23 is below the advisory's patched hotfix for this base."
]
}gpsvc rate-limits under back-to-back probing — the script already retries each HTTP 503 with growing backoff, but -c 5 and a moderate -t is friendly to large fleets:
cat all-targets.txt | python3 CVE-2026-0265-check.py -b -c 5The script can produce a determined verdict only when:
- The target is reachable from the operator's vantage point.
- The target is a PAN-OS GlobalProtect portal (responses from non-PAN-OS hosts resolve to
NOT-AFFECTED-NOT-GLOBALPROTECTorUNDETERMINED-ERROR). - The prelogin response is not gated by mTLS (otherwise
UNDETERMINED-MTLS-GATED) or by an aggressive User-Agent check (otherwiseUNDETERMINED-VERSION-GATED).
Distributed under an MIT license.
Usage of this tool for attacking targets without prior mutual consent is illegal. It is the end user's responsibility to obey all applicable local, state, and federal laws. The developers assume no liability and are not responsible for any misuse or damage caused by this program.