Logo
PolyShell CVE-2026-48356: Lỗ hổng upload file trong Magento khiến 953 cửa hàng nhiễm mã độc — Kiểm tra và vá ngay

PolyShell CVE-2026-48356: Lỗ hổng upload file trong Magento khiến 953 cửa hàng nhiễm mã độc — Kiểm tra và vá ngay

tobi
tobi•• … views

Ngày 27/10/2026, CISA — Cơ quan An ninh mạng và Hạ tầng Hoa Kỳ — đã đưa lỗ hổng PolyShell (CVE-2026-48356) trong Magento và Adobe Commerce vào danh mục lỗ hổng đang bị khai thác thực tế (KEV), với hạn khắc phục 10/11/2026 cho các cơ quan liên bang Mỹ. Đây không phải lỗ hổng “trên giấy”: Sansec vừa công bố một chiến dịch đã cài mã độc vào 953 cửa hàng online kể từ tháng 7/2025, phần lớn chạy Magento. Điều đáng nói là Adobe đã có bản vá từ tháng 7/2026, nhưng rất nhiều cửa hàng chưa cài — và kể cả đã cài, cửa hàng vẫn có thể đang mang sẵn cửa hậu của kẻ tấn công.

Nếu bạn đang vận hành một shop Magento hoặc Adobe Commerce, bài này dành cho bạn: chuyện gì đã xảy ra, cửa hàng nào bị ảnh hưởng, dấu hiệu nhận biết đã bị xâm nhập, và cách kiểm tra — vá — rà soát từng bước.

1. Chuyện gì vừa xảy ra?

PolyShell là tên Sansec đặt cho một lỗ hổng tải file không kiểm soát (unrestricted file upload, CWE-434) trong Magento và Adobe Commerce. Nó cho phép bất kỳ ai trên internet — không cần tài khoản, không cần đăng nhập — tải một file nguy hiểm lên máy chủ cửa hàng qua API giỏ hàng.

Dòng thời gian của vụ việc:

Mốc thời gian Sự kiện
16–17/03/2026 Sansec phát hiện các đợt dò quét đầu tiên và phát cảnh báo công khai về PolyShell
30/03/2026 Đợt tấn công ồ ạt: kẻ tấn công cài loader vào 471 cửa hàng chỉ trong khoảng 1 giờ
14/07/2026 Adobe phát hành APSB26-73 vá PolyShell cho các dòng còn hỗ trợ; khi đó Adobe nói chưa ghi nhận khai thác thực tế
24/10/2026 Sansec công bố báo cáo chiến dịch loader: 953 cửa hàng đã bị cài mã độc kể từ tháng 7/2025
27/10/2026 CISA đưa CVE-2026-48356 vào KEV, hạn khắc phục 10/11/2026

Điểm khiến vụ việc này khác với các lỗ hổng “vá là xong” thông thường: theo Sansec, một cửa hàng chạy Magento 2.4.7-p10 — không thiếu bất kỳ bản vá core nào — vẫn bị cài loader mới vào ngày 23/10/2026, chỉ một giờ sau một lần quét sạch. Nguyên nhân là kẻ tấn công đã “ở trong nhà” từ trước: một tài khoản admin giả tạo từ ngày 16/9 và một backdoor phát hiện ngày 24/9 vẫn còn nguyên sau các lần cập nhật. Bản vá đóng được cửa trước, nhưng kẻ trộm đã lẻn vào và giấu sẵn chìa khóa dự phòng thì đóng cửa thôi là chưa đủ.

2. PolyShell là gì? Giải thích dễ hiểu

Magento cho phép sản phẩm có “tuỳ chọn dạng file” (custom option): ví dụ khách mua áo in theo yêu cầu sẽ tải lên một tấm ảnh hoặc logo để in lên áo. Những file này được gửi qua REST API của giỏ hàng và lưu vào thư mục pub/media/custom_options/quote/ trên máy chủ.

Vấn đề nằm ở chỗ đoạn mã xử lý việc tải file này thiếu tới ba lớp kiểm tra, theo phân tích của Sansec:

  1. Không kiểm tra option ID — ID tuỳ chọn mà người gửi khai báo không hề được đối chiếu với tuỳ chọn thật của sản phẩm.
  2. Không kiểm tra loại tuỳ chọn — logic tải file chạy bất kể sản phẩm có tuỳ chọn dạng file hay không. Sản phẩm nào cũng “nhận” được file, kể cả sản phẩm không hề bán kèm dịch vụ in ấn.
  3. Không chặn đuôi file nguy hiểm — các đuôi .php, .phtml, .phar không bị chặn. Kiểm tra duy nhất là đọc phần đầu file xem có giống ảnh hay không (hàm getimagesizefromstring) — bước này qua mặt được rất dễ.

