fix: reject sub with unsafe ints in since/until

Signed-off-by: Ricardo Arturo Cabral Mejía <me@ricardocabral.io>
This commit is contained in:
Ricardo Arturo Cabral Mejía
2022-12-29 11:19:49 -05:00
parent fa1a9af088
commit fe9ad92b44
5 changed files with 12 additions and 6 deletions

View File

@ -12,6 +12,10 @@ export const signatureSchema = Schema.string().case('lower').hex().length(128).l
export const subscriptionSchema = Schema.string().min(1).max(255).label('subscriptionId') export const subscriptionSchema = Schema.string().min(1).max(255).label('subscriptionId')
const seconds = (value: any, helpers: any) => (Number.isSafeInteger(value) && Math.log10(value) < 10) ? value : helpers.error('any.invalid')
export const createdAtSchema = Schema.number().min(0).multiple(1).custom(seconds)
// [<string>, <string> 0..*] // [<string>, <string> 0..*]
export const tagSchema = Schema.array() export const tagSchema = Schema.array()
.ordered(Schema.string().max(255).required().label('identifier')) .ordered(Schema.string().max(255).required().label('identifier'))

View File

@ -1,6 +1,7 @@
import Schema from 'joi' import Schema from 'joi'
import { import {
createdAtSchema,
idSchema, idSchema,
kindSchema, kindSchema,
pubkeySchema, pubkeySchema,
@ -9,8 +10,6 @@ import {
} from './base-schema' } from './base-schema'
export const seconds = (value: any, helpers: any) => (Math.log10(value) < 10) ? value : helpers.error('any.invalid')
/** /**
* { * {
* "id": <32-bytes sha256 of the the serialized event data> * "id": <32-bytes sha256 of the the serialized event data>
@ -30,7 +29,7 @@ export const eventSchema = Schema.object({
// NIP-01 // NIP-01
id: idSchema.required(), id: idSchema.required(),
pubkey: pubkeySchema.required(), pubkey: pubkeySchema.required(),
created_at: Schema.number().min(0).multiple(1).custom(seconds).required(), created_at: createdAtSchema.required(),
kind: kindSchema.required(), kind: kindSchema.required(),
tags: Schema.array().items(tagSchema).required(), tags: Schema.array().items(tagSchema).required(),
content: Schema.string() content: Schema.string()

View File

@ -1,12 +1,12 @@
import Schema from 'joi' import Schema from 'joi'
import { kindSchema, prefixSchema } from './base-schema' import { createdAtSchema, kindSchema, prefixSchema } from './base-schema'
export const filterSchema = Schema.object({ export const filterSchema = Schema.object({
ids: Schema.array().items(prefixSchema.label('prefixOrId')).max(1000), ids: Schema.array().items(prefixSchema.label('prefixOrId')).max(1000),
authors: Schema.array().items(prefixSchema.label('prefixOrAuthor')).max(1000), authors: Schema.array().items(prefixSchema.label('prefixOrAuthor')).max(1000),
kinds: Schema.array().items(kindSchema).max(20), kinds: Schema.array().items(kindSchema).max(20),
since: Schema.number().min(0).multiple(1), since: createdAtSchema,
until: Schema.number().min(0).multiple(1), until: createdAtSchema,
limit: Schema.number().min(0).multiple(1).max(10000), limit: Schema.number().min(0).multiple(1).max(10000),
}).pattern(/^#[a-z]$/, Schema.array().items(Schema.string().max(1024)).max(256)) }).pattern(/^#[a-z]$/, Schema.array().items(Schema.string().max(1024)).max(256))

View File

@ -84,6 +84,7 @@ describe('NIP-01', () => {
{ message: 'is required', transform: omit(['pubkey']) }, { message: 'is required', transform: omit(['pubkey']) },
], ],
created_at: [ created_at: [
{ message: 'contains an invalid value', transform: assocPath(['created_at'], 1672295751103) },
{ message: 'must be a number', transform: assocPath(['created_at'], null) }, { message: 'must be a number', transform: assocPath(['created_at'], null) },
{ message: 'must be greater than or equal to 0', transform: assocPath(['created_at'], -1) }, { message: 'must be greater than or equal to 0', transform: assocPath(['created_at'], -1) },
{ message: 'must be a multiple of 1', transform: assocPath(['created_at'], Math.PI) }, { message: 'must be a multiple of 1', transform: assocPath(['created_at'], Math.PI) },

View File

@ -58,11 +58,13 @@ describe('NIP-01', () => {
{ message: 'must be a multiple of 1', transform: assocPath(['kinds', 0], Math.PI) }, { message: 'must be a multiple of 1', transform: assocPath(['kinds', 0], Math.PI) },
], ],
since: [ since: [
{ message: 'contains an invalid value', transform: assocPath(['since'], 1672295751103) },
{ message: 'must be a number', transform: assocPath(['since'], null) }, { message: 'must be a number', transform: assocPath(['since'], null) },
{ message: 'must be greater than or equal to 0', transform: assocPath(['since'], -1) }, { message: 'must be greater than or equal to 0', transform: assocPath(['since'], -1) },
{ message: 'must be a multiple of 1', transform: assocPath(['since'], Math.PI) }, { message: 'must be a multiple of 1', transform: assocPath(['since'], Math.PI) },
], ],
until: [ until: [
{ message: 'contains an invalid value', transform: assocPath(['until'], 1672295751103) },
{ message: 'must be a number', transform: assocPath(['until'], null) }, { message: 'must be a number', transform: assocPath(['until'], null) },
{ message: 'must be greater than or equal to 0', transform: assocPath(['until'], -1) }, { message: 'must be greater than or equal to 0', transform: assocPath(['until'], -1) },
{ message: 'must be a multiple of 1', transform: assocPath(['until'], Math.PI) }, { message: 'must be a multiple of 1', transform: assocPath(['until'], Math.PI) },