Hi,
so, for having implementing it, I have a few remarks on this XEP-0070.
(1) The extension focuses on the use case where the client would
request authentication through HTTP authentication (RFC-2617) with a
dedicated scheme ("xmpp" realm).
That's nice and should stay, but nowaydays websites would often use a
"simpler" method, transmitting simply credentials with POST data or
another custom fashion. The XEP should take this possibility into
account.
Of course, in this case, security considerations are left to the
implementer, but usually they would be the same as http authentication
(for instance using HTTPS if using POST data, in order not to leak the
jid, and the transaction id).
(2) The transaction id is not a password, but it is a vector of attack
(that's why it has created, to avoid attempts of authentication by an
attacker at same time you connect) and thus it should be "hidden" like
a password at the time the user types it.
Otherwise an attacker could "look behind your shoulder" when you type
it, and very fast type the same transaction id, along with your JID.
When one receives 2 requests with the same transaction ID from the
website you just attempted to connect, a non-paranoid user might think
that's just a bug of the system and may accept both, hence letting the
attacker in.
That should be added in security considerations.
(3) In <confirm/>, I would personally suggest to add a "title" or
"summary" (or both). The reason for this is that it may be nicer to
distinguish an authentication request generated by the client if it
has a nice relevant title. For instance, an authentication request
generated by xmpp.org could have a title="The XMPP Standards
Foundation" summary="New comment". For many people, this will be more
relevant than looking only at the url to distinguish who sent the
request.
(4) The XEP clearly poses the bases to nicely downgrading to text
messages in a rather secure way to clients which do not support
XEP-0070 but *at least* support message threading (RFC-6121).
Nevertheless it does not go to the end of the possibility. It only
explains how to send a message with an optional body element and a
thread. Here are the changes I propose:
* "The <message/> stanza SHOULD include a <thread/> element for
tracking purposes"
- > MUST include a <thread/>...
* "and MAY include a <body/> element that provides human-readable
information or instructions."
-> and SHOULD include a <body/> element that provides human-readable
information or instructions, *if* message downgrading is desired.
Now change the "4.6 XMPP Client Confirms Request via XMPP" by making
it a 2-case:
== 4.6.1 the client understands the XEP-0070. ==
That's where we keep the current text of the section. In this
subsection though, I would add that:
1/ the human-readable message (<body/>) SHOULD NOT be displayed to the
user. If the client understands the XEP, it should generate its own
generic display with appropriate information. For instance Psi+ would
display what is inside the <confirm/>, so basically the transaction
ID, the url and the method, along with a generic access request text.
That's nice.
On the other other hand, Gajim (I have an old version, this may not be
true anymore in last version. No idea) displayed the <body/> text
also.
Why it is not good, is that the message provided by the server may not
correspond to the data displayed by the client. Let's take example 6
of XEP-0070. It says "If you wish to confirm the request, please reply
to this message by typing "OK". If not, please reply with "No"."
But a client may (as do Psi and Gajim) propose a pop-up with their own
buttons, labeled maybe yes/no or ok/cancel, or maybe localized
oui/non. So that would startle the user and is not good for security.
We must consider the <body/> should only be used for the fallback
version (optionally it might be accessible with a "details" button or
something, but even this I would not advice).
Also that's better for localization by the client (or the server
proposed <body/>s has to be in many xml:lang).
2/ Whatever the client specific displays to present such an
authentication request, it should put some emphasis on the
authentication ID. That's the only part which is not falsifiable and
which really determine the authenticity that this is the request from
the website you just attempted to log-in. The url, the title (if we
add it, see (3)), the method, everything can be fake and is only
"information purpose". And the sender can be any JID (nothing forces
the JID to be a component of the same domain as the website, it can be
a bot on a third party). So though obviously everything here matters
for a fast check (of course, if it gives a completely different url,
refuse!), in the end, only the authentication id which the user
entered really is important.
In security considerations, this should be well explained for client
to display this properly (bigger text, red, bold, whatever, maybe even
with a warning text to ask the user to be sure this is the same id
they entered).
Obviously this is only for cases when ID are entered and checked
humanly. But that will be the main case anyway, unless we end-up being
integrated in browser.
== 4.6.2 the client does not understand XEP-0070 ==
Clearly XEP-0070's example 6 set up the base for this case.
When this happens, the client will normally display the <body/> part
as a "normal" (type) message. It will just discards the <confirm/>
part it does not understand.
So what happens now? The user sees a message which tells one to type
"ok" or "no" (cf. example 6. I would have found more logical yes/no or
ok/cancel but anyway).
Then it types "ok" and expects its authentication to be accepted in the website.
Hence here is the new possible acceptable answer:
<message from='[email protected]/balcony'
to='files.shakespeare.lit'>
<thread>e0ffe42b28561960c6b12b944a092794b9683a38</thread>
</body>ok</body>
</message>
So what is important here, for this to be secure, because we lost the
transaction ID in the process?
The server MUST refuse any answer without a <thread/> which
corresponds. That disqualifies any client which does not understand
<thread/> (sadly there are quite a few), but anyway that's a RFC
feature. They all should get to support it at some point.
The reason is simple. If an attacker was to request access with your
JID in same time as you, you receive 2 requests. You are a
security-conscientious user, so you refuse the attacker's one and
accept yours but your client were to lose the <thread/> in the
process.
=> The server has no mean to know now which request you accepted. So
it MUST definitely refuse this kind of response.
We can add a few security considerations here.
1/ As this is a human response, the server may be less strict to
accept "ok", "OK", "Ok", or even "yes", and so on. That's up to
implementation.
2/ Even though we lost the transaction ID, we can consider this is
quite secure *if* the thread is generated with good randomness. In
particular it must not be guessable by an attacker, but especially
there must definitely not be a clash between 2 requests made within a
short time span (just imagine that the server sends the same thread
for both the request you made and the one for the attacker. If you
were to answer yours positively, the server might think you accept the
attacker's request).
A link to "randomness requirements for security" might be added here:
http://tools.ietf.org/html/rfc4086
It is up to an implementer to disable (= refuse any) normal messages
responses if it considered its own thread generation is not secure.
Nevertheless if the implementer thinks it has a good and random thread
generation, then this kind of response could be considered secure as
well and allow for nice fallback to support any client with good
RFC-6121 support.
So here are my few remaks to improve this XEP!
Thanks.
Jehan