nip10/nip22: guard against malformed tags.

This commit is contained in:
fiatjaf
2026-06-22 21:20:09 -03:00
parent 455124eecd
commit dab630de34
4 changed files with 20 additions and 11 deletions
+1 -1
View File
@@ -1,6 +1,6 @@
{
"name": "@nostr/tools",
"version": "2.23.7",
"version": "2.23.8",
"exports": {
".": "./index.ts",
"./core": "./core.ts",
+6 -4
View File
@@ -1,6 +1,8 @@
import type { Event } from './core.ts'
import type { EventPointer, ProfilePointer } from './nip19.ts'
const HEX64 = /^[0-9a-fA-F]{64}$/
export function parse(event: Pick<Event, 'tags'>): {
/**
* Pointer to the root of the thread.
@@ -41,7 +43,7 @@ export function parse(event: Pick<Event, 'tags'>): {
for (let i = event.tags.length - 1; i >= 0; i--) {
const tag = event.tags[i]
if (tag[0] === 'e' && tag[1]) {
if (tag[0] === 'e' && tag[1] && HEX64.test(tag[1])) {
const [_, eTagEventId, eTagRelayUrl, eTagMarker, eTagAuthor] = tag as [
string,
string,
@@ -53,7 +55,7 @@ export function parse(event: Pick<Event, 'tags'>): {
const eventPointer: EventPointer = {
id: eTagEventId,
relays: eTagRelayUrl ? [eTagRelayUrl] : [],
author: eTagAuthor,
author: eTagAuthor && HEX64.test(eTagAuthor) ? eTagAuthor : undefined,
}
if (eTagMarker === 'root') {
@@ -81,7 +83,7 @@ export function parse(event: Pick<Event, 'tags'>): {
continue
}
if (tag[0] === 'q' && tag[1]) {
if (tag[0] === 'q' && tag[1] && HEX64.test(tag[1])) {
const [_, eTagEventId, eTagRelayUrl] = tag as [string, string, undefined | string]
result.quotes.push({
id: eTagEventId,
@@ -89,7 +91,7 @@ export function parse(event: Pick<Event, 'tags'>): {
})
}
if (tag[0] === 'p' && tag[1]) {
if (tag[0] === 'p' && tag[1] && HEX64.test(tag[1])) {
result.profiles.push({
pubkey: tag[1],
relays: tag[2] ? [tag[2]] : [],
+12 -5
View File
@@ -1,6 +1,8 @@
import type { Event } from './core.ts'
import type { AddressPointer, EventPointer, ProfilePointer } from './nip19.ts'
const HEX64 = /^[0-9a-fA-F]{64}$/
export type ExternalPointer = {
value: string
hint?: string
@@ -19,9 +21,12 @@ function parseAddressPointer(value: string, relayUrl?: string): AddressPointer |
const kind = parseInt(value.slice(0, idx), 10)
if (Number.isNaN(kind)) return undefined
const pubkey = value.slice(idx + 1, idx2)
if (!HEX64.test(pubkey)) return undefined
return {
kind,
pubkey: value.slice(idx + 1, idx2),
pubkey,
identifier: value.slice(idx2 + 1),
relays: relayUrl ? [relayUrl] : [],
}
@@ -31,11 +36,11 @@ function parsePointer(tag: string[]): EventPointer | AddressPointer | ExternalPo
switch (tag[0]) {
case 'E':
case 'e':
if (!tag[1]) return undefined
if (!tag[1] || !HEX64.test(tag[1])) return undefined
return {
id: tag[1],
relays: tag[2] ? [tag[2]] : [],
author: tag[3],
author: tag[3] && HEX64.test(tag[3]) ? tag[3] : undefined,
}
case 'A':
case 'a':
@@ -58,10 +63,12 @@ function parseQuote(tag: string[]): EventPointer | AddressPointer | ExternalPoin
return parseAddressPointer(tag[1], tag[2])
}
if (!HEX64.test(tag[1])) return undefined
return {
id: tag[1],
relays: tag[2] ? [tag[2]] : [],
author: tag[3],
author: tag[3] && HEX64.test(tag[3]) ? tag[3] : undefined,
}
}
@@ -172,7 +179,7 @@ export function parse(event: Pick<Event, 'tags'>): {
continue
}
if ((tag[0] === 'P' || tag[0] === 'p') && tag[1]) {
if ((tag[0] === 'P' || tag[0] === 'p') && tag[1] && HEX64.test(tag[1])) {
result.profiles.push({
pubkey: tag[1],
relays: tag[2] ? [tag[2]] : [],
+1 -1
View File
@@ -1,7 +1,7 @@
{
"type": "module",
"name": "nostr-tools",
"version": "2.23.7",
"version": "2.23.8",
"description": "Tools for making a Nostr client.",
"repository": {
"type": "git",