Closed ngrosc closed 5 months ago
@DaanHoogland @rhtyd Guys, this looks like a pretty nasty security bug. SAML isn't used by default, but regardless this may be a blocker for 4.15 and 4.14.x.
@kiwiflyer yes let's discuss and understand how the env was setup, I suspect it may related to env configuration.
@ngrosc can you share details of your IDP setup? For example the IDP xml metadata, what IDP server are you using (Shibboleth, keycloak etc). Usually, the SP (CloudStack acts as a service provider in SAML terminology) is not in control of whether the SAML token is encrypted or not, and signing and encryption is enforced by the IDP server. For best practices, IDP servers generally should enforce that both signing and encryption be done and (authn) tokens be signed/encrypted (when this is done correctly we should see the encryption and signing public keys in the IDP metadata xml, for example see https://samltest.id/saml/idp). I think only if encryption is not enforced you'll be able to read/extract/change the token parameters, can you try to enforce encryption in your IDP and try your attack/test again? In case that works then we certainly have a blocker.
CloudStack's SAML support (SP) was implemented and tested against Shibboleth and you may use https://samltest.id/ to test the setup. For doc ref: http://docs.cloudstack.apache.org/en/latest/adminguide/accounts.html#using-a-saml-2-0-identity-provider-for-user-authentication
cc @PaulAngus @DaanHoogland
I did a quick code investigation, looks like when there is no encryption in place we get the unencrypted username (uid
usually) parameter from the SAML token: (if I recall correctly this was done only to allow and test unsecure IDP servers)
https://github.com/apache/cloudstack/blob/master/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java#L241
... however, I'm not sure if changing the whole SAML token/response should fail at https://github.com/apache/cloudstack/blob/master/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java#L232 which was signed by a signature?
However, if the SAML IDP server has encryption enforced (see for example https://wiki.shibboleth.net/confluence/display/IDP30/SecurityConfiguration#SecurityConfiguration-SigningandEncryptionEnablement) we get the username from the encrypted assertion value: https://github.com/apache/cloudstack/blob/master/plugins/user-authenticators/saml2/src/main/java/org/apache/cloudstack/api/command/SAML2LoginAPIAuthenticatorCmd.java#L289
I guess we need exact steps of reproduction if encryption and signing are both enabled. In which case, @ngrosc can you email me privately on rohit AT apache.org? Thanks.
I ran a quick test, this server is SAML enabled: http://primate-qa.cloudstack.cloud:8080/client/master
I tracked both SAML request and response. SAML request (base64 encoded) was encrypted so couldn't decode it, SAML response (base64 encoded) was not but I see the username attribute is not plaintext in the XML as encryption in enforced:
<?xml version="1.0" encoding="UTF-8"?>
<saml2p:Response Destination="http://primate-qa.cloudstack.cloud:8080/client/api?command=samlSso" ID="_12f9925a270fb1652e82e635fa6fde35" InResponseTo="uk3foqohiipf3948r0gn2tavbdgo1gsc" IssueInstant="2020-12-04T16:50:45.549Z" Version="2.0" xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2:Issuer xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion">https://samltest.id/saml/idp</saml2:Issuer><ds:Signature xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><ds:SignedInfo><ds:CanonicalizationMethod Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/><ds:SignatureMethod Algorithm="http://www.w3.org/2001/04/xmldsig-more#rsa-sha256"/><ds:Reference URI="#_12f9925a270fb1652e82e635fa6fde35"><ds:Transforms><ds:Transform Algorithm="http://www.w3.org/2000/09/xmldsig#enveloped-signature"/><ds:Transform Algorithm="http://www.w3.org/2001/10/xml-exc-c14n#"/></ds:Transforms><ds:DigestMethod Algorithm="http://www.w3.org/2001/04/xmlenc#sha256"/><ds:DigestValue>Ru6R2nqZCGs532STdqd5alLYCOxgMooNlfww1JWVR4U=</ds:DigestValue></ds:Reference></ds:SignedInfo><ds:SignatureValue>FKUtzP59Vht1Pd77s9jW0KejzbG1m6B2txUyVOi3Y1ioTAg1Xvy/VvxNui8u9G6mVV4s1n5l/gFDGi5v2SIN7YcxH+yX9GJ1TW8XX1WJqxtiDFgGbm+KL8DHeVgyc8kJmAC1zOMRUKOy7arvWc42KmhilAumXbS5oo0qwfnvjNmyhzGQW+lZcMcd/K3eE6ZvdsetRToWlXpnzwKuBqy1iZfZZpxKwgKhBtXDTwCltJjH97FOGP7G9epJH/sfNir/970oNzr+y3TXYL2uDoQKVP5SYOzBPtRvUBR4+qcY0SLIsSNn7X9iXMgKAr2GPfgNMG7zgP4F14ElErYlPiBGgA==</ds:SignatureValue><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIDEjCCAfqgAwIBAgIVAMECQ1tjghafm5OxWDh9hwZfxthWMA0GCSqGSIb3DQEBCwUAMBYxFDAS
BgNVBAMMC3NhbWx0ZXN0LmlkMB4XDTE4MDgyNDIxMTQwOVoXDTM4MDgyNDIxMTQwOVowFjEUMBIG
A1UEAwwLc2FtbHRlc3QuaWQwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQC0Z4QX1NFK
s71ufbQwoQoW7qkNAJRIANGA4iM0ThYghul3pC+FwrGv37aTxWXfA1UG9njKbbDreiDAZKngCgyj
xj0uJ4lArgkr4AOEjj5zXA81uGHARfUBctvQcsZpBIxDOvUUImAl+3NqLgMGF2fktxMG7kX3GEVN
c1klbN3dfYsaw5dUrw25DheL9np7G/+28GwHPvLb4aptOiONbCaVvh9UMHEA9F7c0zfF/cL5fOpd
Va54wTI0u12CsFKt78h6lEGG5jUs/qX9clZncJM7EFkN3imPPy+0HC8nspXiH/MZW8o2cqWRkrw3
MzBZW3Ojk5nQj40V6NUbjb7kfejzAgMBAAGjVzBVMB0GA1UdDgQWBBQT6Y9J3Tw/hOGc8PNV7JEE
4k2ZNTA0BgNVHREELTArggtzYW1sdGVzdC5pZIYcaHR0cHM6Ly9zYW1sdGVzdC5pZC9zYW1sL2lk
cDANBgkqhkiG9w0BAQsFAAOCAQEASk3guKfTkVhEaIVvxEPNR2w3vWt3fwmwJCccW98XXLWgNbu3
YaMb2RSn7Th4p3h+mfyk2don6au7Uyzc1Jd39RNv80TG5iQoxfCgphy1FYmmdaSfO8wvDtHTTNiL
ArAxOYtzfYbzb5QrNNH/gQEN8RJaEf/g/1GTw9x/103dSMK0RXtl+fRs2nblD1JJKSQ3AdhxK/we
P3aUPtLxVVJ9wMOQOfcy02l+hHMb6uAjsPOpOVKqi3M8XmcUZOpx4swtgGdeoSpeRyrtMvRwdcci
NBp9UZome44qZAYH1iqrpmmjsfI9pJItsgWu3kXPjhSfj1AJGR1l9JGvJrHki1iHTA==</ds:X509Certificate></ds:X509Data></ds:KeyInfo></ds:Signature><saml2p:Status xmlns:saml2p="urn:oasis:names:tc:SAML:2.0:protocol"><saml2p:StatusCode Value="urn:oasis:names:tc:SAML:2.0:status:Success"/></saml2p:Status><saml2:EncryptedAssertion xmlns:saml2="urn:oasis:names:tc:SAML:2.0:assertion"><xenc:EncryptedData Id="_82ae30113dddb0a1a6677d2847cbfae8" Type="http://www.w3.org/2001/04/xmlenc#Element" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#aes128-cbc" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"/><ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#"><xenc:EncryptedKey Id="_34573737ef07781b5a5b2182effbc2db" Recipient="http://primate-qa.cloudstack.cloud:8080" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:EncryptionMethod Algorithm="http://www.w3.org/2001/04/xmlenc#rsa-oaep-mgf1p" xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><ds:DigestMethod Algorithm="http://www.w3.org/2000/09/xmldsig#sha1" xmlns:ds="http://www.w3.org/2000/09/xmldsig#"/></xenc:EncryptionMethod><ds:KeyInfo><ds:X509Data><ds:X509Certificate>MIIEsjCCApoCCQCHoExIZv8R3TANBgkqhkiG9w0BAQsFADAbMRkwFwYDVQQDDBBBcGFjaGVDbG91
ZFN0YWNrMB4XDTIwMDMwNTE5MzQyMVoXDTIzMDMwNjE5MzQyMVowGzEZMBcGA1UEAwwQQXBhY2hl
Q2xvdWRTdGFjazCCAiIwDQYJKoZIhvcNAQEBBQADggIPADCCAgoCggIBAJzSnSTViczgkNXMWVLI
ccxjdzRG30ptPfBWEsjWdQBgtn/BXEZpj4yeVyYN4p3gdRvtkW6TdwGOyrQksNdAxDhPpG2xQKY7
j01Sato1Kpdk/QfNfTJMd/asdipbgQ/41sttAlO39zn4Q+nmauWJnt7YbWFaAMslRxx7y3nPqfgZ
RlBINK3ltrGYHsvojybjRfGvZ3ewGKeJ7rtSrjGLKbCRqKHYmyFPQxErDaabgEl7/T9wl1kdREl0
UWUiVXcV25Uzq4gZ9253C+KzbAOHyl2MUNJDnPrw4cmwai/mmjvcODNmN4D2wEXQMCYBnoKa+/wl
BEKanoE5pJje9tj84zwnj1UMvU6PXup9RuKcVO7TUsCZPMcKxZn9iKpRIiedWYWBJREL27GP4FTx
cjtBG/4tBzcEGMSXT4Rjcp67yc7NnuSW3XD01olMeGUYdya5t5kkiWIAmxz009SoyopW2MFzufWj
p1uZTeDiO9T+q8hdlSazD7UO3yqrj2ACuAc1xBRI8tbos5ZnQ/ZecR3Z6ZC7uYzJhKoEVDxIC5WI
APYVTTyvXihU1fBIo2ATJpHoI/3IdO8Ug1Xjq5EH+IRCcCXUZbigNxtv+oYQsTt2SpAK4aRhM6T2
f5tk7ZcvCE+DrsL55Wx9RH/iAs2fuY5TrYQulEatWUE1TEJ4JdqdTNeJAgMBAAEwDQYJKoZIhvcN
AQELBQADggIBAAtgfVTPNZbimb4NywnTJx60+LPJ70yCVRuVTzMhmpdpjgqmNYF5l1TEc5pNWvR6
ghJOivr4iWlYFr9mlZ+ifCS2jjde4V3I/Fp4vuzxYXGsw805hSksl+u/BOChq6L32Xf9UVPWwj/Q
xIv1kZ+ZV5uAp4YKAYlAyWO+WknPV6tSYGIjxRNfYacqf0yQPGwSlDG1cAYfBbMxweWD79n0b2ZR
o3e8LPRvODxZigSIW6FG2J4naa8rYxs3B7dSrEKTSMqXLSNqJwEY/7gnwgP/j/NDPtjvRh/ESoUY
dNvDnUQBFK37POI4dJUYSgj4axjBsIE0cvqLoXkO773hRZZzKQima0AwCWTmm2HbeAs8xk4MmDYM
8SsXrbmketEsEq3QgJzyYAeFEvn9Nxrs93KSh/onHaFgI4fo7VVJD4Wwi9nlSsQlCkalcTVJEkbT
upx/0mWGZBQC70Alo9ACr21OgFUDDW5xuewazE7TO6h00WnJe9uuoMV8+5q6yWJKCLCYBaZeVxqu
Pa2bki4+w8ZcWmlc2T9ErhE76hgUjo0Lz3MSfWY+86e4kirZBP3U3zWPVHduyF6bJlik22T879Ns
JG3kPSSrAFvE151cYf2QlqChO/mwbQFurht985Y5uMnnORMU8qTTtoIU8hNQkKrktN4XHEIF3IiI
DxOpmM3iFAVh</ds:X509Certificate></ds:X509Data></ds:KeyInfo><xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:CipherValue>UTlSgRyKSc/gYMHmCiS4EUHm6vZGoVZUNVfTXupfVP1FNB7B4nelClhajG+soCrLA4LMVdrc2R96vuwJalroS0V7To1WlXCxOoS8qwxVj7npafR65vLNt7DnE/p1p4biphTZOAlEVYBcFEMwTxnugWfnEBaoMZcAFAU4YFd3ZAdlK6Urn41F8bpTxPk9grzRbF2qFZb/KfHonUV9+klhemA64tcQoifyA6EzstZLI2qFvdHxGikZDWwATFBSLYuYJX0cAUp0EBQQvIduQZm2d7UzZwbSRTp+WgN318e4wRFgI0cCjH5MrxDI0B7cW48807s3wJiM1lHIRfYKBy1X/P8zFguBXnWv+5QsADMTyIfCT64s5rBjzJ9ll1+LrLMIFwMlUvKeenMrkhLxELWROS4i21lItDOKCDNdlIKXyVuMlZnt2nVkQqcxNOoFE1qGBhCQqnf7rAMuOwp58ENr6R03VUYYwtZ7z6fPnwVdr1LralhZPJ+kRY/e709wMXQ1n3SeQpP+xhpLhCHlbM1GEXCM76tQTFT1sJlzB1Kv5EqyozLiInWqZsovrGdPCWzfiL2/MDn4M0gxFqQU/kwvsIhFFDC5A6izvX7Hu9noVkEZ3Xk7fLyon+qJmeYDxRbXc2AQAYdadRsha+pPEZq+vSGeYkL7GNKquo8H+q/MBVk=</xenc:CipherValue></xenc:CipherData></xenc:EncryptedKey></ds:KeyInfo><xenc:CipherData xmlns:xenc="http://www.w3.org/2001/04/xmlenc#"><xenc:CipherValue>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</xenc:CipherValue></xenc:CipherData></xenc:EncryptedData></saml2:EncryptedAssertion></saml2p:Response>
Hand-waving the details, it sounds to me like we're saying that it's the IDP that controls whether the token is encrypted.
IF so, I agree with Rohit; This is not a CloudStack issue, as CloudStack can work with encrypted tokens.
If the IDP is not configured to send encrypted tokens, that's not CloudStack's 'fault'.
+1 on what Paul and Rohit said. That sounds the same as "if user uses insecure HTTP instead of HTTPS it's ACS security issue" Cloud operator is in charge of the configuration of everything, encryption included everywhere.
So, agreed that everything should be encrypted. I'm not going to claim in anyway that I'm a SAML expert, but if the username changes, shouldn't we be sending a new AuthnRequest back to the IDP?
hi guys
sorry for the late answer.
we're using https, not http. so that should not be the the main issue.
as IDP, we're using keycloack with the following config:
{ "clientId": "iaas.cloudstack", "baseUrl": "https://**********/client", "surrogateAuthRequired": false, "enabled": true, "clientAuthenticatorType": "client-secret", "redirectUris": [ "https://**********/client/api?command=samlSso", "https://**********/client/api?command=samlSlo", ], "webOrigins": [], "notBefore": 0, "bearerOnly": false, "consentRequired": false, "standardFlowEnabled": true, "implicitFlowEnabled": false, "directAccessGrantsEnabled": false, "serviceAccountsEnabled": false, "publicClient": false, "frontchannelLogout": true, "protocol": "saml", "attributes": { "saml.assertion.signature": "false", "saml_assertion_consumer_url_redirect": "https://**********/client/api?command=samlSso", "saml.force.post.binding": "true", "saml.multivalued.roles": "false", "saml_single_logout_service_url_post": "https://**********/client/api?command=samlSlo", "saml.encrypt": "false", "saml_assertion_consumer_url_post": "https://**********/client/api?command=samlSso", "saml.server.signature": "true", "saml.server.signature.keyinfo.ext": "false", "exclude.session.state.from.auth.response": "false", "saml.signing.certificate": "**********", "saml_single_logout_service_url_redirect": "https://**********/client/api?command=samlSlo", "saml.signature.algorithm": "RSA_SHA256", "saml_force_name_id_format": "false", "saml.client.signature": "false", "tls.client.certificate.bound.access.tokens": "false", "saml.authnstatement": "true", "display.on.consent.screen": "false", "saml.signing.private.key": "**********", "saml_name_id_format": "username", "saml.onetimeuse.condition": "false", "saml_signature_canonicalization_method": "http://www.w3.org/2001/10/xml-exc-c14n#" }, "authenticationFlowBindingOverrides": {}, "fullScopeAllowed": true, "nodeReRegistrationTimeout": -1, "protocolMappers": [ { "name": "username-2-userid", "protocol": "saml", "protocolMapper": "saml-user-property-mapper", "consentRequired": false, "config": { "attribute.nameformat": "Basic", "user.attribute": "username", "attribute.name": "uid" } } ], "defaultClientScopes": [ "web-origins", "role_list", "profile", "roles", "email" ], "optionalClientScopes": [ "address", "phone", "offline_access" ], "access": { "view": true, "configure": true, "manage": true } }
regarding to PaulAngus' answer: yes, we have saml.client.signature and saml.encrypt set to false in keycloack. so that might be the issue for all of this. I'll try to change that in an emergency maintenance window an post an update.
thanks for your help!
@ngrosc in that case can you please close the issue. Thanks.
Hi guys
Meanwhile we were able to secure the connection between our IDP and Cloudstack and are now encrypting the assertions. But the initial issue still exists.
When someone removes the signature, cloudstack accepts this. Of course, if someone is able to intercept, decrypt, edit and reencrypt the assertion, we have some other major problems.
But from my point of view, it should be possible to enforce signature checking. As far as I understood, the underlying java component has a flag for this, but its not used from cloudstack. Even it is almost impossible to manipulate such a request, pentesters will classify this as "critical design flaw".
i agree it is an issue but only if a demontrable exploit exists can it be critival, @ngrosc . that said, it should be addressed.
@rhtyd can you shed a light on why teh signature is ignored (and how to fix)?
Needs investigation, I don't remember if it does or does not. However, if the assertions are not encrypted - I suppose that's issue of the overall IDP setup.
Hi Rohit
I completely agree with you. If the assertion is encrypted or not is an IDP "issue".
But if a signature is present or not, has to be enforced on client side (cloudstack). Because even when the IDP adds a signature, a man in the middle can remove it and fake data. Of course, in case of encrypted assertions only if he has the private key of the IDP, and then you definitely have other issues.. Nevertheless, it should be possible to enforce the check of the signature. Then, cloudstack can ensure, that the data is valid..
Am Sa., 6. März 2021 um 11:13 Uhr schrieb Rohit Yadav < notifications@github.com>:
Needs investigation, I don't remember if it does or does not. However, if the assertions are not encrypted - I suppose that's issue of the overall IDP setup.
— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/apache/cloudstack/issues/4519#issuecomment-791907116, or unsubscribe https://github.com/notifications/unsubscribe-auth/ARBOIGJTIFMRSXJYLMUWPL3TCH54HANCNFSM4UNP732Q .
Hi, at least on 4.15.1 cloudstack is unable to find (or decrypt?) saml2.user.attribute if the assertions are encrypted (which is default in keycloak, and also enabled after importing cloudstack's metadata.xml). I do not know, if this exactly relates to this topic.
@s-seitz yes, there is no issue if the SAML IDP enforces encryption.
The issue reporter is essentially asking that assertions/signature be checked even when encryption is not enforced.
I stumbled upon this - and from what I can see the validation of signature is dependent upon the IDP metadata containing a signing cert. If the IDP metadata XML doesn't specify a signing cert, cloudstack simply doesn't check the signature.
The sig checks are wrapped in code like if (idpMetadata.getSigningCertificate() != null)
. So again I'd go back to the IDP configuration. Not sure if the IDP metadata in question is in an XML file on the cloudstack management server, or if it is being fetched via URL in this case.
@mlsorensen are you saying this is a security issue (as opposed to how it was ruled earlier)?
@mlsorensen From my point of view, the origin of the IDP data doesen't matter. As long as Cloudstack does not enforce a signature, any unsigned message would be accepted and processed.
A man in the middle could easy modify the original message, remove the signature and send it to Cloudstack. Of course, as soon as the assertions are encrypted, thats not a real issue anymore.
But from a security point of view, it's not uncritical when a security mechanism can be removed without any problems.
I'm still thinking about a simple true/false flag named "require signed assertions". In case of not set, assertions will be processed with or without signature. But as soon as enabled, every assertion must be signed or it will be dropped.
I tend to agree with @mlsorensen 's remarks, if the IDP configuration/metadata has the signing key then the signature check would be performed. I'm less worried about the MITM, as long as API activities are happening on https. Nonetheless, I've introduced a global setting that can fail a SAML based login check when enabled for more stricter env or http-based env, when the signature is missing from the SAMl response - https://github.com/apache/cloudstack/pull/9219 cc @ngrosc
Addressed by https://github.com/apache/cloudstack/pull/9219
@ngrosc - regarding this issue, please ping me: nux@apache.org, need some info from you.
As the documentation does not state the exact verification of signatures: The linked and integrated PR expects the whole SAMLResponse to be signed, not only the assertion. As far i can see in the source code the assertion signature is not validated. That's a problem with Authentik as it only signs the assertions (which itself would be also valid, Link to authentik issue). E.g. Nextcloud offers a more fine grained control about the validation.
Hope this helps someone to save time debugging SAML in that case. A workaround is to disable signature validation here for now.
ISSUE TYPE
COMPONENT NAME
CLOUDSTACK VERSION
CONFIGURATION
SAML authentication activated
OS / ENVIRONMENT
N/A
SUMMARY
The SAML signature is optional and not mandatory. A user can login into a domain where he's not allowed to.
STEPS TO REPRODUCE
Use a tool to intercept the web requests between your browser ant the cloudstack UI (our pentester used "burp"). Login to cloudstack using a SSO account (SAML). Now, you're logged in successfully to your cloudstack domain. Logout from cloudstack.
Now, log in again to cloudstack, but with the "interceptor" active. In the request, delete the whole saml-signature and change the username to another SSO user from within another tenant. Run the modified request, and you're logged in into this foreign account.
EXPECTED RESULTS
User can't log in into foreign tenant
ACTUAL RESULTS
User can log in into foreign tenant