diff --git a/package.json b/package.json index 232c817540..9ddbc56142 100644 --- a/package.json +++ b/package.json @@ -83,6 +83,7 @@ "nuxt": "4.3.0", "nuxt-og-image": "5.1.13", "ofetch": "1.5.1", + "ohash": "2.0.11", "perfect-debounce": "2.1.0", "sanitize-html": "2.17.0", "semver": "7.7.3", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 9a7aaf5f84..3725685657 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -146,6 +146,9 @@ importers: ofetch: specifier: 1.5.1 version: 1.5.1 + ohash: + specifier: 2.0.11 + version: 2.0.11 perfect-debounce: specifier: 2.1.0 version: 2.1.0 diff --git a/server/api/registry/badge/[type]/[...pkg].get.ts b/server/api/registry/badge/[type]/[...pkg].get.ts index 7e5f72cdf9..6092913fed 100644 --- a/server/api/registry/badge/[type]/[...pkg].get.ts +++ b/server/api/registry/badge/[type]/[...pkg].get.ts @@ -1,4 +1,5 @@ import * as v from 'valibot' +import { hash } from 'ohash' import { createError, getRouterParam, getQuery, setHeader } from 'h3' import { PackageRouteParamsSchema } from '#shared/schemas/package' import { CACHE_MAX_AGE_ONE_HOUR, ERROR_NPM_FETCH_FAILED } from '#shared/utils/constants' @@ -11,11 +12,13 @@ const OSV_QUERY_API = 'https://api.osv.dev/v1/query' const BUNDLEPHOBIA_API = 'https://bundlephobia.com/api/size' const NPMS_API = 'https://api.npms.io/v2/package' +const SafeStringSchema = v.pipe(v.string(), v.regex(/^[^<>"&]*$/, 'Invalid characters')) + const QUERY_SCHEMA = v.object({ - color: v.optional(v.string()), + color: v.optional(SafeStringSchema), name: v.optional(v.string()), - labelColor: v.optional(v.string()), - label: v.optional(v.string()), + labelColor: v.optional(SafeStringSchema), + label: v.optional(SafeStringSchema), }) const COLORS = { @@ -338,7 +341,7 @@ export default defineCachedEventHandler( const type = getRouterParam(event, 'type') ?? 'version' const pkg = getRouterParam(event, 'pkg') ?? '' const query = getQuery(event) - return `badge:${type}:${pkg}:${JSON.stringify(query)}` + return `badge:${type}:${pkg}:${hash(query)}` }, }, )