Bug 55248 - hidden saml2.s_utils.UnravelError in unknown condition during SAML login
hidden saml2.s_utils.UnravelError in unknown condition during SAML login
Status: CLOSED FIXED
Product: UCS
Classification: Unclassified
Component: UMC (Generic)
UCS 5.0
Other Linux
: P4 normal (vote)
: UCS 5.0-2-errata
Assigned To: Florian Best
Dirk Wiesenthal
https://git.knut.univention.de/univen...
:
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2022-10-07 15:00 CEST by Florian Best
Modified: 2022-11-16 18:03 CET (History)
3 users (show)

See Also:
What kind of report is it?: Bug Report
What type of bug is this?: 5: Major Usability: Impairs usability in key scenarios
Who will be affected by this bug?: 3: Will affect average number of installed domains
How will those affected feel about the bug?: 5: Blocking further progress on the daily work
User Pain: 0.429
Enterprise Customer affected?: Yes
School Customer affected?:
ISV affected?:
Waiting Support:
Flags outvoted (downgraded) after PO Review:
Ticket number:
Bug group (optional):
Max CVSS v3 score:


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Florian Best univentionstaff 2022-10-07 15:00:54 CEST
An error in the UMC-Web-Server during SAML login might happen if we give a wrong data type to pysaml2.
In a customer debug session we patched pysaml2 to not ignore exceptions and return None in "parse_authn_request_response" but to raise an exception:
```
127.0.0.1 - - [06/Oct/2022:15:46:28] "POST /saml/ HTTP/1.1" 500 2227 "https://.../simplesamlphp/module.php/core/loginuserpass.php?, https://.../simplesamlphp/module.php/core/loginuserpass.php?"
[06/Oct/2022:15:46:29] HTTP 
Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/saml2/entity.py", line 387, in unravel
    xmlstr = base64.b64decode(txt)
  File "/usr/lib/python3.7/base64.py", line 80, in b64decode
    s = _bytes_from_decode_data(s)
  File "/usr/lib/python3.7/base64.py", line 46, in _bytes_from_decode_data
    "string, not %r" % s.__class__.__name__) from None
TypeError: argument should be a bytes-like object or ASCII string, not 'list'

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
  File "/usr/lib/python3/dist-packages/cherrypy/_cprequest.py", line 670, in respond
    response.body = self.handler()
  File "/usr/lib/python3/dist-packages/cherrypy/lib/encoding.py", line 220, in __call__
    self.body = self.oldhandler(*args, **kwargs)
  File "/usr/lib/python3/dist-packages/cherrypy/_cpdispatch.py", line 60, in __call__
    return self.callable(*self.args, **self.kwargs)
  File "/usr/sbin/univention-management-console-web-server", line 1261, in index
    return acs(binding, message, relay_state)
  File "/usr/sbin/univention-management-console-web-server", line 1269, in attribute_consuming_service
    response = self.acs(message, binding)
  File "/usr/sbin/univention-management-console-web-server", line 1399, in acs
    response = self.sp.parse_authn_request_response(message, binding, self.outstanding_queries)
  File "/usr/lib/python3/dist-packages/saml2/client_base.py", line 702, in parse_authn_request_response
    binding, **kwargs)
  File "/usr/lib/python3/dist-packages/saml2/entity.py", line 1132, in _parse_response
    xmlstr = self.unravel(xmlstr, binding, response_cls.msgtype)
  File "/usr/lib/python3/dist-packages/saml2/entity.py", line 397, in unravel
    raise UnravelError("Unravelling binding '%s' failed" % binding)
saml2.s_utils.UnravelError: Unravelling binding 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST' failed
```

The curl command to trigger this did not contain two `SAMLResponse` HTTP POST form data but the UMC-Webserver somehow had `message == [saml_response, saml_response]`.

A fix which worked for us was:
diff --git management/univention-management-console/univention-management-console-web-server management/univention-management-console/univention-management-console-web-server                                                                
index eecd8e85fb..8bb58ae8a2 100755
--- management/univention-management-console/univention-management-console-web-server
+++ management/univention-management-console/univention-management-console-web-server
@@ -1303,7 +1303,8 @@ class SAML(Ressource):

@@ -1391,6 +1392,9 @@ class SAML(Ressource):
                                message = self.sp.artifact2message(message, 'spsso')
                                binding = BINDING_HTTP_ARTIFACT

+               if isinstance(message, list):
+                       message = message[0]
+
                return binding, message, relay_state

        def acs(self, message, binding):  # attribute consuming service  # TODO: rename into parse
Comment 2 Tim Breidenbach univentionstaff 2022-11-03 13:54:50 CET
This was seen in 2 more environments.
Comment 4 Florian Best univentionstaff 2022-11-14 18:17:24 CET
It is now ensured that no list is passed to pysaml2.

univention-management-console.yaml
04230a180c44 | fix(umc-saml): handle duplicated SAML messages as one

univention-management-console (12.0.13-3)
04230a180c44 | fix(umc-saml): handle duplicated SAML messages as one
Comment 5 Dirk Wiesenthal univentionstaff 2022-11-15 18:13:50 CET
No regressions: OK
Reproducing the problem: ~Not without monkey patching
YAML: OK