Nhờ đó, kẻ tấn công gửi lên một file polyglot — đúng như cái tên PolyShell (polyglot + webshell): vừa là ảnh GIF/PNG hợp lệ ở phần đầu, vừa chứa mã PHP ở phần sau. Các endpoint bị lợi dụng là route giỏ hàng khách vãng lai (POST/PUT /V1/guest-carts/...), không yêu cầu đăng nhập; riêng GraphQL dùng đường xử lý khác nên không bị ảnh hưởng.

Sau khi file nằm trên máy chủ, nó có chạy được hay không phụ thuộc vào cấu hình web server. Nếu server cho phép PHP thực thi trong thư mục media (nhiều gói hosting dùng cấu hình tuỳ biến và không chặn việc này), kẻ tấn công chỉ cần mở đường dẫn tới file là có toàn quyền chạy lệnh trên cửa hàng: đọc cơ sở dữ liệu, tạo admin mới, sửa trang thanh toán. Còn nếu server chặn tốt, file vẫn nằm yên trên ổ đĩa — và sẽ “sống dậy” bất cứ khi nào cấu hình thay đổi hay chuyển server. Thấy file lạ trong thư mục này là phải xử lý nghiêm túc, dù hiện tại nó chưa chạy được.

3. Ai bị ảnh hưởng?

Gần như mọi cửa hàng Magento 2 đang chạy bản chưa cài APSB26-73 đều nằm trong diện ảnh hưởng, ở cả bản miễn phí Magento Open Source lẫn bản thương mại Adobe Commerce. Adobe chấm lỗ hổng này 9.6 (Critical) trong bản tin APSB26-73 và ghi rõ không cần xác thực để khai thác; hồ sơ NVD chấm 9.3 — lệch nhau do cách đánh giá chi tiết, nhưng cả hai đều ở mức Critical.

Bảng phiên bản theo đúng bản tin APSB26-73 của Adobe (cập nhật lần cuối ngày 11/8/2026):

Sản phẩm Phiên bản bị ảnh hưởng Bản đã vá
Adobe Commerce 2.4.9; 2.4.8-p5, 2.4.7-p10, 2.4.6-p15, 2.4.5-p17, 2.4.4-p18 và các bản trước đó 2.4.9-2026-jul, 2.4.8-2026-jul, 2.4.7-2026-jul, 2.4.6-2026-jul, 2.4.5-2026-jul, 2.4.4-2026-jul
Magento Open Source 2.4.9; 2.4.8-p5, 2.4.7-p10, 2.4.6-p15 và các bản trước đó 2.4.9-2026-jul, 2.4.8-2026-jul, 2.4.7-2026-jul, 2.4.6-2026-jul
Adobe Commerce B2B 1.5.3; 1.5.2-p5, 1.4.2-p10, 1.3.4-p17, 1.3.3-p18 và các bản trước đó Các bản tương ứng có hậu tố -2026-jul
Adobe Commerce Events 1.6.0 đến 1.20.0 1.21.0

Vài lưu ý quan trọng khi đối chiếu phiên bản:

  • Bản vá chỉ có cho các dòng còn được hỗ trợ. Nếu cửa hàng đang ở dòng quá cũ (ví dụ 2.4.3 trở xuống) hoặc đã hết vòng đời hỗ trợ, sẽ không có bản vá riêng — hãy lên kế hoạch nâng cấp dòng, và trong lúc chờ đợi áp dụng ngay biện pháp chặn ở mục 7.
  • Bản vá tách riêng (isolated patch) chỉ được Adobe kiểm thử trên bản bảo mật mới nhất của từng dòng. Ví dụ shop đang ở 2.4.7-p1 thì cần lên 2.4.7-p10 trước khi áp bản vá tháng 7.
  • Adobe Commerce Cloud nhận bản vá qua gói cloud-patches mới nhất thay vì bản phát hành ở bảng trên.

