Philipp Hörist pushed to branch master at gajim / python-nbxmpp
Commits:
f4098bee by Philipp Hörist at 2026-08-26T18:41:04+02:00
imprv: VCardAvatars: Validate and normalize sha1
- - - - -
2 changed files:
- nbxmpp/modules/vcard_avatar.py
- nbxmpp/util.py
Changes:
=====================================
nbxmpp/modules/vcard_avatar.py
=====================================
@@ -15,6 +15,7 @@ from nbxmpp.namespaces import Namespace
from nbxmpp.protocol import Presence
from nbxmpp.structs import PresenceProperties
from nbxmpp.structs import StanzaHandler
+from nbxmpp.util import normalize_sha1
if TYPE_CHECKING:
from nbxmpp.client import Client
@@ -47,15 +48,27 @@ class VCardAvatar(BaseModule):
avatar_sha = update.getTagData("photo")
if avatar_sha is None:
properties.avatar_state = AvatarState.NOT_READY
- self._log.info("%s is not ready to promote an avatar",
stanza.getFrom())
+ self._log.info("%s is not ready to promote an avatar",
properties.jid)
# Empty update element, ignore
return
if avatar_sha == "":
properties.avatar_state = AvatarState.EMPTY
- self._log.info("%s empty avatar advertised", stanza.getFrom())
+ self._log.info("%s empty avatar advertised", properties.jid)
+ return
+
+ # XEP-0153 hashes are hex SHA-1 of the image bytes. Implementations
must
+ # accept mixed case and should emit lowercase.
+ normalized_sha = normalize_sha1(avatar_sha)
+ if normalized_sha is None:
+ properties.avatar_state = AvatarState.IGNORE
+ self._log.warning(
+ "%s advertised invalid avatar hash: %r",
+ properties.jid,
+ avatar_sha,
+ )
return
properties.avatar_sha = avatar_sha
properties.avatar_state = AvatarState.ADVERTISED
- self._log.info("%s advertises %s", stanza.getFrom(), avatar_sha)
+ self._log.info("%s advertises %s", properties.jid, avatar_sha)
=====================================
nbxmpp/util.py
=====================================
@@ -53,6 +53,8 @@ if TYPE_CHECKING:
log = logging.getLogger("nbxmpp.util")
+SHA1_RX = re.compile(r"[a-f0-9]{40}")
+
def b64decode(data: str | bytes) -> bytes:
if not data:
@@ -475,3 +477,11 @@ def parse_websocket_uri(data: str) -> str:
raise ValueError("No href attr found")
return href
raise ValueError("no websocket uri found")
+
+
+def normalize_sha1(value: str) -> str | None:
+ """Return a canonical lowercase SHA-1 hex digest, or None if invalid."""
+ value = value.lower()
+ if SHA1_RX.fullmatch(value) is None:
+ return None
+ return value
View it on GitLab:
https://dev.gajim.org/gajim/python-nbxmpp/-/commit/f4098beeddbc1dbd29320ab40513f0adcb57eb9f
--
View it on GitLab:
https://dev.gajim.org/gajim/python-nbxmpp/-/commit/f4098beeddbc1dbd29320ab40513f0adcb57eb9f
You're receiving this email because of your account on dev.gajim.org.
_______________________________________________
Commits mailing list -- [email protected]
To unsubscribe send an email to [email protected]