GitHub Advisoryadvisory · npm
GHSA-2x6f-rp82-ppmj Nuxt OG Image cache poisoning through derivable cache keys on unsigned dynamic image routes
MEDIUM
Official page ↗
- Aliases
- CVE-2026-102527
- Ecosystem
- npm
- Packages
- nuxt-og-image
- Severity
- Moderate
- CVSS vector
- CVSS:4.0/AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:L/VA:N/SC:N/SI:N/SA:N
- Weaknesses
- CWE-349
- Reviewed
- 2026-10-15
Affected packages
• npm nuxt-og-image: >= 6.2.5, < 6.7.0 → fixed in 6.7.0
Description
Vendor: Nuxt
Product: Nuxt OG Image
Version: 6.2.5
Description: Due to the specifics of caching and key generation in the Open Graph image cache created by the module, an unauthenticated attacker can modify the content of the image (for example, the `title` parameter) that is delivered to the user.
Impact: Content Spoofing
Vulnerable component: route `/_og/d/*.png`
Exploitation conditions: Access to the application
Mitigation: Upgrade to 6.7.2 and set a sufficiently secure `secret` in config `ogImage`
Researcher: Dmitry Vanin (Positive Technologies)
Research
During the previous vulnerability research, it was discovered that version 6.2.5 changed the mechanism for generating cache indexes; it now takes into account the parameters passed during image generation.
However, the image is still generated from data transmitted to the attacker.
_Listing 1. New code for generating indexes in cache_
```
export function resolvePathCacheKey(e: H3Event, path: string, resolvedOptions?: Record) {
const siteConfig = getSiteConfig(e, {
resolveRefs: true,
})
const basePath = withoutTrailingSlash(withoutLeadingSlash(normalizeKey(path)))
const hashParts: any[] = [
basePath,
import.meta.prerender ? '' : siteConfig.url,
]
// Hash resolved options (not raw query string) so unknown/extra query params
// cannot produce unique cache keys and bypass the cache.
if (resolvedOptions)
hashParts.push(hash(resolvedOptions))
return [
(!basePath || basePath === '/') ? 'index' : basePath,
hash(hashParts),
].join(':')
}
```
In this case, `basePath` is obtained from the `_path` parameter, `resolvedOptions` are the normalized settings of the component, for example:
_Listing 2. An example of `resolvedOptions`_
```
{"emojis":"noto","extension":"png","width":1200,"height":600,"cacheMaxAgeSeconds":259200,"component":"OgImageDefaultImageTakumi"}
```
From the analysis of `resolvedOptions`, it was concluded that, in general, all parameters are known either from the direct link to the OG Image or from the server response.
Vulnerability reproduction
1. Find the route to OG Image.
_Figure 1. Demonstration of finding the route to OG Image_
2. Retrieve parameters from the server’s response, especially `cacheMaxAgeSeconds` (`cache-control` header, `s-maxage` key), the other parameters are known from the meta tags as well as from the `c_` parameter.
_Figure 2. Obtaining parameters_
3. Generate a cache key using a script.
_Listing 3. Srcipt_
```
import {hash} from "ohash";
var url = "https://contoso.com"
var obj = JSON.parse(`{"emojis":"noto","extension":"png","width":1200,"height":600,"cacheMaxAgeSeconds":259200,"component":"OgImageBlogPostTakumi"}`)
var basePath = '/'
var hashParts = [
basePath,
url
]
if (obj)
hashParts.push(hash(obj))
console.log([
(!basePath || basePath === '/') ? 'index' : basePath,
hash(hashParts),
].join(':'))
```
4. Repeat the steps as in the vulnerability 1, but transmit the obtained `cacheKey` in addition.
5. Thus, the same result as in the vulnerability 1 was obtained.
_Figure 4. Server response_
Credits
Researcher: Dmitry Vanin (Positive Technologies)
Related
Alias · CVE (1)
- CVE-2026-102527 Nuxt OG Image generates OG Images with Vue templates in Nuxt. vulnerability
Weakness · CWE (1)
- CWE-349 Acceptance of Extraneous Untrusted Data With Trusted Data weakness
References
- https://github.com/nuxt-modules/og-image/security/advisories/GHSA-2x6f-rp82-ppmj web
- https://nvd.nist.gov/vuln/detail/CVE-2026-102527 advisory
- https://github.com/nuxt-modules/og-image/pull/638 web
- https://github.com/nuxt-modules/og-image/commit/e6c5b53ce7f434ab8cbc91298dccfb2b515c56a5 web
- https://github.com/nuxt-modules/og-image package
- https://github.com/nuxt-modules/og-image/releases/tag/v6.7.0 web