Skip to content
This repository has been archived by the owner on Feb 12, 2019. It is now read-only.

Stringprep calls may reveal random memory #85

Open
xnyhps opened this issue Oct 22, 2014 · 7 comments
Open

Stringprep calls may reveal random memory #85

xnyhps opened this issue Oct 22, 2014 · 7 comments
Labels

Comments

@xnyhps
Copy link

xnyhps commented Oct 22, 2014

When a bind iq comes in, the following happens:

  1. c2s/c2s.c#L285 grabs the bytes of the chosen resource. If the resource was > 1023 bytes, only the first 1023 bytes are copied.

  2. That calls jid_reset_components, which eventually ends up in jid_prep_pieces.

  3. That calls stringprep_xmpp_resourceprep(resource, 1024). However, the stringprep 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.

  4. If the resource ends with just a part of a multi-byte character (so is not valid UTF-8) then stringprep skips over the terminating NULL-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.

@xnyhps xnyhps changed the title Strinprep calls leak random memory Stringprep calls leak random memory Oct 22, 2014
@smokku
Copy link
Member

smokku commented Oct 23, 2014

So, this is not really about leaking any memory, rather than reading outside given buffer boundary, right?
Would there be enough fix to enlarge the buffer by n characters filled by \0 chars, where n is the longest possible utf-8 character?

@xnyhps
Copy link
Author

xnyhps commented Oct 23, 2014

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 stringprep may do other weird things.

@smokku
Copy link
Member

smokku commented Oct 23, 2014

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.
http://www.cprogramming.com/tutorial/unicode.html looks reasonable with its utf8.[ch] companion helpers.

Other option would be to move away from libidn to ICU, but that would get jabberd2 much heavier.

@frub
Copy link

frub commented Jan 26, 2015

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?

@ghost
Copy link

ghost commented Feb 10, 2015

A CVE id has been requested for this issue, oss-sec mailing list: http://seclists.org/oss-sec/2015/q1/487

@xnyhps
Copy link
Author

xnyhps commented Feb 24, 2015

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.

@smokku
Copy link
Member

smokku commented May 19, 2016

http://www.gnu.org/software/libunistring/ looks good and we should use it for all UTF8 string processing.

@smokku smokku changed the title Stringprep calls leak random memory Stringprep calls may reveal random memory May 29, 2016
@smokku smokku added the Bug label May 30, 2016
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

3 participants