4. Chiến dịch loader trên 953 cửa hàng: mục tiêu là gì?

Theo báo cáo ngày 24/10/2026 của Sansec, một nhóm tấn công duy nhất đã hoạt động liên tục từ tháng 7/2025 và cài mã độc vào tổng cộng 953 cửa hàng online, phần lớn chạy Magento. “Hàng hoá” chúng để lại là một đoạn JavaScript nhỏ gọi là loader, với vài đặc điểm rất đáng chú ý:

  • Loader sống trong cơ sở dữ liệu, không sống trong file. Nó được chèn vào bảng cms_block — nơi chứa các khối nội dung tĩnh mà Magento hiển thị lên trang (đầu trang, chân trang, banner…). Quét mã nguồn trên ổ đĩa sẽ không thấy nó.
  • Loader “kén khách” để né bị phát hiện. Nó kiểm tra dấu vết trình duyệt (fingerprint) và chỉ tải mã độc thật cho khách mua hàng thật. Scanner, bot phân tích hay urlscan.io ghé thăm chỉ nhận về trang trống hoặc lỗi 404 — khiến chủ shop quét hoài vẫn thấy “sạch”.
  • Hạ tầng đổi liên tục. Nhóm này đã luân phiên dùng 5 tên miền loader: manulfie.click, neswnsssn.click, lanhd6549tdhse.top, additionalver.com và mới nhất là deepveindrilling.com (đăng ký ngày 06/10/2026; 83 cửa hàng dính bản này, 60 trong số đó từng nhiễm trước).
  • Đường vào chính là PolyShell và một lỗ hổng cũ. Trong đợt tấn công ngày 30/03/2026, nhóm này tải webshell qua PolyShell rồi cài loader vào 471 cửa hàng trong khoảng 1 giờ. Hơn 100 cửa hàng khác có dấu vết file tải lên qua PolyShell hoặc qua SessionReaper (CVE-2025-54236) — lỗ hổng RCE khác của Magento, đã vá ở bản tin APSB25-88.

Về mục tiêu cuối cùng: Sansec cho biết chưa thu hồi được payload giai đoạn cuối mà loader tải về, nên chưa thể khẳng định chắc chắn nhóm này định làm gì. Bối cảnh cần biết là các chiến dịch loader nhắm vào trang thanh toán của Magento trước nay phần lớn phục vụ việc cài skimmer đánh cắp thông tin thẻ, và các loader đời trước của nhóm này từng phân phối script từ các tên miền mang chủ đề tiền số. Dù mục tiêu là gì, một cửa hàng đang chứa loader nghĩa là kẻ tấn công đã có quyền ghi vào cơ sở dữ liệu của bạn — xoá script mà không cắt quyền truy cập đó thì vài hôm sau nó quay lại, đúng như 60 cửa hàng “tái nhiễm” trong tháng 10.

Minh họa 3D isometric: cửa hàng online với giỏ hàng và lá chắn bảo vệ, kỹ sư đang kiểm tra máy chủ của shop

5. Dấu hiệu cửa hàng của bạn đã bị xâm nhập

Hãy rà soát cửa hàng theo danh sách dưới đây — đây đều là các dấu hiệu Sansec ghi nhận trong các vụ PolyShell thực tế:

  • File .php, .phtml hoặc .phar trong thư mục pub/media/custom_options/quote/. Thư mục này sinh ra chỉ để chứa ảnh khách tải lên. Các tên file kẻ tấn công hay dùng: index.php, dạng ghép số tuỳ chọn như 780index.php, json-shell.php, bypass.phtml, c.php, rce.php, test.php.
  • “Ảnh” mà ruột là mã PHP. Webshell thường giả dạng ảnh: file đuôi .jpg, .png, hoặc file index.php mở đầu bằng chuỗi GIF89a của ảnh GIF rồi nối mã PHP phía sau.
  • File accesson.php rải rác khắp nơi. Sau khi chiếm quyền chạy mã, kẻ tấn công thả thêm backdoor accesson.php vào thư mục con assets/images/ của hàng loạt thư mục gốc (var/, app/, vendor/, pub/, bin/, setup/…) để chống dọn dẹp. Một Magento sạch không bao giờ có file này.
  • Thẻ <script> lạ trong CMS blocks/pages, đặc biệt khi nhắc tới các tên miền loader ở mục 4 — mới nhất là deepveindrilling.com.
  • Tài khoản admin lạ trong mục quản trị người dùng mà không ai trong đội của bạn tạo ra — đây chính là “chìa khóa dự phòng” khiến cửa hàng ở mục 1 bị tái nhiễm dù đã vá đủ.

