
Exploit para CVE-2021-21239: bypass de validação de assinatura SAML em pysaml2/Redash. Forja respostas SAML com chaves públicas incorporadas para personificar usuários e escalar privilégios via provisionamento JIT.
Security Assertion Markup Language (SAML) é um padrão aberto para troca de dados de autenticação e autorização entre partes em um sistema de identidade federada. Ele permite o single sign-on (SSO) entre domínios. Os principais componentes são:
Em um fluxo SAML típico, o SP redireciona o usuário para o IdP para autenticação. O IdP retorna uma resposta SAML assinada contendo asserções sobre o usuário (ex.: e-mail, nome). O SP valida a assinatura e provisiona ou autentica o usuário.
CVE-2021-21239 é uma vulnerabilidade de bypass na validação de assinaturas na biblioteca pysaml2 (versões <6.5.0), usada pelo Redash <=10.1.0 para SAML SSO. Em um nível alto, ela permite que um atacante forje uma resposta SAML com uma chave pública incorporada arbitrária, possibilitando a suplantação de usuários e escalonamento de privilégios por meio do provisionamento just-in-time (JIT).
A vulnerabilidade decorre de como o pysaml2 invoca o xmlsec1 para verificar assinaturas SAML. O , por padrão, prefere chaves públicas incorporadas no da resposta SAML em vez do certificado configurado do IdP. Um atacante pode criar uma resposta SAML com um par de chaves RSA gerado por ele, incorporar a chave pública em e assinar a asserção com a chave privada. Como o pysaml2 não restringe o a utilizar apenas o certificado confiável do IdP, a assinatura forjada é considerada válida, permitindo que o atacante entre como qualquer usuário (ex.: admin) e obtenha os maiores privilégios.
Xmlsec1<ds:KeyInfo><ds:RSAKeyValue>xmlsec1No nível de código, a vulnerabilidade existe no sigver.py do pysaml2 (função check_signature). A lista de comandos do xmlsec1 não inclui a opção --enabled-key-data raw-x509-cert, permitindo que o xmlsec1 use chaves incorporadas não confiáveis:
com_list = [
self.xmlsec, '--verify', '--enabled-reference-uris', 'empty,same-doc',
'--pubkey-cert-pem', cert_file_name,
'--id-attr:%s' % id_attr, node_name,
'--node-id', nodeid, '--output', output_file_name, xml_file_name
]
Isso permite ataques em que o atacante modifica o e-mail em <saml:NameID> para suplantar qualquer usuário, aproveitando o provisionamento JIT.
Para testar o exploit, uma instância local do Redash (v10.1.0 ou anterior) é iniciada usando Docker Compose. A configuração envolve definir o SAML SSO com o IdP do Google:
Essa configuração permite testar a resposta SAML forjada enviada por meio de um script Python ou Burp Suite, verificando o escalonamento de privilégios.
A vulnerabilidade surge porque a invocação do xmlsec1 pelo pysaml2 permite que chaves incorporadas sejam usadas para verificação, contornando o certificado confiável do IdP. Um atacante gera um par de chaves RSA, cria uma resposta SAML com a chave pública em <ds:RSAKeyValue>, modifica atributos (ex.: e-mail para o do admin) e assina a asserção. O Xmlsec1 verifica usando a chave incorporada, considerando-a válida.
A correção foi implementada no pysaml2 v6.5.0 (commit inicial em 17 de janeiro de 2021) em src/saml2/sigver.py. A lista de comandos do xmlsec1 foi atualizada para incluir --enabled-key-data raw-x509-cert, restringindo a verificação ao certificado configurado do IdP:
com_list = [
self.xmlsec, '--verify', '--enabled-reference-uris', 'empty,same-doc',
'--pubkey-cert-pem', cert_file_name,
'--enabled-key-data', 'raw-x509-cert',
'--id-attr:%s' % id_attr, node_name,
'--node-id', nodeid, '--output', output_file_name, xml_file_name
]
Isso impõe a validação da cadeia de confiança, impedindo o uso de chaves incorporadas. O Redash corrigiu isso atualizando o pysaml2 em versões posteriores (ex.: v11+). As versões vulneráveis não usavam --insecure; o bug era a opção de restrição ausente.
O código do exploit está implementado no cve-2021-21239.py. Este script Python automatiza o processo de forjar uma resposta SAML para explorar a CVE-2021-21239 no Redash <=10.1.0, permitindo suplantação de usuários e escalonamento de privilégios via provisionamento JIT. O exploit visa o IdP SAML do Google Workspace, mas o ataque foi testado com outros IdPs (keycloak). O script executa as seguintes etapas:
email="[email protected]").idpid do endpoint de login SAML do Redash se não for fornecido, garantindo compatibilidade com a configuração do alvo.SAMLResponseTempalte.xml) com espaços reservados para e-mail, nomes, carimbos de data/hora e ID da asserção. Carimbos de data/hora UTC dinâmicos são gerados com uma janela de validade de 5 minutos para passar na validação do Redash.xmlsec para assinar o elemento <saml:Assertion> com RSA-SHA256, incorporando a chave pública em <ds:RSAKeyValue> para explorar a vulnerabilidade./saml/callback?org_slug=default).Explorar a CVE-2021-21239 exigiu forjar uma resposta SAML que o Redash aceitasse via provisionamento JIT. Principais dificuldades e contornos:
<ds:RSAKeyValue>, assinando com a chave privada.xmlsec1 funcionaram, mas a biblioteca Python xmlsec causava incompatibilidades de digest devido a problemas de espaços em branco/canonicalização. Contornado ao serializar o XML em uma única linha (etree.tostring(..., pretty_print=False)) antes de assinar.NotOnOrAfter muito no futuro causava rejeição; contornado usando carimbos de data/hora UTC dinâmicos com validade de 5 minutos.SAMLResponse duas vezes, causando falhas de parsing; contornado enviando dados de formulário brutos.Esses desafios destacam a necessidade de manipulação precisa de XML e configuração de ambiente para explorar a vulnerabilidade com eficácia. O código do exploit fornecido demonstra isso com sucesso, forjando uma resposta SAML para suplantar usuários e obter acesso.