Vendor: Nuxt
Product: Nuxt OG Image
Version: 6.2.5
CWE-ID: CWE-349: Acceptance of Extraneous Untrusted Data With Trusted Data
CVSS vector v.4.0: 8.8 (AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N)
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<string, any>) {
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
- Find the route to OG Image.
Figure 1. Demonstration of finding the route to OG Image
- 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_<component name> parameter.
Figure 2. Obtaining parameters
- 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(':'))
- Repeat the steps as in the vulnerability 1, but transmit the obtained
cacheKey in addition.
- Thus, the same result as in the vulnerability 1 was obtained.
Figure 4. Server response
Credits
Researcher: Dmitry Vanin (Positive Technologies)
Remediation (v6.7.0, #638): URL signing is enabled by default from v6.7.0; the signature covers the encoded params including cacheKey, so a forged or derived cache key on an unsigned request is rejected with 403 before it can select the cache slot.
Vendor: Nuxt
Product: Nuxt OG Image
Version: 6.2.5
CWE-ID: CWE-349: Acceptance of Extraneous Untrusted Data With Trusted Data
CVSS vector v.4.0: 8.8 (AV:N/AC:L/AT:N/PR:N/UI:N/VC:N/VI:H/VA:L/SC:N/SI:N/SA:N)
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
titleparameter) that is delivered to the user.Impact: Content Spoofing
Vulnerable component: route
/_og/d/*.pngExploitation conditions: Access to the application
Mitigation: Upgrade to 6.7.2 and set a sufficiently secure
secretin configogImageResearcher: 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
In this case,
basePathis obtained from the_pathparameter,resolvedOptionsare the normalized settings of the component, for example:Listing 2. An example of
resolvedOptionsFrom 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
Figure 1. Demonstration of finding the route to OG Image
cacheMaxAgeSeconds(cache-controlheader,s-maxagekey), the other parameters are known from the meta tags as well as from thec_<component name>parameter.Figure 2. Obtaining parameters
Listing 3. Srcipt
cacheKeyin addition.Figure 4. Server response
Credits
Researcher: Dmitry Vanin (Positive Technologies)
Remediation (v6.7.0, #638): URL signing is enabled by default from v6.7.0; the signature covers the encoded params including
cacheKey, so a forged or derived cache key on an unsigned request is rejected with 403 before it can select the cache slot.