Bản vá PHP tạm thời từ năm 2014 đã có gần 20 triệu lượt cài đặt, nay tác giả tuyên bố ngừng hỗ trợ
Năm 2014, lập trình viên Jake Smith viết 174 dòng PHP để vá tạm cho hệ thống CMS của AOL trong lúc nâng cấp phiên bản. Ông không ngờ gói mã này được cài đặt gần 20 triệu lần và vẫn còn chạy trên hàng triệu website. Mới đây, ông chính thức đánh dấu gói là deprecated và giải thích lý do không bàn giao cho người khác tiếp quản.

Bản vá PHP tạm thời từ năm 2014 đã có gần 20 triệu lượt cài đặt, nay tác giả tuyên bố ngừng hỗ trợ
Cách đây 12 năm, lập trình viên Jake Smith viết 174 dòng PHP như một giải pháp chữa cháy cho hệ thống quản trị nội dung (CMS) của AOL. Ông đăng nó lên Packagist với hy vọng vài người khác cũng cần bản vá tương tự, và không ngờ nó đã được cài đặt gần 20 triệu lần kể từ đó. Mới đây, ông đã chính thức đánh dấu gói này là deprecated (ngừng hỗ trợ).
Một miếng đệm tạm thời
Năm 2014, AOL đang trong quá trình nâng cấp CMS từ PHP 5.2 lên PHP 5.3. Một phần của quá trình này là loại bỏ phiên bản 1 của tiện ích mở rộng pecl_http, vốn cung cấp hàm http_build_url(). Một hệ thống CMS xử lý rất nhiều URL, và hệ thống của họ gọi hàm này ở hàng chục vị trí. Jake không muốn đụng vào đống code đó, nên ông tự viết lại http_build_url() của riêng mình, chỉ định nghĩa khi hàm gốc không tồn tại. Nhờ vậy, code cũ không hề hay biết có gì thay đổi.
Thời điểm đó, Composer đang bắt đầu phổ biến, giúp việc chia sẻ trở nên dễ dàng. Ông nghĩ gói này chỉ "sống" được một hai năm, cho đến khi cộng đồng PHP chuyển sang giải pháp tốt hơn.
Sơ đồ minh họa hàm http_build_url trong PHP
Con số cài đặt khổng lồ
Hoá ra nó chẳng hề tạm thời chút nào. Gói này đã được tải về từ Packagist gần 20 triệu lần, và vẫn duy trì hơn 400.000 lượt cài đặt mỗi tháng.
Và Composer chỉ là một phần của bức tranh. WPML — plugin đa ngôn ngữ hàng đầu cho WordPress — đóng gói trực tiếp bản polyfill này trong mã nguồn, và WPML cho biết nó đang được cài trên hơn 1,5 triệu website. Thư viện xử lý tên miền idna-convert cũng phụ thuộc vào nó, nhờ đó gói này có mặt trong mã nguồn của SPIP (một hệ thống CMS của Pháp) và được đóng gói trong Debian lẫn Ubuntu. Cộng lại, khả năng cao là bạn từng truy cập một website vẫn đang chạy code của Jake mà không hề biết.
Tôi chưa bao giờ tưởng tượng nó lại lan rộng đến mức này.
Quay lại nhìn nó
Jake chỉ thực sự hiểu mức độ lan toả của gói này vài tháng trước, khi lần đầu xem lại nó sau nhiều năm. Ông biết nó có người dùng. Đến năm 2021, khi đã rời xa PHP một thời gian, số lượt tải đủ bất ngờ để ông đề nghị tìm người bảo trì mới. Ba người đã ngỏ lời. Ngay sau khi ông đưa ra đề nghị, gia đình ông gặp biến cố bất ngờ khiến mọi thứ đảo lộn. Ông không theo đuổi tiếp, và tự nhận đó là lỗi của mình. Đến khi mọi việc ổn định, những mục tiêu khác đã lấp đầy cuộc sống, và ông quên bẵng gói phần mềm này suốt nhiều năm.
Bên cạnh những con số, có một vài issue trên GitHub — trong đó có một lỗi mà khi ghép một đường dẫn vào URL có dấu gạch chéo ở cuối, mọi ký tự "a" trong đường dẫn đều bị xoá sạch. Dưới dòng ghi chú // Workaround for trailing slashes, code của ông gắn thêm một chữ "a" vào đường dẫn để luôn có đoạn cuối cùng để cắt bỏ, rồi cắt nó bằng tìm-và-thay-thế. Khi đường dẫn kết thúc bằng dấu gạch chéo, đoạn cuối chỉ còn chữ "a", và thao tác tìm-và-thay-thế vô tình xoá luôn mọi chữ "a" khác trong đường dẫn. Ông không thể tin nổi lỗi này lại tồn tại lâu đến vậy mà không ai phát hiện.
Không chọn phương án nào trong số đó
Jake có ba lựa chọn: quay lại với PHP sau gần một thập kỷ, bàn giao gói cho một trong những người từng ngỏ lời, hoặc để nó nằm im. Ông chọn cách thứ tư — ngừng hỗ trợ nó.
Gói này vốn chỉ mang tính tạm thời, nên ông quyết định cho nó "nghỉ hưu". Thư viện URI của The PHP League đã là câu trả lời chính thức của cộng đồng suốt nhiều năm, và PHP 8.5 giờ đây tích hợp sẵn một API URI chuẩn ngay trong ngôn ngữ. Cả hai đều tốt hơn một miếng đệm 174 dòng viết từ năm 2014. Việc tiếp tục bảo trì gói sẽ chỉ trì hoãn bước chuyển đổi mà mọi người nên thực hiện, còn bàn giao lại càng tăng thêm rủi ro.
Điểm đáng chú ý về mặt bảo mật: một gói được cài đặt rộng rãi với người bảo trì mới mà không ai ở phía sau kiểm chứng chính là mục tiêu mà kẻ tấn công nhắm đến. Jake nhắc đến video của Veritasium về backdoor trong xz Utils như ví dụ điển hình cho kịch bản này. Đây cũng là lời cảnh tỉnh cho cộng đồng mã nguồn mở Việt Nam về rủi ro chuỗi cung ứng phần mềm (supply chain) khi các dự án nhỏ bé bị bỏ quên lại có sức ảnh hưởng lớn.
Gói vẫn sẽ cài đặt được, nhưng sẽ không nhận bản sửa lỗi mới, kể cả lỗi thiếu chữ "a" nói trên. Sau ngần ấy năm không thay đổi, ngay cả một bản vá một dòng cũng có thể gây hậu quả ngoài ý muốn cho ai đó, mà lại không có ai đứng ra hỗ trợ. Tệp README có hướng dẫn cách chuyển sang giải pháp thay thế.
Tôi viết đoạn code này để giảm nhẹ một cuộc di trú đau đớn, cho chính mình và cho bất kỳ ai đang trải qua quá trình tương tự. Cảm ơn tất cả những người đã gửi pull request hoặc ngỏ ý tiếp quản, và những người vẫn kiên trì mở issue rất lâu sau khi tôi đã ngừng đọc chúng. Đó là một chặng đường tốt đẹp cho một bản vá tạm thời.
Tái bút: AOL chưa bao giờ di chuyển CMS của họ khỏi bản polyfill "tạm thời" này. Nó chạy ở đó cho đến khi toàn bộ nền tảng bị đóng cửa vào khoảng năm 2020.


