Skip to content

Commit 818ba57

Browse files
committed
fix: derive cache key from resolved options, not raw query
resolvePathCacheKey now hashes the filtered/sanitized options object instead of the raw getQuery(e). This closes the gap where cacheQueryParams allowed arbitrary query params to inflate cache keys even after prop filtering.
1 parent 7319cf1 commit 818ba57

File tree

1 file changed

+7
-5
lines changed

1 file changed

+7
-5
lines changed

src/runtime/server/og-image/context.ts

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -26,17 +26,19 @@ import { getBrowserRenderer, getSatoriRenderer, getTakumiRenderer } from './inst
2626

2727
const RE_HASH_MODE = /^o_([a-z0-9]+)$/i
2828

29-
export function resolvePathCacheKey(e: H3Event, path: string, includeQuery = false) {
29+
export function resolvePathCacheKey(e: H3Event, path: string, resolvedOptions?: Record<string, any>) {
3030
const siteConfig = getSiteConfig(e, {
3131
resolveRefs: true,
3232
})
3333
const basePath = withoutTrailingSlash(withoutLeadingSlash(normalizeKey(path)))
34-
const hashParts = [
34+
const hashParts: any[] = [
3535
basePath,
3636
import.meta.prerender ? '' : siteConfig.url,
3737
]
38-
if (includeQuery)
39-
hashParts.push(hash(getQuery(e)))
38+
// Hash resolved options (not raw query string) so unknown/extra query params
39+
// cannot produce unique cache keys and bypass the cache.
40+
if (resolvedOptions)
41+
hashParts.push(hash(resolvedOptions))
4042
return [
4143
(!basePath || basePath === '/') ? 'index' : basePath,
4244
hash(hashParts),
@@ -172,7 +174,7 @@ export async function resolveContext(e: H3Event): Promise<H3Error | OgImageRende
172174
// so use the options hash directly as cache key to avoid all hash-mode images sharing one cache entry.
173175
// Component hash is appended so template changes invalidate the runtime cache.
174176
const baseCacheKey = normalised.options.cacheKey
175-
|| (hashMatch ? `hash:${hashMatch[1]}` : resolvePathCacheKey(e, basePathWithQuery, runtimeConfig.cacheQueryParams))
177+
|| (hashMatch ? `hash:${hashMatch[1]}` : resolvePathCacheKey(e, basePathWithQuery, normalised.options))
176178
const key = componentHash ? `${baseCacheKey}:${componentHash}` : baseCacheKey
177179

178180
let renderer: ((typeof SatoriRenderer | typeof BrowserRenderer | typeof TakumiRenderer) & { __mock__?: true }) | undefined

0 commit comments

Comments
 (0)