mirror of
https://git.jabber.space/devs/cproof.git
synced 2026-07-18 16:36:20 +00:00
fix(xmpp): verify 'by' attribute of stanza-id and MAM result
Implement security checks to ensure the 'archive_id' (XEP-0359) used for database deduplication originates from a trusted source. XEP-0359 Section 3.1: "The 'by' attribute MUST be the XMPP address (JID) of the entity assigning the unique and stable stanza ID." Furthermore, Section 4 (Security Considerations) specifies: "A client SHOULD only trust <stanza-id/> elements from its own server or from a MUC service it is joined to." XEP-0313 Section 4.1.2: "The 'by' attribute of the <result/> element is the JID of the archive being queried." and "If the 'by' attribute is not present, the recipient MUST assume that the results are from their own personal archive." Let _handle_chat verify <stanza-id/> 'by' attribute matches our bare JID. Let _handle_groupchat verify <stanza-id/> 'by' attribute matches the MUC s bare JID. Let _handle_mam verify the <result/> 'by' attribute matches the outer message 'from' (archive JID). If 'by' is missing then 'from' matches our own bare JID (personal archive). Signed-off-by: Michael Vetter <jubalh@iodoru.org>
This commit is contained in:
@@ -1067,9 +1067,12 @@ _handle_groupchat(xmpp_stanza_t* const stanza)
|
||||
char* stanzaid = NULL;
|
||||
xmpp_stanza_t* stanzaidst = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_STANZA_ID, STANZA_NS_STABLE_ID);
|
||||
if (stanzaidst) {
|
||||
stanzaid = (char*)xmpp_stanza_get_attribute(stanzaidst, STANZA_ATTR_ID);
|
||||
if (stanzaid) {
|
||||
message->stanzaid = strdup(stanzaid);
|
||||
const char* by = xmpp_stanza_get_attribute(stanzaidst, "by");
|
||||
if (by && (g_strcmp0(by, from_jid->barejid) == 0)) {
|
||||
stanzaid = (char*)xmpp_stanza_get_attribute(stanzaidst, STANZA_ATTR_ID);
|
||||
if (stanzaid) {
|
||||
message->stanzaid = strdup(stanzaid);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1389,9 +1392,12 @@ _handle_chat(xmpp_stanza_t* const stanza, gboolean is_mam, gboolean is_carbon, c
|
||||
char* stanzaid = NULL;
|
||||
xmpp_stanza_t* stanzaidst = xmpp_stanza_get_child_by_name_and_ns(stanza, STANZA_NAME_STANZA_ID, STANZA_NS_STABLE_ID);
|
||||
if (stanzaidst) {
|
||||
stanzaid = (char*)xmpp_stanza_get_attribute(stanzaidst, STANZA_ATTR_ID);
|
||||
if (stanzaid) {
|
||||
message->stanzaid = strdup(stanzaid);
|
||||
const char* by = xmpp_stanza_get_attribute(stanzaidst, "by");
|
||||
if (by && equals_our_barejid(by)) {
|
||||
stanzaid = (char*)xmpp_stanza_get_attribute(stanzaidst, STANZA_ATTR_ID);
|
||||
if (stanzaid) {
|
||||
message->stanzaid = strdup(stanzaid);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1524,6 +1530,20 @@ _handle_mam(xmpp_stanza_t* const stanza)
|
||||
|
||||
// <result xmlns='urn:xmpp:mam:2' queryid='f27' id='5d398-28273-f7382'>
|
||||
// same as <stanza-id> from XEP-0359 for live messages
|
||||
const char* by = xmpp_stanza_get_attribute(result, "by");
|
||||
const char* from = xmpp_stanza_get_from(stanza);
|
||||
if (by) {
|
||||
if (g_strcmp0(by, from) != 0) {
|
||||
log_warning("MAM result 'by' attribute (%s) does not match 'from' (%s)", by, from);
|
||||
return TRUE;
|
||||
}
|
||||
} else {
|
||||
if (from && !equals_our_barejid(from)) {
|
||||
log_warning("MAM result from %s with no 'by' attribute (expected our own JID)", from);
|
||||
return TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
const char* result_id = xmpp_stanza_get_id(result);
|
||||
|
||||
GDateTime* timestamp = stanza_get_delay_from(forwarded, NULL);
|
||||
|
||||
Reference in New Issue
Block a user