6. Kiểm tra cửa hàng trong 10 phút

Ba lệnh dưới đây là cách kiểm tra nhanh nhất. Mình đã chạy thử chúng trên một môi trường mô phỏng cấu trúc thư mục Magento (có cài sẵn các file “mồi” đúng như dấu hiệu thật) để bạn thấy kết quả trông như thế nào:

# 1. Liệt kê mọi file trong thư mục upload tuỳ chọn sản phẩm
find pub/media/custom_options/ -type f ! -name '.htaccess'

# 2. Tìm backdoor accesson.php trên toàn bộ gốc shop
find . -name 'accesson.php' -type f

# 3. Xem đầu một file đáng ngờ: mở đầu bằng GIF89a mà đuôi .php = polyglot
head -c 120 pub/media/custom_options/quote/780index.php

Ảnh chụp terminal thật: chạy 3 lệnh find và head để kiểm tra file lạ trong thư mục custom_options và backdoor accesson.php trên môi trường mô phỏng Magento

Cách đọc kết quả:

  • Lệnh 1: cửa hàng bình thường chỉ cho ra các file ảnh của khách (logo, ảnh in ấn). Chỉ cần thấy một file .php hay .phtml trong danh sách là phải coi như đã bị xâm nhập.
  • Lệnh 2: accesson.php là tên backdoor cụ thể của chiến dịch này — kết quả đúng phải là không có dòng nào. Có kết quả trả về nghĩa là kẻ tấn công đã vào rất sâu.
  • Lệnh 3: file 780index.php ở môi trường mô phỏng mở đầu bằng GIF89a — đúng chữ ký file polyglot: đội lốt ảnh GIF nhưng mang đuôi .php. Gặp dấu hiệu này ngoài đời thật thì đừng mở hay chạy thử, hãy xử lý theo mục 7.

Ngoài ba lệnh trên, còn hai chỗ phải tự kiểm tra bằng tay: (1) trong cơ sở dữ liệu, tìm ở bảng cms_block (và cms_page) các thẻ <script> hoặc tên miền lạ ở mục 5; (2) trong trang admin, mục System → Permissions → Users, soát từng tài khoản admin.

7. Vá và xử lý từng bước

Bước 1: Áp bản vá APSB26-73 đúng với dòng bản của bạn

Kiểm tra phiên bản hiện tại (lệnh bin/magento --version hoặc xem trong composer.json), đối chiếu bảng ở mục 3 rồi cài bản phát hành có hậu tố -2026-jul tương ứng, hoặc nâng hẳn lên bản bảo mật mới nhất của dòng. Lưu ý: bản vá tách riêng chỉ được kiểm thử trên bản bảo mật mới nhất của từng dòng (đang ở bản vá lẻ cũ thì phải cập nhật nối tiếp lên trước), và Adobe Commerce Cloud thì áp gói cloud-patches mới nhất. Nhân tiện, nếu chưa vá SessionReaper (CVE-2025-54236, APSB25-88) thì vá luôn trong đợt này — cùng một chiến dịch đang dùng cả hai lỗ hổng.

Bước 2: Chặn chạy PHP trong thư mục upload — làm ngay, kể cả trước khi vá xong

Đây là lớp bảo hiểm rẻ nhất và hiệu quả tức thì: file độc đã nằm trên đĩa mà không chạy được thì không gây hại được. Với Nginx, thêm khối này vào cấu hình server, đặt trước khối location xử lý .php (nếu để sau, PHP handler được ưu tiên và webshell vẫn chạy):

location ~* ^/pub/media/custom_options/ {
    deny all;
    return 403;
}

Với Apache, kiểm tra file pub/media/custom_options/.htaccess còn tồn tại và chứa chỉ thị tắt PHP (php_flag engine 0 trong khối mod_php) cùng dòng Deny from all.

Một lưu ý quan trọng từ chính Sansec: chặn truy cập web vào thư mục upload không ngăn được việc tải file lên — kẻ tấn công vẫn ghi được file lên đĩa qua API. Lớp chặn này chỉ vô hiệu hoá khả năng thực thi; muốn bịt hẳn đường vào phải có bản vá ở bước 1 (hoặc WAF chặn chính request gọi API đó). Bước 2 là biện pháp cầm cự, không thay thế cho việc vá.

