ช่องโหว่ Node.js: แพตช์ Node2Shell และวิธีตรวจสอบเวอร์ชัน Node.js (WordPress)

Node2Shell คือชื่อเรียกของ CVE-2026-111497 ช่องโหว่ Node.js ที่มีการเปิดเผยแพตช์เมื่อวันที่ 21 ตุลาคม 2026 โดยชื่อทางการระบุว่าเป็นข้อบกพร่องการเขียนข้อมูลนอกขอบเขตในตัวถอดรหัส Brotli ของ Google เนื่องจากการคลายการบีบอัดข้อมูล Brotli ที่ถูกดัดแปลงอาจนำไปสู่การรันโค้ดจากระยะไกลได้ สิ่งแรกที่ต้องทำคือตรวจสอบเวอร์ชันของ Node.js, Bun และ libbrotli บนเซิร์ฟเวอร์ แล้วอัปเกรดเป็นเวอร์ชันที่แพตช์แล้ว
นี่คือขั้นตอนการตรวจสอบแพ็กเกจที่ใช้ตัวถอดรหัส Brotli และเส้นทางที่คำขอระยะไกลของ WordPress ผ่าน libbrotli บนเซิร์ฟเวอร์แบบ Nginx + Apache ที่ติดตั้ง WordPress 7.1.3
1️⃣ ช่องโหว่ Node.js Node2Shell: หลักการของข้อบกพร่องและขอบเขตผลกระทบ
ชื่อ Node2Shell เป็นชื่อเรียกที่ทีมวิจัยของบริษัทความปลอดภัย Imperva ตั้งไว้ในบทความวิจัยเมื่อวันที่ 22 ตุลาคม หัวข้อของประกาศจาก nodejs.org คือ [Brotli decoder out-of-bounds write permits remote code execution] ข้อบกพร่องอยู่ในซอร์สโค้ดตัวถอดรหัส Google Brotli ที่ฝังมาใน Node.js (c/dec/decode.c) จึงป้องกันไม่ได้ด้วยการแก้โค้ดของแอปพลิเคชัน
ตามบันทึกของ NVD ตัวถอดรหัส Google Brotli 1.0.3 ถึง 1.2.0 จะเขียนข้อมูลเลยปลายบัฟเฟอร์เมื่อคลายสตรีมที่ถูกดัดแปลง และทำให้หน่วยความจำสถานะของตัวถอดรหัสที่อยู่ติดกันเสียหาย ผู้โจมตีจากระยะไกลที่ไม่ได้ล็อกอินสามารถใช้ข้อบกพร่องนี้อ่านข้อมูลในหน่วยความจำของเซิร์ฟเวอร์ ทำให้บริการหยุดทำงาน และรันโค้ดใดก็ได้
การจัดระดับความรุนแรงมีสองแบบ ประกาศของ nodejs.org จัดไว้ที่ระดับ High ส่วน Google ซึ่งเป็นผู้ออก CVE ให้คะแนน 9.2 (Critical) ตาม CVSS 4.0 ณ วันที่ 23 ตุลาคม NVD ยังวิเคราะห์เองไม่เสร็จ จึงยังไม่มีคะแนนของ NVD ประเภทจุดอ่อนคือการไม่ตรวจสอบค่าที่ส่งกลับ (CWE-252) และการเขียนนอกขอบเขต (CWE-787)
ตามประกาศความปลอดภัยของ nodejs.org Node.js สาย 22.x, 24.x และ 26.x ที่ยังได้รับการสนับสนุนได้รับผลกระทบทั้งหมด และเวอร์ชันที่แพตช์แล้วคือ 22.23.4, 24.22.1 และ 26.12.1 ประกาศเดียวกันระบุว่าสายที่หมดการสนับสนุนแล้วจะถือว่าได้รับผลกระทบเสมอทุกครั้งที่มีประกาศความปลอดภัย
โปรแกรมที่ใช้ตัวถอดรหัสเดียวกันได้รับผลกระทบทั้งหมด แม้จะอยู่นอก Node.js ก็ตาม เมื่อวันที่ 21 ตุลาคม Google ออกไลบรารี Brotli สามเวอร์ชันที่แก้ CVE เดียวกัน ได้แก่ 1.0.10, 1.1.1 และ 1.2.1 ส่วน Bun ใส่ Brotli ไว้ในรายการแก้ไขความปลอดภัยของประกาศ 1.4.4 เมื่อวันที่ 22 ตุลาคม และ issue ในรีโพซิทอรีระบุว่าเวอร์ชันนั้นมีการแก้ไขที่อัปเดต brotli
| ปลายทาง | เวอร์ชันที่ได้รับผลกระทบ | เวอร์ชันที่แก้ไข | แหล่งอ้างอิง |
|---|---|---|---|
| Node.js | สาย 22.x · 24.x · 26.x ที่ยังได้รับการสนับสนุนทั้งหมด · สายที่หมดการสนับสนุนแล้ว | 22.23.4 · 24.22.1 · 26.12.1 | ประกาศความปลอดภัยของ nodejs.org (2026-10-21) |
| ไลบรารี Brotli ของ Google | 1.0.3 ~ 1.2.0 | 1.0.10 · 1.1.1 · 1.2.1 | บันทึกของ NVD · รีลีสของ google/brotli (2026-10-21) |
| Bun | มี Brotli ในรายการแก้ไขความปลอดภัยของประกาศ 1.4.4 | 1.4.4 | ประกาศของ Bun (2026-10-22) |
| แพ็กเกจ libbrotli ของดิสทริบิวชัน | แพ็กเกจที่สร้างจาก Brotli 1.0.3 ถึง 1.2.0 | เวอร์ชันที่ประกาศความปลอดภัยของดิสทริบิวชันจะออก (ณ 2026-10-23 ยังไม่มี) | หน้าติดตามความปลอดภัยของแต่ละดิสทริบิวชัน |
ตัว Node.js เองไม่ได้คลายการบีบอัดข้อมูล Brotli ที่รับมาด้วยตัวเอง ตามประกาศความปลอดภัยของบริษัทโฮสติ้ง Vercel จุดที่เปิดรับความเสี่ยงคือจุดที่แอปหรือไลบรารีคลายการบีบอัดข้อมูลที่ถูกบีบอัดซึ่งมาจากภายนอก ตัวอย่างเช่น ตอนที่ fetch() ในตัวรับการตอบกลับแบบ br และตอนที่ Express 5 หรือ body-parser 2 คลายการบีบอัดเนื้อหาคำขอแบบ br ส่วนเซิร์ฟเวอร์ HTTP พื้นฐานที่รับอย่างเดียวจะไม่คลายการบีบอัด
ณ วันที่ 23 ตุลาคม ยังไม่มีการยืนยันว่ามีการโจมตีจริง CVE นี้ไม่อยู่ในแคตตาล็อกช่องโหว่ที่ทราบว่าถูกใช้โจมตีของ CISA (KEV ฉบับวันที่ 21 ตุลาคม) ส่วนระดับการโจมตีที่ CISA กำหนดในบันทึก CVE เปลี่ยนเป็น [เผยแพร่การพิสูจน์แนวคิด (PoC)] เมื่อวันที่ 23 ตุลาคม
สิ่งที่ต้องทำขึ้นอยู่กับว่าตัวถอดรหัสอยู่ที่ไหน ไบนารีทางการของ Node.js ฝังตัวถอดรหัสไว้ในไฟล์ปฏิบัติการ และยังมีบิลด์ที่ใช้ libbrotli ของระบบ เช่น แพ็กเกจ nodejs ของ Debian ดิสทริบิวชัน Linux ติดตั้งซอร์สเดียวกันเป็นแพ็กเกจ libbrotli ให้โปรแกรมอย่าง curl ใช้ร่วมกัน
2️⃣ เว็บไซต์ WordPress และ PHP ก็ได้รับผลกระทบ: เส้นทางที่คำขอระยะไกลคลายการบีบอัดการตอบกลับด้วย libbrotli
แม้แต่เซิร์ฟเวอร์ WordPress ที่ไม่ได้ติดตั้ง Node.js ก็มีตัวถอดรหัสเดียวกันอยู่ในรูปแพ็กเกจ libbrotli ณ วันที่ 23 ตุลาคม ฝั่ง WordPress, curl และ PHP ยังไม่มีการกล่าวถึง CVE นี้อย่างเป็นทางการ และ CVE นี้ก็ไม่อยู่ในรายการช่องโหว่ทางการของ curl ด้วย บทนี้จึงยืนยันเพียงโครงสร้างจากโค้ดแกนหลัก เอกสารของ curl และการวัดจริงบนเซิร์ฟเวอร์ทดสอบ
บนเซิร์ฟเวอร์แบบ Nginx + Apache ที่วัดจริง มีแพ็กเกจที่ต้องใช้ไลบรารีตัวถอดรหัส (libbrotlidec) ห้าตัว และตัวที่เชื่อมกับ WordPress คือ libcurl
rpm -q --whatrequires 'libbrotlidec.so.1()(64bit)' | sed 's/-[0-9].*//'freetype
brotli-devel
libjxl
libcurl
libsoupเหตุที่ libcurl ต้องใช้ libbrotli คือเพื่อคลายการบีบอัดการตอบกลับ HTTP ที่ถูกบีบอัด ตามเอกสารทางการของ curl libcurl ที่บิลด์พร้อมไลบรารี brotli จะคลายการบีบอัดการตอบกลับที่มี Content-Encoding เป็น br โดยอัตโนมัติ และส่วนขยาย curl ของ PHP ก็เรียกใช้ libcurl ตัวนั้นโดยตรง
ldd /usr/lib64/libcurl.so.4 | grep brotli libbrotlidec.so.1 => /lib64/libbrotlidec.so.1 (0x00007f32803ed000)
libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007f327f858000)php -i | grep BROTLIBROTLI => Yesเวอร์ชันของ libcurl ที่ WordPress ใช้จะแสดงในแถว [รุ่นของ cURL] เมื่อคุณขยายส่วน [เซิร์ฟเวอร์] ในแท็บ [ข้อมูล] ของ [เครื่องมือ › สุขภาพเว็บ] บนหน้าจอผู้ดูแล แถวนั้นไม่บอกว่ารองรับ brotli หรือไม่ จึงต้องตรวจสอบด้วยคำสั่งบนเซิร์ฟเวอร์อย่างข้างบน
แถว [รุ่นของ cURL] ในภาพแสดงเวอร์ชันของ libcurl พร้อมไลบรารี SSL ที่บิลด์มาด้วยกัน ตามเอกสารของ curl br รองรับตั้งแต่ 7.57.0 ถ้าค่านี้ต่ำกว่านั้นจะคลายการบีบอัดการตอบกลับแบบ br ไม่ได้ ถ้าเท่ากันหรือสูงกว่า ให้ตรวจสอบด้วยคำสั่งบนเซิร์ฟเวอร์ว่าบิลด์นั้นมี brotli หรือไม่
ไลบรารี Requests ในแกนหลักของ WordPress ตั้งค่า [CURLOPT_ENCODING] ของแฮนเดิล curl เป็นสตริงว่างเมื่อส่งคำขอไปยังที่อยู่ภายนอก ตามเอกสารของ curl สตริงว่างหมายถึงการรับทุกวิธีบีบอัดที่ libcurl ตัวนั้นรองรับ ดังนั้นถ้าเซิร์ฟเวอร์ปลายทางส่งการตอบกลับที่บีบอัดด้วย br มา libbrotli ของเซิร์ฟเวอร์ WordPress ก็จะเป็นตัวคลายการบีบอัด
grep -n CURLOPT_ENCODING wp-includes/Requests/src/Transport/Curl.php110: curl_setopt($this->handle, CURLOPT_ENCODING, '');
212: curl_setopt($this->handle, CURLOPT_ENCODING, 'none');บรรทัด 110 เป็นค่าเริ่มต้นของทุกคำขอ ส่วนบรรทัด 212 ทำงานเฉพาะตอนส่งคำขอที่คลายการบีบอัดไม่สำเร็จซ้ำแบบไม่บีบอัด ไม่มีทางโจมตีตรงจากภายนอกได้ ต้องยึดเซิร์ฟเวอร์ปลายทางที่ WordPress รับการตอบกลับมาก่อน เช่น การตรวจหาอัปเดตของแกนหลักและปลั๊กอิน oEmbed หรือฟีด RSS
ลำดับเริ่มจากข้อมูลบีบอัดแบบ br ที่มาจากภายนอก ข้อบกพร่องถูกกระตุ้นในขั้นที่ fetch() ของ Node.js, Express 5, fetch() ของ Bun หรือ libbrotli ที่ libcurl ของ WordPress เรียกใช้คลายการบีบอัดข้อมูลนั้น ผลที่ได้นำไปสู่การรันโค้ดบนเซิร์ฟเวอร์ เวอร์ชันที่แพตช์แล้วจะหยุดลำดับนี้ สิ่งที่ต้องทำจึงเป็นการเปลี่ยนตัวถอดรหัสเป็นเวอร์ชันที่แพตช์แล้ว
mod_brotli ของ Apache ลิงก์เฉพาะไลบรารีตัวเข้ารหัส (libbrotlienc) ที่ใช้บีบอัดการตอบกลับ การตั้งค่าที่เปิดการบีบอัดด้วยโมดูลนี้จึงไม่อยู่ในเส้นทางของข้อบกพร่องตัวถอดรหัส
ldd /usr/lib64/httpd/modules/mod_brotli.so | grep brotli libbrotlienc.so.1 => /lib64/libbrotlienc.so.1 (0x00007f34b4b79000)
libbrotlicommon.so.1 => /lib64/libbrotlicommon.so.1 (0x00007f34b4a79000)3️⃣ ตรวจสอบเวอร์ชัน Node.js: เซิร์ฟเวอร์มี Node.js, Bun และ libbrotli หรือไม่ และเป็นเวอร์ชันใด
สิ่งแรกที่ต้องทำคือสำรวจว่าบนเซิร์ฟเวอร์ติดตั้งอะไรไว้บ้าง สำหรับ Node.js ให้ดูเวอร์ชันด้วย [node -v] ถ้าค่าต่ำกว่า 22.23.4, 24.22.1 หรือ 26.12.1 ตามสายของตัวเองถือว่าได้รับผลกระทบ
| สภาพแวดล้อมของคุณ | คำสั่งตรวจสอบ | สิ่งที่ได้รับการแก้ |
|---|---|---|
| ตัวติดตั้งจาก nodejs.org · nvm · อิมเมจ Docker ทางการ | [node -v] | ตัว Node.js เอง (22.23.4 · 24.22.1 · 26.12.1) |
| nodejs ของดิสทริบิวชัน · มีแถว libbrotli ใน ldd | [ldd $(command -v node)] | แพ็กเกจ libbrotli |
| nodejs ของดิสทริบิวชัน · ผล ldd เป็น 0 | [ldd $(command -v node)] | แพ็กเกจ nodejs (หลังประกาศความปลอดภัยของดิสทริบิวชัน) |
| Node.js Selector บนแชร์โฮสติ้ง (CloudLinux alt-nodejs) | ประกาศของผู้ให้บริการ · หมายเลข release ของแพ็กเกจ | แพ็กเกจที่ผู้ให้บริการปล่อย + รีสตาร์ตแอป |
| Bun | [bun --version] | Bun 1.4.4 ขึ้นไป |
| ไม่มี Node.js (มีเฉพาะ WordPress) | ตรวจสอบ libcurl ด้วย [ldd] | แพ็กเกจ libbrotli + รีสตาร์ต php-fpm · ระหว่างนั้นใช้มาตรการชั่วคราว |
| Managed Hosting | ประกาศของผู้ให้บริการ · สอบถาม | แพ็กเกจที่ผู้ให้บริการอัปเกรด |
บน PC (Windows หรือ macOS) ให้ติดตั้งใหม่ด้วยตัวติดตั้งเวอร์ชันที่แพตช์แล้วจาก nodejs.org ส่วน nvm ให้ดูเวอร์ชันด้วย [nvm ls] แล้วติดตั้งใหม่ตามหมายเลขสาย เช่น [nvm install 24] แท็ก 22, 24 และ 26 ของอิมเมจ node ทางการบน Docker ถูกสร้างใหม่ด้วยเวอร์ชันที่แพตช์แล้วเมื่อวันที่ 22 ตุลาคม จึงต้องดึงอิมเมจใหม่ บิลด์ และดีพลอย ประกาศของ Vercel ยังแนะนำให้อัปเกรดอิมเมจคอนเทนเนอร์ที่บิลด์เอง สภาพแวดล้อม CI และสภาพแวดล้อมพัฒนาในเครื่องเป็นเวอร์ชันที่แพตช์แล้วด้วย
เซิร์ฟเวอร์ที่ ติดตั้ง Node.js ผ่านสตรีม dnf module จะแสดงเวอร์ชันในสายของสตรีมนั้นใน [node -v] แม้สายจะตรงกัน แต่ถ้าเลขท้ายยังไม่ถึงเวอร์ชันที่แพตช์แล้วก็ต้องอัปเกรด
node -vv24.xx.xตรวจสอบด้วย [ldd] ว่า Node.js ใช้ libbrotli ของระบบหรือใช้ตัวถอดรหัสที่ฝังมา ถ้าผลลัพธ์มีแถว libbrotlidec แปลว่าเป็นบิลด์ที่ใช้ไลบรารีร่วม ถ้าเป็น 0 อย่างข้างล่าง แปลว่าตัวถอดรหัสฝังมาในตัว ต้องอัปเกรด Node.js เองจึงจะแก้ได้
ldd $(command -v node) | grep -c brotli0สำหรับ Bun ให้ตรวจสอบเวอร์ชันด้วย [bun --version] และอัปเกรดถ้าต่ำกว่า 1.4.4
บนระบบตระกูล RPM ให้ดูเวอร์ชันของแพ็กเกจ libbrotli ด้วย [rpm -q libbrotli] หมายเลขเวอร์ชันของแพ็กเกจเป็นเลขที่ดิสทริบิวชันกำหนด จึงไม่ควรเทียบกับหมายเลขรีลีสของ Google โดยตรง แต่ให้เทียบกับเวอร์ชันที่ประกาศความปลอดภัยของดิสทริบิวชันออกสำหรับหมายเลข CVE นี้
rpm -q libbrotlilibbrotli-1.0.x-x.el9_x.x86_64ตรวจสอบว่าดิสทริบิวชันออกประกาศแล้วหรือยังด้วย [dnf updateinfo info --cve CVE-2026-111497] ถ้าผลลัพธ์ว่างเปล่า แปลว่ารีโพซิทอรีนั้นยังไม่มีประกาศสำหรับ CVE นี้
dnf updateinfo info --cve CVE-2026-111497แพ็กเกจที่ย้ายเฉพาะการแก้ไขเข้ามาโดยคงหมายเลขเวอร์ชันเดิมไว้จะมีหมายเลข CVE อยู่ในบันทึกการเปลี่ยนแปลง จึงตรวจสอบด้วย [rpm -q --changelog libbrotli | grep CVE-2026-111497] ถ้ามีบรรทัดขึ้นมาแปลว่าเป็นแพ็กเกจที่แพตช์แล้ว
rpm -q --changelog libbrotli | grep CVE-2026-111497ณ วันที่ 23 ตุลาคม แพ็กเกจ libbrotli ของ Debian, Ubuntu, Red Hat และ AlmaLinux ยังไม่มีเวอร์ชันที่แพตช์ CVE นี้ Alpine มีเวอร์ชันที่แพตช์แล้วเฉพาะแพ็กเกจ nodejs โดยอ้างอิงจากหน้าติดตามความปลอดภัยของแต่ละดิสทริบิวชัน ตอนนี้จึงต้องเฝ้าดูว่าประกาศความปลอดภัยของดิสทริบิวชันออกหรือยัง แล้วค่อยอัปเกรดเมื่อออก
ตระกูล Debian และ Ubuntu ใช้ชื่อแพ็กเกจ libbrotli1 และได้ตรวจสอบรายการเดียวกันบนเซิร์ฟเวอร์ทดสอบ Debian 12 ของโฮสติ้งแบบมีผู้ดูแลรายหนึ่ง เซิร์ฟเวอร์นี้ก็เช่นกัน libcurl ลิงก์ libbrotlidec และส่วนขยาย curl ของ PHP รองรับ brotli บันทึกการเปลี่ยนแปลงดูได้ด้วย [zcat /usr/share/doc/libbrotli1/changelog.Debian.gz | grep CVE-2026-111497]
dpkg -l libbrotli1 | tail -1ii libbrotli1:amd64 1.1.0-2+0~20240305.8+debian12~1.gbp62df71 amd64 library implementing brotli encoder and decoder (shared libraries)ldd /usr/lib/x86_64-linux-gnu/libcurl.so.4 | grep brotli libbrotlidec.so.1 => /lib/x86_64-linux-gnu/libbrotlidec.so.1 (0x00007fa2baac6000)
libbrotlicommon.so.1 => /lib/x86_64-linux-gnu/libbrotlicommon.so.1 (0x00007fa2b9cb9000)4️⃣ อัปเดต Node.js: อัปเกรดเป็นเวอร์ชันที่แพตช์แล้วและตรวจสอบอีกครั้ง
สำหรับโฮสติ้งแบบมีผู้ดูแลและแชร์โฮสติ้ง ผู้ให้บริการจะเป็นผู้อัปเกรดแพ็กเกจบนเซิร์ฟเวอร์ จึงต้องตรวจสอบสถานะการแพตช์ Node.js และ libbrotli จากประกาศหรือสอบถามผู้ให้บริการ ถ้าคุณดูแลเซิร์ฟเวอร์เอง ให้อัปเกรด Node.js เป็นเวอร์ชันที่แพตช์แล้วตามประกาศของ nodejs.org และอัปเกรด Bun เป็น 1.4.4 ขึ้นไปด้วย [bun upgrade]
Node.js ที่ติดตั้งผ่านสตรีมโมดูลของดิสทริบิวชันจะอัปเกรดด้วยคำสั่งแบบ [dnf upgrade nodejs] หลังจากเวอร์ชันที่แพตช์แล้วขึ้นมาในรีโพซิทอรีนั้น เซิร์ฟเวอร์ที่ดาวน์โหลดจาก nodejs.org มาติดตั้งเองให้เปลี่ยนเป็นเวอร์ชันที่แพตช์แล้วจากที่เดียวกัน สายที่หมดการสนับสนุนแล้วจะไม่มีเวอร์ชันที่แพตช์ จึงต้องย้ายไปสาย 22, 24 หรือ 26 ที่ยังได้รับการสนับสนุน
Node.js Selector บนแชร์โฮสติ้ง (CloudLinux alt-nodejs) มีสำเนา brotli ของตัวเองแยกไว้ การอัปเกรด libbrotli ของระบบจึงแก้ไม่ได้ ตามประกาศของ CloudLinux ต้องเปลี่ยนเป็นแพ็กเกจที่ผู้ให้บริการปล่อยแล้วรีสตาร์ตแอป ไบนารีใหม่จึงจะทำงาน ประกาศเดียวกันระบุว่าเวอร์ชันที่หมดการสนับสนุนแล้วจะมีค่า [node --version] เท่าเดิม จึงต้องตรวจสอบจากหมายเลข release ของแพ็กเกจ
สำหรับแพ็กเกจ libbrotli เมื่อประกาศความปลอดภัยของดิสทริบิวชันออกแล้วให้อัปเกรดแพ็กเกจนั้น และรีสตาร์ตโปรเซสที่โหลดไลบรารีไว้ในหน่วยความจำ จึงจะเปลี่ยนไปใช้ไลบรารีใหม่ ไลบรารีร่วมถูกอ่านตอนที่โปรเซสเริ่มทำงาน บนเซิร์ฟเวอร์ WordPress จึงต้องทำไปจนถึงการรีสตาร์ต php-fpm
หลังอัปเกรดแล้วให้ดูว่า [node -v] เป็นเวอร์ชันที่แพตช์แล้วขึ้นไป และ [rpm -q libbrotli] เป็นเวอร์ชันตามประกาศของดิสทริบิวชันหรือไม่ ตรวจสอบว่าหมายเลข CVE เข้าไปอยู่ในบันทึกการเปลี่ยนแปลงแล้วด้วย [rpm -q --changelog libbrotli | grep CVE-2026-111497] ถ้ารีสตาร์ต php-fpm แล้ว ให้ตรวจสอบสถานะบริการและการตอบสนองของเว็บไซต์ด้วย
systemctl is-active php-fpmactivecurl -s -o /dev/null -w '%{http_code}\n' 'https://example.com/?r=1'2005️⃣ มาตรการชั่วคราวก่อนแพตช์: ปิดการคลายการบีบอัด br ในคำขอระยะไกลของ WordPress
คำแนะนำเรื่อง CVE ของ Red Hat แนะนำให้ตั้งค่าแอปไม่ให้รับ หรือไม่ให้คลายการบีบอัด br ที่มาจากแหล่งที่เชื่อถือไม่ได้โดยอัตโนมัติ
แม้แพ็กเกจที่แพตช์แล้วจะยังไม่ออก ก็ปิดเส้นทางฝั่ง WordPress ได้ตั้งแต่ตอนนี้ WordPress มีฮุก [http_api_curl] ที่ส่งแฮนเดิล curl มาให้ในทุกคำขอระยะไกล ถ้าตั้ง [CURLOPT_ENCODING] เป็น null ตรงนั้น การคลายการบีบอัดอัตโนมัติของ libcurl จะถูกปิด
ถ้าวางไฟล์ด้านล่างไว้ในโฟลเดอร์ [wp-content/mu-plugins/] จะมีผลกับทุกคำขอระยะไกล ชื่อไฟล์เป็นเพียงตัวอย่าง ถ้าจะย้อนกลับก็ลบไฟล์นี้
<?php
// no-brotli-decode.php — WordPress ระยะไกล ในคำขอ libcurl อัตโนมัติ การคลาย ปิด(libbrotli แพตช์ เวอร์ชัน ออก จนกว่า)
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
add_action( 'http_api_curl', function ( $handle ) {
curl_setopt( $handle, CURLOPT_ENCODING, null );
}, 99 );หลายคนอาจคิดว่าถ้าจำกัด [CURLOPT_ENCODING] ไว้ที่ [gzip, deflate] จะตัด br ออกไปได้ ค่านั้นเพียงแค่เอา br ออกจากเฮดเดอร์ Accept-Encoding ของคำขอ ถ้าเซิร์ฟเวอร์ปลายทางตอบกลับมาด้วย br libcurl ก็ยังคลายการบีบอัดตามที่ได้รับมา ผลจากการดึง httpbin.org/brotli ด้วยค่าเดียวกันบนเว็บไซต์ทดสอบ การตอบกลับที่มี Content-Encoding เป็น br ถูกคลายการบีบอัดและอ่านได้ตามปกติ
ตามเอกสารของ curl ค่าที่ปิดการคลายการบีบอัดอัตโนมัติได้มีเพียง null เท่านั้น ถ้าเป็น null จะไม่ส่งเฮดเดอร์ Accept-Encoding และไม่คลายการบีบอัดเนื้อหาที่ได้รับ การตอบกลับแบบ gzip และ deflate ไลบรารี Requests ของ WordPress จะคลายเองจึงยังอ่านได้ตามเดิม เหลือเพียงการตอบกลับแบบ br ที่ไม่ถูกคลายการบีบอัด
ฮุกนี้คือจุดที่ WordPress เชื่อมไว้กับตำแหน่ง [curl.before_send] ซึ่ง Requests เรียกก่อนรัน curl ทันที มีการเรียกที่บรรทัด 174 ของ Curl.php และรัน curl ที่บรรทัด 205 ค่าสตริงว่างที่แกนหลักใส่ไว้ที่บรรทัด 110 จึงถูกเขียนทับในช่วงนั้น
ตรวจสอบว่ามีผลหรือไม่ด้วยไฟล์ทดสอบด้านล่าง httpbin.org เป็นที่อยู่สำหรับทดสอบที่ส่งเฮดเดอร์คำขอที่ได้รับกลับมาให้ และยังส่งการตอบกลับที่บีบอัดด้วย br และ gzip ให้ด้วย จึงเห็นได้ในครั้งเดียวว่า WordPress ส่งอะไรและคลายการบีบอัดอะไร
<?php
// br-check.php — WordPress ระยะไกล คำขอ แบบใด การบีบอัด ส่ง คลายหรือไม่ ยืนยัน(httpbin.org ทดสอบ ที่อยู่)
$h = json_decode( wp_remote_retrieve_body( wp_remote_get( 'https://httpbin.org/headers' ) ), true );
echo 'Accept-Encoding: ', isset( $h['headers']['Accept-Encoding'] ) ? $h['headers']['Accept-Encoding'] : '(none)', PHP_EOL;
foreach ( array( 'brotli', 'gzip' ) as $p ) {
$r = wp_remote_get( 'https://httpbin.org/' . $p );
$readable = strpos( wp_remote_retrieve_body( $r ), ': true' ) !== false;
echo $p, ': Content-Encoding=', wp_remote_retrieve_header( $r, 'content-encoding' ), ' / ', strlen( wp_remote_retrieve_body( $r ) ), ' bytes / ', ( $readable ? 'readable' : 'not decoded' ), PHP_EOL;
}ก่อนใส่ไฟล์ Accept-Encoding มี br อยู่ และการตอบกลับแบบ br ถูกคลายการบีบอัดจนอ่านได้
wp eval-file br-check.phpAccept-Encoding: deflate, gzip, br
brotli: Content-Encoding=br / 316 bytes / readable
gzip: Content-Encoding=gzip / 317 bytes / readableหลังใส่ไฟล์ เฮดเดอร์ Accept-Encoding หายไป การตอบกลับแบบ br ยังไม่ถูกคลายการบีบอัด และการตอบกลับแบบ gzip ยังอ่านได้ตามเดิม
wp eval-file br-check.phpAccept-Encoding: (none)
brotli: Content-Encoding=br / 199 bytes / not decoded
gzip: Content-Encoding=gzip / 272 bytes / readableเมื่ออัปเกรดเป็นแพ็กเกจ libbrotli ที่แพตช์แล้วของดิสทริบิวชันและรีสตาร์ต php-fpm เสร็จแล้ว ให้ลบไฟล์นี้เพื่อกลับไปเป็นแบบเดิม
🔢 FAQ & เนื้อหาแนะนำ
ความปลอดภัย
ช่องโหว่ OpenSSH CVE-2024-6387
ขั้นตอนที่บล็อกข้อบกพร่องของ OpenSSH ไว้ชั่วคราว แล้วติดตั้งแพตช์และตรวจสอบ
ความปลอดภัย
ความปลอดภัย WP: ความปลอดภัยของ wp-admin
การตั้งค่าที่ปกป้องหน้าผู้ดูแลระบบด้วยการเปลี่ยนที่อยู่ล็อกอิน จำกัดการล็อกอิน และบล็อก XML-RPC
เซิร์ฟเวอร์
อัปเดต Alma Linux: 9.4 → 9.8
ขั้นตอนอัปเกรด AlmaLinux 9.4 เป็น 9.8 และรายการที่ต้องตรวจสอบ
ℹ️ ประกาศเรื่องลิงก์แอฟฟิลิเอต
เนื้อหาของเว็บไซต์นี้มีลิงก์แอฟฟิลิเอต หากผู้เข้าชมซื้อสินค้าหรือบริการผ่านลิงก์เหล่านี้ เว็บไซต์นี้จะได้รับค่าคอมมิชชันจากผู้ขาย ในกระบวนการนี้ ราคาที่ผู้ซื้อจ่าย(ราคาจะลดลงเมื่อมีโปรโมชัน↓)จะไม่สูงขึ้นแต่อย่างใด ราคา ส่วนลด และข้อมูลสต็อกที่แสดงเป็นข้อมูล ณ เวลาที่เขียนและอาจต่างจากความเป็นจริง โปรดตรวจสอบกับผู้ขายอีกครั้งก่อนซื้อ การเลือกและการประเมินสินค้าเขียนตามเกณฑ์ของเราเอง และการได้รับค่าคอมมิชชันหรือไม่ไม่มีผลต่อลำดับการแนะนำหรือเนื้อหาการประเมิน