Nostr WoT
NostrSignataireNIP-46Clients

Amber 6.6.6 corrige un analyseur nostrconnect qui abîmait les secrets NIP-46

Un séparateur par défaut de Kotlin transformait un secret base64 avec remplissage en un fragment séparé par des virgules, et NIP-46 oblige le client à rejeter exactement cela.

Nostr WoT Newsroom

Article5 min de lecture

Rédigé par la rédaction de Nostr WoT à partir des sources primaires citées, et publié automatiquement sans relecture humaine individuelle.

Amber 6.6.6 corrige un analyseur nostrconnect qui abîmait les secrets NIP-46

Amber 6.6.6 a été publiée le 28 septembre 2026. La première entrée de son journal des modifications répare un défaut d'analyse dans le traitement des jetons de connexion nostrconnect:// par le signataire : un secret de connexion contenant le caractère = revenait altéré dans la réponse connect, et le client demandeur refusait la connexion.

Le ticket #526, ouvert le 23 septembre, expose le cas concret. Un client propose un jeton de la forme nostrconnect://715ad7d1...?relay=wss%3A%2F%2Frelay.primal.net&secret=XQUdha4rjh_gjAgHN8X5yg==&perms=.... Le secret est du base64 dont le remplissage est intact. Amber renvoyait XQUdha4rjh_gjAgHN8X5yg, , à la place. Le ticket indique que les applications construites sur NDK, en citant Nmail comme exemple, produisaient des secrets sous cette forme.

La spécification rend la panne totale, pas cosmétique

NIP-46 décrit secret comme un paramètre de requête obligatoire, « une courte chaîne aléatoire que le remote-signer devrait renvoyer comme champ result de sa réponse ». Elle précise ensuite que la valeur « MUST be provided to avoid connection spoofing » et que le client « MUST validate the secret returned by connect response ».

Cette exigence explique pourquoi une seule séquence de caractères altérée met fin à la poignée de main. Le client n'a pas le droit d'accepter une correspondance approchante ni de se rabattre sur la confiance envers la clé qui répond. Il compare ce qu'il a produit à ce qu'il a reçu, constate une chaîne différente et s'arrête. L'appairage ne se termine jamais et, du côté de l'utilisateur, le signataire ne se connecte tout simplement pas.

La spécification n'impose aucune restriction sur l'alphabet du secret. « Une courte chaîne aléatoire » admet le base64, et le remplissage du base64 est =. Un client produisant du base64 avec remplissage respectait la spécification, et c'était au signataire de l'accepter.

Un séparateur par défaut, deux fois

La cause est étroite et documentée dans le diff. Le joinToString de Kotlin utilise ", " comme séparateur par défaut. Le code précédent découpait chaque paramètre de requête sur chaque =, écartait le premier élément, puis réassemblait le reste sans passer de séparateur :

kotlin
val internalSplit = it.split("=")
val paramName = internalSplit.first()
val json = internalSplit.mapIndexedNotNull { index, s ->
    if (index == 0) null else s
}.joinToString { data -> data }

Appliqué à secret=XQUdha4rjh_gjAgHN8X5yg==, le découpage produit quatre éléments, les deux derniers vides. Réassembler les trois derniers avec ", " donne XQUdha4rjh_gjAgHN8X5yg, , . Deux défauts se cumulent sur une ligne : les caractères de remplissage sont consommés comme délimiteurs, et un séparateur que personne n'avait voulu est inséré à leur place.

La version 6.6.6 remplace tout le bloc par une fonction auxiliaire nommée qui découpe une seule fois :

kotlin
fun splitParam(param: String): Pair<String, String> =
    param.substringBefore("=") to param.substringAfter("=", "")

La même publication corrige l'erreur identique à un second point d'appel. Le jeton est découpé sur ? pour séparer la clé publique du client de la chaîne de requête, et les fragments restants étaient réassemblés par split.drop(1).joinToString { it }. On lit désormais joinToString("") { it }. Le premier point cassait tout secret avec remplissage ; le second ne touche qu'un jeton dont la chaîne de requête porte un ? littéral, mais il s'agit de la même valeur par défaut et de la même classe d'erreur.

Un nouveau fichier de tests, NostrConnectUtilsTest.kt, ajoute sept cas. Quatre couvrent des valeurs contenant =, dont le secret avec remplissage du ticket, une valeur avec = au milieu, une URL de relais encodée en pourcentage et une liste perms. Trois figent les entrées dégénérées pour que la réparation ne les modifie pas : un paramètre sans =, un paramètre à valeur vide et la chaîne vide.

Le reste de la publication

Six commits et seize fichiers séparent la 6.6.5 de la 6.6.6. Le reste relève de la présentation et du routage, non du protocole.

Trois entrées du journal concernent le contraste. Le texte et les icônes blancs sur les surfaces ambre claires en thème sombre sont corrigés sur le bouton d'action flottant d'Edit Relays, sur les boutons icônes d'ajout de relais et sur les puces de filtre sélectionnées de l'écran de retours. L'icône d'état Tor et proxy de la barre supérieure, décrite comme presque invisible en thème clair, utilise maintenant des couleurs adaptées au thème dans les deux cas, et l'icône de reconnexion de relais s'aligne sur le compteur de relais voisin.

La dernière entrée change la destination des retours. Les signalements de retours sont publiés sur les relais annoncés dans l'annonce du dépôt d'Amber plutôt que sur un relais codé en dur, avec un repli sur le comportement précédent lorsque l'annonce ne peut pas être récupérée. Les délais d'attente sur Tor ont été allongés pour qu'un relais lent puisse quand même confirmer la publication.

Ce que les artefacts établissent

La version 6.6.6 est une publication GitHub avec des ressources Android et un manifeste de sommes de contrôle signé, étiquetée au commit fc2e0de5. La modification de l'analyseur, la fonction auxiliaire, le second point d'appel et les sept cas de test sont visibles dans la comparaison avec la 6.6.5 : le journal des modifications et le diff concordent donc sur cette publication.

Cela établit ce que fait désormais le code. Cela n'établit pas qu'une installation donnée s'est mise à jour, et les canaux de magasin et de dépôt avancent à leur propre rythme. Quiconque avait un client qui continuait d'échouer à sa vérification du secret devrait confirmer la version réellement exécutée sur l'appareil.

Sources

Chaque affirmation de cet article renvoie vers une source primaire.

  1. Publication d'Amber v6.6.6 — greenart7c3/Amber (28 septembre 2026)
  2. Ticket #526 : l'analyseur de nostrconnect:// corrompt les valeurs contenant = — greenart7c3/Amber (23 septembre 2026)
  3. Comparaison v6.6.5...v6.6.6 — greenart7c3/Amber (28 septembre 2026)
  4. NIP-46 Nostr Remote Signing — nostr-protocol/nips (28 septembre 2026)

Restez au courant

Recevez les actualités sur les versions publiées de Nostr WoT, les nouvelles fonctionnalités et les intégrations.

Vous recevrez la newsletter en français.

Nous conservons votre adresse e-mail et votre langue préférée pour vous envoyer la newsletter.

Lettres d’information