Bước 3: Rà soát và dọn dẹp sau vá

Làm đủ các việc sau, theo đúng thứ tự:

  1. Xoá mọi file lạ tìm được ở mục 6, đặc biệt là file .php/.phtml trong pub/media/custom_options/ và mọi bản sao của accesson.php.
  2. Kiểm tra bảng cms_block và cms_page, gỡ mọi thẻ <script> và tên miền lạ ở mục 5.
  3. Xoá các tài khoản admin lạ; đổi mật khẩu toàn bộ tài khoản admin còn lại và bật xác thực hai lớp (2FA) cho tất cả.
  4. Nếu từng phát hiện webshell hoặc admin giả, hãy đổi luôn mật khẩu cơ sở dữ liệu và các khoá API tích hợp (thanh toán, vận chuyển, ERP…) vì chúng có thể đã bị đọc.

Bước 4: Nếu đã bị xâm nhập sâu, đừng cố “dọn tại chỗ”

Nếu bạn tìm thấy webshell, backdoor accesson.php hoặc tài khoản admin giả, hãy mặc định rằng dữ liệu khách hàng và dữ liệu thanh toán có thể đã bị lộ. Khi đó: giữ nguyên chứng cứ (log, file độc, thời điểm phát hiện) phục vụ điều tra; cân nhắc dựng lại cửa hàng từ một bản sao sạch đã kiểm chứng thay vì dọn dẹp trên nền đang nhiễm — backdoor thường được gài nhiều lớp và rất dễ sót; đồng thời cân nhắc thông báo cho khách hàng, đối tác thanh toán và nhờ một đơn vị bảo mật thương mại điện tử hỗ trợ.

Minh họa 3D isometric: kỹ sư đang rà soát máy chủ và cơ sở dữ liệu của cửa hàng Magento để tìm backdoor còn sót lại sau khi vá

8. Câu hỏi thường gặp

Cửa hàng đã cài APSB26-73 có an toàn không?

Bản vá bịt đường vào PolyShell, nhưng không xoá các loader, webshell hay tài khoản giả đã bị cài trước đó. Sau khi vá, bắt buộc phải làm bước rà soát và dọn dẹp ở mục 7 bước 3 — như trường hợp cửa hàng sạch vẫn bị cài loader mới một giờ sau khi quét, chỉ vì quyền truy cập của kẻ tấn công chưa bị cắt.

WAF chặn được PolyShell không?

Có, một WAF (hoặc rule chặn) đúng cấu hình ngăn được việc khai thác qua HTTP nếu nó nhận diện được request bất thường gửi file lên — nhưng đó chỉ là lớp giảm thiểu tạm thời, không thay thế bản vá.

Shop dùng Magento Open Source tự host có nằm trong diện ảnh hưởng không?

Có. Lỗi nằm trong mã xử lý upload của Magento, tồn tại ở cả Adobe Commerce lẫn Magento Open Source (bảng ở mục 3).

Làm sao biết cửa hàng có nằm trong 953 cửa hàng nhiễm mã độc không?

Chạy các bước kiểm tra ở mục 6 và mục 5. Chỉ một dấu hiệu là đủ để coi như bị xâm nhập và xử lý theo mục 7 bước 4.

9. Kết luận

PolyShell là một lỗ hổng nghiêm trọng ở mức Critical: không cần tài khoản vẫn khai thác được, đã có mã khai thác ngoài thực tế và cả đợt tấn công quy mô lớn. Thứ tự ưu tiên là: (1) xác minh phiên bản và áp bản vá APSB26-73 (hoặc nâng lên bản đã vá); (2) chặn thực thi PHP trong thư mục upload và đối chiếu các biện pháp bảo vệ của phía máy chủ; (3) rà soát toàn diện và dọn dẹp loader, webshell, tài khoản lạ theo mục 7. Và nếu trong cửa hàng có dấu hiệu đã bị xâm nhập, cần nhanh chóng liên hệ đội ngũ bảo mật hoặc nhà cung cấp hosting để được hỗ trợ kịp thời.


Nguồn tham khảo:

Chuyên mục:Cybersecurity

Bình luận (0)

+ =
Zalo